Note: this is mostly relevant to x86 architecture. Here's a somewhat simplified explanation.
The transition is usually caused by one of the following:
- Fault (e.g. a page fault or some other exception caused by executing an instruction)
- Interrupt (e.g. a keyboard interrupt or I/O finishing)
- Trap (e.g. a system call)
What normally happens is that system checks the Interrupt Descriptor Table (IDT). Each exception (interrupt, fault, etc.) has a number associated with it which is used to index into this table.
From this table the CPU can determine the interrupt handler to run.
As part of the transition the following changes (generally) take effect:
- Switch to Kernel stack
- EFLAGS are saved
- Code segment selector and EIP are saved.
- stack segment selector and stack pointer are saved
- Start executing the interrupt handler
- The general purpose registers are saved (handler's job)
- Segment selectors are changed to Kernel ones (handler's job)
You're now in kernel mode.
Hope that helps :)