Implementing an Operating System

Nimesha Dilini
4 min readJun 4, 2019

I started the project by following the instructions given in the resource website. To get a better understanding of the JOSH operating system, I read the Tutorial written on JOSH by Dr. Mohan Raj Dhanagopal and fully understand its code.

From that Tutorial, I understood that I do not have to edit the boot.asm to implement a new command.

Boot loader handles the loading of the kernel to the
memory. Therefore after the OS is loaded, the computer will be totally controlled by the kernel.

There were some problems when I making the image file for bootloader and kernel. I refer to some online materials and I used the .sh file in MikeOS which can convert bootloader and kernel to image file easily. Then I run the JOSH OS in VirtualBox. shell implementation works for it.

Then I try to modify the kernel file to add new commands for displaying hardware information and help.

Hardware Information Command(CPU)

CPUID is a special command to get CPU details. When we set the EAX (EAX=0) to an initial value then it returns the CPU’s manufacturer ID string (a twelve character ASCII string stored in EBX, EDX, ECX — in that order)

This the online material that I have referred for this.

  • In CPU vendorID function,

mov eax,0
cpuid; call cpuid command
mov [strcpuid],ebx; load last string
mov [strcpuid+4],edx; load middle string
mov [strcpuid+8],ecx; load first string
;call _display_endl
mov si, strcpuid;print CPU vender ID
mov al, 0x01
int 0x21
ret

  • In CPU Type function,

mov eax, 0x80000002 ; get first part of the brand
cpuid
mov [strcputype], eax
mov [strcputype+4], ebx
mov [strcputype+8], ecx
mov [strcputype+12], edx

mov eax,0x80000003
cpuid; call cpuid command
mov [strcputype+16],eax
mov [strcputype+20],ebx
mov [strcputype+24],ecx
mov [strcputype+28],edx

mov eax,0x80000004
cpuid ; call cpuid command
mov [strcputype+32],eax
mov [strcputype+36],ebx
mov [strcputype+40],ecx
mov [strcputype+44],edx

mov si, strcputype ;print processor type
mov al, 0x01
int 0x21
ret

When “cpuid” is called with EAX=80000002h,80000003h,80000004h , we get the entire 48-byte null-terminated ASCII processor type string.Then save that string to strcputype and print using interrrupt 21.

  • In CPU Feature Function

When CPUID executes with EAX set to 1, feature information is returned in ECX and EDX. (Further details 2nd reference link at the bottom of page). This function test the availability of features such as sse ,sse2 ,sse3 ,sse41,sse42, aes , avx etc;

checksse:
test edx, 00000010000000000000000000000000b
jz checksse2
mov si, sse

At first test the bit in the edx register for specific feature. If that is avilable print the feature name else jump to check the new feature

other hardware functions;

  • test the State of Mouse(Available or not)
  • print the CPUSerialNo(still trying on this)

Help Command

I use this to display the details of commands can be used within the shell.

In the help command, I used interrupt 21 methods to print 3 strings describing the commands as follows.

mov si, strHelpMsg1
mov al, 0x01
int 0x21
call _display_endl
mov si, strHelpMsg2
mov al, 0x01
int 0x21
call _display_endl
mov si, strHelpMsg3
mov al, 0x01
int 0x21

Memory Command

I referred to the https://wiki.osdev.org/Detecting_Memory_(x86) for implementing the memory commands. According to the source, we cannot read the whole memory at once. It has lower memory part and the upper memory part stored separately in the computer. First I used the interrupt 12h to get the number of base memory. After the interrupt, 12 amount of base memory is stores in the ax register in Kb. Then I print the value
using the _print_dec procedure. I used a similar approach to find the memory between 1M and 16M. The only difference is interrupt is 15h and the function is ax=e801h.

mov ax, 0xE801
int 0x15
mov dx, ax
call _print_dec

To read the memory above 16M, I used the same interrupt but this time I used the value in DX register. Since DX register contains the number of 64k blocks, I divided the number by 16 to get the value in megabytes.

mov ax, 0xE801
int 0x15
mov ax, dx
mov dx, 0
mov si , 16
div si

To show the total memory, I needed to get the sum of the three memory parts. First I stored them in variables. Then later I first added the 1 st and 2 nd parts of memory which are in kB. Then converted the result to MB by dividing it by 2 10 (by shifting bits 10 times.) Then added the last memory part and printed the result in MB.

After adding new commands I copied the image file to the boot sector of my pen drive by referring to the medium article given below and boot with my operating system. For booting, I used the virtual box and installed ploplinux to boot from USB.

Here is the Screenshot of my Edited version of JOSH operating System.

After adding some more functions to hardware information

Github repository is given below.

Some other useful Links:

https://medium.com/setublog/hands-on-to-operating-systems-a847e9dc75f7

https://c9x.me/x86/html/file_module_x86_id_45.html

--

--

Nimesha Dilini

Former Software Engineer at Sysco LABS | Bsc.(hons) in Software Engineering Graduate from university of Kelaniya (www.kln.ac.lk)