Sunday, May 1, 2011

Making your own Operating System - The Next Step

Now you've successfully set up the virtual machine to boot from JOSH OS (If you haven't done it yet, read this post on how to do it), I'm going to tell you how to add a new functionality to display the hardware details of your computer.



There are three main methods to get the hardware information from the BIOS Data Area.

 
1.      Use BIOS Service interrupts
By using various BIOS interrupts we can get the hardware information that are stored in the BIOS data area. Interrupt call will return the AX register with the corresponding information.
Ex:
xor ax, ax  ;clear the ax register
int 0x11   ;send the interrupt, it sets the ax register
and ax, 0x0e00             ;keep the bits 9-11
shr ax, 9       ;shift 9 bits right
add al, 0x30               ;add 48 and convert to decimal
mov ah, 0x0e
int 0x10

2.      Use BIOS Data area and access it using the offset
When a computer is powered on, the BIOS data area is created at memory location 0040:0000h with a  typical size of 255 bytes. This data area can be accessed by calling the relevant offset where the required data is saved.

Ex:
push es                 ;save the current values of the es register
mov ax, 0x40            ;get the address no 0x40 to the ax register
mov es, ax               ;move ax to the es
mov al, [es:75h]        ;get the required offset to display no of HDD
add al, 0x30             ;convert the number to ASCII by adding 48(decimal) = 0x30
mov ah, 0x0e            ;print the number
int 0x10
pop es                    ;restore the value stored in the es register

By using the table below we can find almost all the information of the hardware underneath the computer. We can use either,
calling BIOS service interrupts or
referring to BIOS Data area
to get the information needed.

Offset Hex
BIOS Service
Field Size
[byte(s)]
Information
10h
Int 11h
2
Equipment word



Bits 15-14 indicate the number of installed parallel ports
00b = 1 parallel port
01b = 2 parallel ports
03b = 3 prallel ports



Bits 13-12 reserved



Bits 11-9 indicate the number of installed serial ports
000b = none
001b = 1 serial port
002b = 2 serial ports
003b = 3 serial ports
004b = 4 serial ports



Bit 8 reserved



Bits 7-6 indicate the number of installed floppy drives
0b = 1 floppy drive
1b = 2 floppy drives



Bits 5-4 indicate the video mode
00b = EGA or later
01b = color 40x25
10b = color 80x25
11b = monochrome 80x25



Bit 3 reserved



Bit 2 indicate if a PS/2 mouse is installed
0b = not installed
1b = installed



Bit 1 indicate if a math coprocessor is installed
0b = not installed
1b = installed



Bit 0 indicated if a boot floppy is installed
0b = not installed
1b = installed
13h
Int 12h
2
Memory size in Kb
17h
Int 16h
1
Keyboard shift flags 1
18h
Int 16h
1
Keyboard shift flags 2
1Eh
Int 13h
1
Keyboard buffer
41h
Int 13h
1
Floppy disk drive status
42h
Int 13h
1
Hard disk and floppy controller status register 0
43h
Int 13h
1
Floppy drive controller status register 1
44h
Int 13h
1
Floppy drive controller status register 2
49h
Int 10h
1
Active video mode setting
63h
Int 10h
1
I/O port address for the video display adapter
65h
Int 10h
1
Video display adapter internal mode register
67h

2
Adapter ROM offset address
69h

2
Adapter ROM segment address
6Bh

1
Last interrupt (not PC)
74h
Int 13h
1
Status of last hard disk operation
75h
Int 13h
1
Number of hard disk drives
8Ch
Int 13h
1
HDD controller status
F0h

16
Intra-applications communications area

 
3.Using special commands
In order to view the Processor details, we can use a special command which is provided by the processor manufacturers. The cpuid command requires no operands, but takes arguments from the EAX register. The value stored in the EAX register before calling the cpuid command, specifies what information is returned.

Argument given to the EAX register
Result
EAX=0
Get vendor ID
EAX=1
Processor Info and Feature Bits
EAX=2
 Cache and TLB Descriptor information
EAX=3
Processor Serial Number
EAX=80000000h
Get Highest Extended Function Supported
EAX=80000001h
Extended Processor Info and Feature Bits
EAX=80000002h,80000003h,80000004h
Processor Brand String
EAX=80000005h
L1 Cache and TLB Identifiers
EAX=80000006h
Extended L2 Cache Features
EAX=80000007h
 Advanced Power Management Information
EAX=80000008h
Virtual and Physical address Sizes

Ex:
_show_CPU_VendorID:
          ;******************read CPU vendor ID
          mov eax,0
          cpuid
          mov [vendorID], ebx
          mov [vendorID+4],edx
          mov [vendorID+8],ecx         
          call _display_endl
          mov si, strVendorID
          mov al, 0x01
     int 0x21
          call _display_space
          mov si, vendorID                 ;print CPU vender ID
          mov al, 0x01
    int 0x21
                  ret      
;end

The material below helped me to complete this assignment…Hope they’ll be helpful to you else also.
Hexadecimal to decimal conversion 
The procedure given below will convert the value stored in the DX register to decimal and print it character by character using decimal to ASCII conversion.
_hexToDec:                        ;convert hex to decimal
          push ax
          push bx
          push cx
          push si
          mov ax,dx                ;copy number into AX
          mov si,10                ;SI will be our divisor
          xor cx,cx                ;clean up the CX
_non_zero:
          xor dx,dx                ;clean up the DX
          div si                   ;divide by 10
          push dx                  ;push number onto the stack
          inc cx                   ;increment CX to do it more times
          or ax,ax                 ;end of the number?
          jne _non_zero            ;if not go to _non_zero
_write_digits:
          pop dx                    ;get the digit off DX
          add dl,0x30               ;add 48 to get the ASCII value
          call _print_char          ;print
          loop _write_digits        ;keep going till cx == 0
          pop si                   ;restore SI
          pop cx                   ;restore DX
          pop bx                   ;restore CX
          pop ax                   ;restore AX
          ret                     
_print_char:
          push ax                 ;save the current AX register

          mov al, dl
        mov ah, 0x0E            ;BIOS teletype acts on newline
        mov bh, 0x00
        mov bl, 0x07
    int 0x10
          pop ax                  ;restore the AX register
          ret
                       ;end  
If you need to have a look at what i implemented here is my kernal.asm file. Below are the methods I implemented.  If you can't understand any, feel free to ask me. :)

Method
Action
_display_hardware_info:
Display hardware information invoked by “hinfo” command
_show_CPU_VendorID:
Show CPU vendor ID
_show_Processor_Brand:
Show processor brand
_show_floppy_info:
Show available number of floppy drives
_no_floppyD:
If no floppy drives found print 0
_available_floppyD:
Print the number of floppy drives
_show_serial_info:
Show number of installed serial ports
_show_parallel_info:
Show number of installed parallel ports
_show_memory_info:
Show RAM size
_remove_cx_conflict:
Some bioses return CX=BX=0 if so copy ax to cx and bx to dx
_memCalculate:
Calculate and print the memory size
_MemErr:
If an error occurred print the error
_show_HDD_info:
Show number of installed Hard Disk Drives
_show_Mouse_status:
Show if a PS/2 mouse is installed
_print_true:
Print “true”
_print_false:
Print “false”
_display_custom_msg:
Display a custom message stored in the strTest invoked by “who” command
_display_help:
Display help invoked by “help” command

Here's list of what i referred while doing this assignment. A big thank goes to all of them.
           
http://asiri.rathnayake.org/articles/hacking-josh-operating-system-tutorial/
http://www.mohanraj.info/josh5.jsp
http://wiki.osdev.org/Main_Page
http://www.bioscentral.com/misc/bda.htm
http://wiki.osdev.org/NASM
http://wiki.osdev.org/Detecting_Memory_%28x86%29
http://wiki.osdev.org/Detecting_CPU_Speed
http://en.wikipedia.org/wiki/INT_(x86_instruction)
http://cyberasylum.wordpress.com/2010/11/19/assembly-tips-and-tricks/
http://en.wikipedia.org/wiki/CPUID

So that's about it for now. A long post, i guess. Hope this helps you guys. Please feel free to leave a comment on anything you need clarification. There are lots of resources available in the Internet. So don't be afraid to mod your OS by adding more features. Have fun with it. Bye for now. :)