The XamOS — Let’s Build an OS!!!

Nipuni Perera
4 min readAug 26, 2021

--

The 6th step of OS development — integrate user modes

Welcome back readers!!!

If you’re new to OS development and my article series you better come from this first article.Otherwise it would be hard to understand what’s going on.🤔

The Road to User Mode

What do we do now that the kernel has booted, printed to the screen, and reads from the keyboard? Normally, a kernel isn’t meant to handle application logic; instead, applications are supposed to accomplish it. To make application development easier, the kernel generates appropriate abstractions (for memory, files, and devices), executes 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, thus (badly written) user programs will not be able to interfere with other programs or the kernel. Kernels that are poorly written are free to do anything they want.

Although there is still a long way to go before the OS built in this book can run applications in user mode, this chapter will demonstrate how to run a tiny program in kernel mode.

External Program Loading

What is the source of the external program? We need to load the code we wish 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 generally included in more feature-rich operating systems.
Instead of developing all of these drivers and file systems from scratch, we’ll utilize GRUB’s modules functionality to load the application.

GRUB Modules

GRUB can load arbitrary files 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:

module /modules/program

Now create the folder iso/modules:

mkdir -p iso/modules

Later in the article, I’ll create an application program. The code that calls kmain has to be changed so that it can tell kmain where the modules are. We also want GRUB to know that when loading modules, they should all be aligned on page boundaries. The “multiboo.t header” — the kernel’s initial bytes — must be modified as follows to inform GRUB how to install our modules:

In the register ebx, GRUB will also save a reference to a struct that indicates where the modules are loaded, among other things. To make ebx an argument for kmain, you should probably put it into the stack before calling it.

Executing a Program

A Very Simple Program😋

At this point, the software can only do a few actions. As a result, a test program consisting of a very small program that writes a value to a register suffices. Stopping Bochs after a time and checking the register for the right number in the Bochs log will confirm that the program has been completed. Here’s an example of a brief program:

Compiling

We must compile the code into a flat binary since our kernel cannot understand sophisticated executable formats.
The flag -f: can be used in NASM to do this.

nasm -f bin program.s -o program

All we require is this. You must now copy the application file to the iso/modules folder.

Finding the Program in Memory

We must first locate the application in memory before proceeding. We can accomplish this fully in C if the contents of ebx are given as an input to kmain.
A multiboot structure is pointed to by the pointer in ebx. Download the multiboot.h file, which specifies the structure, from

http://www. gnu.org/software/grub/manual/multiboot/html node/multiboot.h.html

The ebx register pointer supplied to kmain can be converted to a multiboot info t reference. The parameter mods addr contain the address of the first module. An example may be found in the code below:

However, before blindly following the pointer, make sure the module was successfully loaded by GRUB. Check the flags field of the multiboot info t structure to see whether this is the case. You should also double-check the parameter mods count for accuracy.

We should observe 0xDEADBEEF in the register eax through the Bochs log if we start the kernel, wait until it has run and reached the endless loop in the program, and then terminate Bochs. We’ve successfully launched a program in our operating system! #The_XamOS

The First Days of User Mode

We’ve now set the application to execute at the same privilege level as the kernel; we’ve simply done so in an unusual method. We’ll need to implement paging and page frame allocation in addition to segmentation to allow apps to run at a separate permission level. There’s a lot of effort and technical intricacies to go through, but you’ll have functional user-mode applications in a few articles.

Is that all?

— yes of course! That’s all for today..

It’s very short ..!

— Yes, yes.. Short and sweet 😎,

I’ll hope to get back to you with the chapter seven, “virtual_memory_paging” as soon as possible.Till then,

Stay Safe!!! 👋

-Nipuni Perera-

--

--