First, I don't quite understand what it is that you want to gain by switching into kernel mode "manually". So, you have switched and then what? What do you want to do next? If you want to access resources that aren't supposed to be accessible in user applications, then that's the whole point of not allowing it because if it was allowed, then your app would be able to easily do nasty things like this:
- damage the OS and hang or reboot the computer
- take the computer user hostage and demand ransom
- turn the computer into a covert spam bot or an remotely-operated attacker of other computers on the network
- spy on the OS and other apps and steal confidential info
- tamper with info
- work around things like DRM and various other licenses
- impersonate other users of the same computer to possibly incriminate them or steal from them using their banking account or credit card info or their passwords to other resources
- disable anti-virus software, if any, potentially leading to any or all of the above
- etc etc
Now, if you are not interested in doing any of the above, then there's no reason for your app to gain kernel privileges.
I admit, there are certain bugs in the OS and things we consider bugs that we'd like to work around by gaining said access, but that is rare and few people can actually "fix" those bugs without breaking something of importance, so the reliability and security concerns outweigh 1000 to 1 the urge to "fix" something that you don't like in the OS.
As for interrupts and exceptions being the way to switch to kernel mode, that's just a common implementation that makes sense.
Interrupts have to be handled in the kernel, which is why they incur a switch when needed. They have to be because only the kernel and device drivers know what to do with the hardware that triggers interrupts. And that's the whole point of the OS, to abstract away hardware differences and provide programs with a unified API to do things that frees them from the burden of knowing how to work with this or that display or sound card or network card or printer, etc etc.
Software interrupts just piggy-back on the same mechanism as hardware interrupts as it's cheap to do so. The primary use of software interrupts is to request some work/assistance from the OS, and, understandably, they need to switch too, which is what hardware interrupts do already.
On the x86 platform, hardware interrupts and the ìnt
instruction result in a pretty much identical response in the CPU, they are handled very similarly.
For this system call functionality some CPUs provide special instructions unrelated to interrupts. They may be faster then software interrupts implemented on top of hardware interrupts or they may come with some useful extra functionality that software interrupts don't offer.
This is the case with the x86 instructions sysenter
and syscall
. They are optimized for fast transitions from user mode to kernel mode.
Some exceptions are of the same nature as hardware interrupts, e.g. the page fault exception. It has to be handled in the kernel as well because that's the mechanism the OS uses to implement virtual on-disk memory. The OS needs to access stuff on the disk in response to page faults and then alter page tables and your app is unlikely to be able to do that itself and it wouldn't be a good thing to let it access those important things like arbitrary locations on the disk or the page tables freely.
Other exceptions are used to control execution of apps and notify the OS of something going wrong, which gives the OS a chance to either fix the problem or terminate the misbehaving application without having to keep it around in a zombi state still consuming valuable resources such as memory. These exceptions also need to be handled in the kernel, it's the only way of doing it.
Now, you may be interested in handling your app's exceptions within the app itself. Some OSes let you do that. Windows implements what it calls Structured Exception Handling
(AKA SEH
) while Linux and Unix implement signals
. Doing either usually still involves first handling the exception in the kernel and only then reflecting it back to where it's come from. It's just how most CPUs are implemented. Such an implementation, when exceptions are first routed into the kernel, is easy and cheap to do and it doesn't disallow anything as the kernel can implement anything on top of this, including SEH and signals.
Anyway, since it's the OS/kernel to provide user apps with functionality and to ensure security and the two more often than not go hand in hand (because the OS/kernel has access to everything and your app isn't supposed to and the OS sometimes accesses those things on behalf of your app, think of courtesy:), both of these things are behind the imaginary fence between user mode and kernel mode.