My Operating system Development Experience and understanding -Part 06
in this article we are going to understand about user modes in OS development. Before that if you don’t read my previous OS development Articles please go and check those from below links
- My Operating system Development Experience and understanding. Part 01 -Setting Up environments
- My Operating system Development Experience and understanding -Part 02- C instead of assembly
- My Operating system Development Experience and understanding -Part 03-implement Drivers
- My Operating system Development Experience and understanding -Part 04-Segmentation in OS development
- My Operating system Development Experience and understanding -Part 05-nterrupts and inputs
let get into todays Topics
What do we do now that the kernel has booted, printed to the screen, and reads from the keyboard? Normally, a kernel isn’t designed to handle application logic; instead, applications are supposed to accomplish it. To make application development easier, the kernel creates appropriate abstractions , performs activities on behalf of applications (system calls), and schedules processes.
In contrast to kernel mode, user mode is the environment in which the user’s programs run. This environment has fewer privileges than the kernel, therefore (badly constructed) user programs will not be able to interfere with other programs or the kernel. Kernels that are poorly written are free to do whatever they want.
Although there is still a long way to go before the OS created in this article can run applications in user mode, this chapter will demonstrate how to run a simple program in kernel mode.
Loading an External Program
What is the source of the external program? We need to load the code we want to run into memory in some way. Drivers and file systems for loading software from a CD-ROM drive, a hard disk, or other persistent media are frequently included in more feature-rich operating systems.
Instead of building all of these drivers and file systems from scratch, we’ll use GRUB’s modules functionality to load the software.
GRUB may load files directly from the ISO image into memory, and these items are known as modules. Edit the file iso/boot/grub/menu.lst and add the following line at the end to make GRUB load a module:
Now create the iso/modules
The application program will be created later in next article
The code that calls kmain.c has to be modified so that it can tell kmain where to look for the modules. We also want to notify GRUB that when loading modules, they should all be aligned on page borders.(i will explain details about page alignment in next article)
The “multiboot header” — the first bytes of the kernel — must be changed as follows to tell GRUB how to load our modules:
In the register ebx, GRUB will also keep a pointer to a struct that, among other things, describes where the modules are loaded. To make ebx an argument for kmain, you should probably push it to the top of the stack before calling it.
Executing a Program
A Very Simple Program
At this point, a program can only do a few actions. As a result, a test program consisting of a very simple program that writes a value to a register suffices. Stopping Bochs after a while and checking the register for the proper number in the Bochs log will confirm that the program has completed. Here’s an example of a brief program:
Since our kernel cannot parse advanced executable formats we need to compile the code into a flat binary. NASM can do this with the flag -f:
nasm -f bin program.s -o program
This is all we need. You must now move the file program to the folder iso/modules.
Finding the Program in Memory
We must first locate the application in memory before proceeding. We can perform this totally in C if the contents of ebx are supplied as an argument to kmain.
A multiboot structure is indicated by the pointer in ebx. Copy the structure described in the multiboot.h file from my code.
The pointer passed to kmain in the ebx register can be cast to a multiboot_info_t pointer. The address of the first module is in the field mods_addr. The following code shows an example:
We should observe 0xDEADBEEF in the register eax via the Bochs log if we start the kernel, wait until it has run and reached the endless loop in the program, and then halt Bochs. We’ve successfully launched a program in our operating system!
thanks for reading
see you on next article