Operating Systems, User Mode

Mahela Dissanayake
3 min readSep 27, 2021

Hello everyone, In today’s article I’m going to talk about entering the User Mode of your Operating system. Until now we ran all our programs in the kernel-mode which is the highest possible privilege mode. But for an OS running everything in this mode is risky since any program running in Kernel mode can directly access any device or a memory location but also a crash in Kernel mode will bring down the whole system. So we will need a different less privileged mode to run user programmes to avoid these risks. This is where user mode comes into play.

Since we have successfully implemented the segmentation and paging in previous chapters we can finally get into accessing the user mode.

First, in order to enter the user mode, we have to add two more segments to the GDT. They are user code segment and user data segment. They are similar to the kernel segments we added earlier but the difference is that these segments are at privilege level 3 while kernel segments were privilege level 0.

Adding User Mode Segments to the GDT

There are three major steps to set up user mode. First, you have to create the page frames for the program code, data and stack. Then the binaries from the GRUB module has to be copied to the page frames for the programme code and finally, we have to create the page tables to map the created page frames to the memory.

Entering the User Mode

There is only one way to enter user mode from kernel mode and it is to use lret or iret assembly instruction.

To enter the user mode we have to configure the stack to make it look like the processor has raised an interrupt. This can be done in assembly or C. I’m doing this using assembly instruction.

Configure the stack

Then for the moment, we have to disable system interrupts. So we’ll create a hardware interrupt handler and disable interrupts using that.

If all is gone correctly now we will have an operating system with a user mode.

Switching to user mode in Kmain.c

Using C

When we are using C to program user programs it is important to think about the structure of the output file. We can use elf as a file format for the kernel because GRUB has instructions on how to handle it. But with user programs that’s not the case, So we have to compile them to flat binaries. One of the main problems with this is that the entry point of code generated by c is unpredictable. So we have to wrap it in some assembly instructions.

Then we have to link it using a linker script.

If all has gone well your OS will boot successfully.

References

Helin E, Renberg A. (2015). The little book about OS development: https://littleosbook.github.io/

Os Dev Wiki https://wiki.osdev.org/Main_Page

linux-insides https://0xax.gitbooks.io/linux-insides/content/

GNU GRUB Multiboot Manual http://www.gnu.org/software/grub/manual/multiboot/

JamesM’s kernel development tutorials http://www.jamesmolloy.co.uk/tutorial_html/6.-Paging.html

Thank you for reading and I will be back next week with another article.

--

--

Mahela Dissanayake

Software Engineering Undergraduate of University of Kelaniya, Sri Lanka.