Creating a simple OS to retrieve hardware information.

Ravindu Senal Fernando
4 min readJul 26, 2020

This is a guidance to create a simple OS in windows to retrieve hardware information using assembly language.

Prerequisites

I am going to use a little bit different approach in this by using WSL2 (Windows Subsystem for Linux 2) to build the OS. You can read more about it in here.

You have to install nasm and mkisofs in wsl2 to get started. Open up the wsl terminal and run these command.

To install nasm :-

sudo apt install nasm

To install mkisofs :-

sudo apt-get install mkisofs

Implementation

You can get the code for Alpha_OS from github.

File structure of the Alpha_OS

  • programs/ — Source code for programs added to the disk image.
  • source/ — Contains the entire OS source code.
  • source/bootload/ — Source to generate BOOTLOAD.BIN, which is added to the disk image when building.
  • source/features/ — Components of Bubble OS(keyboard and screen).
  • source/kernel.asm — The core kernel source file, which pulls in other source files.

You can build the OS by running the following command in the root directory of the OS. You must run the command in WSL terminal.

sudo  bash  ./build-linux.sh

These are some defined strings.

 strmemory  db "Base Memory size: ", 0x00
strsmallextended db "Extended memory between(1M - 16M): ", 0x00
strbigextended db "Extended memory above 16M: ", 0x00
strCPUVendor db "CPU Vendor : ", 0x00
strCPUdescription db "CPU description: ", 0x00
strNotSupported db "Not supported.", 0x00
strhdnumber db "Number of hard drives: ",0x00
strserialportnumber db "Number of serial ports: ", 0x00
strserialport1 db "Base I/O address for serial port 1 (communications port 1 - COM 1): ", 0x00
strtotalmemory db "Total memory: ", 0x00

Code for reading the base memory.

 push ax
push dx

int 0x12 ; call interrupt 12 to get base mem size
mov dx,ax
mov [basemem] , ax
call _print_dec ; display the number in decimal
mov al, 0x6b
mov ah, 0x0E ; BIOS teletype acts on 'K'
mov bh, 0x00
mov bl, 0x07
int 0x10

pop dx
pop ax

Code for reading the extended memory

call _display_endl
mov si, strsmallextended
mov al, 0x01
int 0x21

xor cx, cx ; Clear CX
xor dx, dx ; clear DX
mov ax, 0xE801
int 0x15 ; call interrupt 15h
mov dx, ax ; save memory value in DX as the procedure argument
mov [extmem1], ax
call _print_dec ; print the decimal value in DX
mov al, 0x6b
mov ah, 0x0E ; BIOS teletype acts on 'K'
mov bh, 0x00
mov bl, 0x07
int 0x10
xor cx, cx ; clear CX
xor dx, dx ; clear DX
mov ax, 0xE801
int 0x15 ; call interrupt 15h
mov ax, dx ; save memory value in AX for division
xor dx, dx
mov si , 16
div si ; divide AX value to get the number of MB
mov dx, ax
mov [extmem2], ax
push dx ; save dx value

call _display_endl
mov si, strbigextended
mov al, 0x01
int 0x21

pop dx ; retrieve DX for printing
call _print_dec
mov al, 0x4D
mov ah, 0x0E ; BIOS teletype acts on 'M'
mov bh, 0x00
mov bl, 0x07
int 0x10

call _display_endl
mov si, strtotalmemory
mov al, 0x01
int 0x21; total memory = basemem + extmem1 + extmem2
mov ax, [basemem]
add ax, [extmem1] ; ax = ax + extmem1
shr ax, 10
add ax, [extmem2] ; ax = ax + extmem2
mov dx, ax
call _print_dec
mov al, 0x4D
mov ah, 0x0E ; BIOS teletype acts on 'M'
mov bh, 0x00
mov bl, 0x07
int 0x10

Code for CPU Information

call _display_endl
mov si, strCPUVendor
mov al, 0x01
int 0x21
mov eax, 0x00000000 ; set eax register to get the vendor
cpuid
mov eax, ebx ; prepare for string saving
mov ebx, edx
mov edx, 0x00
mov si, strVendorID
call _save_string
mov si, strVendorID ;print string
mov al, 0x01
int 0x21
call _display_endl
mov si, strCPUdescription
mov al, 0x01
int 0x21
mov eax, 0x80000000 ; First check if CPU support this
cpuid
cmp eax, 0x80000004
jb _cpu_not_supported ; if not supported jump to function end
mov eax, 0x80000002 ; get first part of the brand
mov si, strBrand
cpuid
call _save_string
add si, 16
mov eax, 0x80000003 ; get second part of the brand
cpuid
call _save_string
add si, 16
mov eax, 0x80000004 ; get third part of the brand
cpuid
call _save_stringmov si, strBrand ; print the saved Brand string
mov al, 0x01
int 0x21
jmp _hard_info

The number of hard drives

_hard_info:
call _display_endl
mov si, strhdnumber
mov al, 0x01
int 0x21
mov ax,0040h ; look at 0040:0075 for a number
mov es,ax ;
mov dl,[es:0075h] ; move the number into DL register
add dl,30h ; add 48 to get ASCII value
mov al, dl
mov ah, 0x0E ; BIOS teletype acts on character
mov bh, 0x00
mov bl, 0x07
int 0x10

About serial ports

_serial_ports:
call _display_endl
mov si, strserialportnumber
mov al, 0x01
int 0x21mov ax, [es:0x10]
shr ax, 9
and ax, 0x0007
add al, 30h
mov ah, 0x0E ; BIOS teletype acts on character
mov bh, 0x00
mov bl, 0x07
int 0x10; Reading base I/O addresses
;Base I/O address for serial port 1 (communications port 1 - COM 1)
mov ax, [es:0000h] ; Read address for serial port 1
cmp ax, 0
je _end
call _display_endl
mov si, strserialport1
mov al, 0x01
int 0x21
mov dx, ax
call _print_dec

You can run the Alpha_OS in VirtualBox.

--

--