Advertisement
NovaYoshi

bootloader

Mar 20th, 2013
194
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; Edited version of the FritzOS boot code.
  2. ; Start Of Assembly Code:
  3.  
  4. ; The BIOS loads the code into address 0x7C00, so tell NASM where our code is going to be running from.
  5.     ORG 0x7c00
  6.  
  7.     jmp Start
  8.     db "MSWIN4.1" ; OEM
  9.     dw 512        ; bytes per sector
  10.     db 1          ; sectors per cluster
  11.     dw 1          ; number of reserved sectors ( including sector zero )
  12.     db 2          ; number of file allocation tables
  13.     dw 224        ; total number of directory entries
  14.                   ; (must be set so that the root directory occupies entire sectors)
  15.     dw 2880       ; total sectors in logical volume
  16.     db 42         ; media descriptor type (?)
  17.     dw 9          ; sectors per FAT (FAT12/16 only)
  18.     dw 18         ; sectors per track
  19.     dw 2          ; number of heads or sides on storage media
  20.     dd 0          ; number of hidden sectors
  21.     dd 1337       ; large amount of sector on disk
  22.  
  23. ; total sectors 2880
  24.  
  25.     db $00        ; drive number
  26.     db $00        ; flags
  27.     db $28        ; $28 or $29
  28.     db "YIFF"     ; volume serial number
  29.     db "WahovipabOS" ; volume label
  30.     db "FAT12   " ;system identifier
  31.  
  32. [BITS 16]
  33. Start:  mov [drive], dl     ; Save the index of the floppy we booted from
  34.         cli
  35.         mov ax, 0x03        ; Start in text mode
  36.         int 0x10
  37.  
  38. ; ------------------------------------------------------
  39.         mov ah, 02h ; set cursor pos
  40.         mov bh,0
  41.         mov dh, 5  ; row
  42.         mov dl, 15 ; col
  43.         int 10h
  44.  
  45.         mov ah, 0eh
  46.         mov bh, 0
  47.         mov bl, 15
  48.  
  49.         mov al, 'B'
  50.         int 10h
  51.         mov al, 'o'
  52.         int 10h
  53.         mov al, 'o'
  54.         int 10h
  55.         mov al, 't'
  56.         int 10h
  57.         mov al, ' '
  58.         int 10h
  59.         mov al, 'O'
  60.         int 10h
  61.         mov al, 'K'
  62.         int 10h
  63.         mov al, '!'
  64.         int 10h
  65.         mov al, ' '
  66.         int 10h
  67.         mov al, 3
  68.         int 10h
  69.  
  70.         mov ah, 0
  71.         int 16h
  72. ; ------------------------------------------------------
  73.  
  74.  
  75. ResetFloppy:                ; Get ready to load the kernel from the floppy. First, we reset it.
  76.         mov ax,     0x00    ; Select Floppy Reset BIOS Function
  77.         mov dl,     [drive] ; Select the floppy FritzOS booted from
  78.         int 13h             ; Reset the floppy drive
  79.         jc ResetFloppy      ; If there was a error, try again.
  80.  
  81. ; Now talk to the floppy drive
  82. ReadFloppy:
  83.         mov bx,    0x9000   ; Load FritzOS at 0x9000.
  84.         mov ah,    0x02     ; Load disk data to ES:BX
  85.         mov al,    17       ; Load two floppy head full's worth of data.
  86.         mov ch,    0        ; First Cylinder
  87.         mov cl,    2        ; Start at the 2nd Sector
  88.         mov dh,    0        ; Use first floppy head
  89.         mov dl,    [drive]  ; Load from the drive FritzOS booted from.
  90.         int 0x13            ; Read the floppy disk.
  91.         jc ReadFloppy       ; Error, try again.
  92. ReadFloppy2:                ; Read another floppy head
  93.         mov al, 17          ; The Second Head Full
  94.         inc dh              ; Set it to the second head
  95.         int 13h             ; Read the floppy disk.
  96.         jc ReadFloppy2      ; If there was a error, try again.
  97. SetPMode:                   ; Get ready to set PMode ( Protected Mode)
  98.  
  99. ; ------------------------------------------------------
  100.         mov ah, 02h ; set cursor pos
  101.         mov bh,0
  102.         mov dh, 6  ; row
  103.         mov dl, 15 ; col
  104.         int 10h
  105.  
  106.         mov ah, 0eh
  107.         mov bh, 0
  108.         mov bl, 15
  109.  
  110.         mov al, 'L'
  111.         int 10h
  112.         mov al, 'o'
  113.         int 10h
  114.         mov al, 'a'
  115.         int 10h
  116.         mov al, 'd'
  117.         int 10h
  118.         mov al, ' '
  119.         int 10h
  120.         mov al, 'O'
  121.         int 10h
  122.         mov al, 'K'
  123.         int 10h
  124.         mov al, '!'
  125.         int 10h
  126.         mov al, ' '
  127.         int 10h
  128.         mov al, 3
  129.         int 10h
  130.  
  131.         mov ah, 0
  132.         int 16h
  133.  
  134.         mov ax, 0x13        ; Change into mode 13h now
  135.         int 0x10
  136.  
  137. ;        call do_e820
  138.  
  139. ; ------------------------------------------------------
  140. ; http://wiki.osdev.org/Detecting_Memory_(x86)
  141.  
  142.         ; Load a temporary GDTR.
  143.         lgdt [GDTR]         ; Load the GDTR.
  144.  
  145.         ; Set Protected Mode ( PMode )
  146.         mov eax,    cr0     ; Get the first control register.
  147.         or eax,     1       ; Poke the 'Protected mode' bit into it.
  148.         mov cr0,    eax     ; Store the modified control register.
  149.  
  150.         ; The CPU needs to jump at least once to get set up the rest of the way for protected mode
  151.         jmp dword CodeSel:PMode
  152.  
  153. [bits 32] ; Tell NASM that we're in 32-bit protected mode now
  154. PMode:  ; Put the Data Selector into eax for setting up other registers.
  155.         mov eax,   DataSel      ; Data Selector.
  156.  
  157.     ; Make SS, DS, ES, FS and GS = the Data Selector ( In the GDT )
  158.         mov ss, eax
  159.         mov ds, eax
  160.         mov es, eax
  161.         mov fs, eax
  162.         mov gs, eax
  163.  
  164.     ; Set up the PMode stack:
  165.         mov ax, 0x10
  166.         mov ss, ax
  167.         mov esp, 0xFFFF ; Init stack
  168.  
  169.     ; Stop the floppy motor from spinning ( since we are in PMode, the BIOS can't stop it so we stop it )
  170.         mov dl, [ drive ]       ; Select which motor to stop ( the floppy drive FritzOS booted from )
  171.  
  172.     ; Select Stop Floppy Motor function:
  173.         mov dx, 0x3f2
  174.         mov al, 0x0c
  175.         out dx, al      ; Floppy Motor stopped!
  176.    
  177.         jmp dword CodeSel:0x9000    ; Jump to the main kernel
  178.  
  179.  
  180. ; use the INT 0x15, eax= 0xE820 BIOS function to get a memory map
  181. ; inputs: es:di -> destination buffer for 24 byte entries
  182. ; outputs: bp = entry count, trashes all registers except esi
  183. do_e820:
  184.     xor ebx, ebx        ; ebx must be 0 to start
  185.     xor bp, bp      ; keep an entry count in bp
  186.     mov edx, 0x0534D4150    ; Place "SMAP" into edx
  187.     mov eax, 0xe820
  188.     mov [es:di + 20], dword 1   ; force a valid ACPI 3.X entry
  189.     mov ecx, 24     ; ask for 24 bytes
  190.     int 0x15
  191.     jc short .failed    ; carry set on first call means "unsupported function"
  192.     mov edx, 0x0534D4150    ; Some BIOSes apparently trash this register?
  193.     cmp eax, edx        ; on success, eax must have been reset to "SMAP"
  194.     jne short .failed
  195.     test ebx, ebx       ; ebx = 0 implies list is only 1 entry long (worthless)
  196.     je short .failed
  197.     jmp short .jmpin
  198. .e820lp:
  199.     mov eax, 0xe820     ; eax, ecx get trashed on every int 0x15 call
  200.     mov [es:di + 20], dword 1   ; force a valid ACPI 3.X entry
  201.     mov ecx, 24     ; ask for 24 bytes again
  202.     int 0x15
  203.     jc short .e820f     ; carry set means "end of list already reached"
  204.     mov edx, 0x0534D4150    ; repair potentially trashed register
  205. .jmpin:
  206.     jcxz .skipent       ; skip any 0 length entries
  207.     cmp cl, 20      ; got a 24 byte ACPI 3.X response?
  208.     jbe short .notext
  209.     test byte [es:di + 20], 1   ; if so: is the "ignore this data" bit clear?
  210.     je short .skipent
  211. .notext:
  212.     mov ecx, [es:di + 8]    ; get lower dword of memory region length
  213.     or ecx, [es:di + 12]    ; "or" it with upper dword to test for zero
  214.     jz .skipent     ; if length qword is 0, skip entry
  215.     inc bp          ; got a good entry: ++count, move to next storage spot
  216.     add di, 24
  217. .skipent:
  218.     test ebx, ebx       ; if ebx resets to 0, list is complete
  219.     jne short .e820lp
  220. .e820f:
  221.     mov [mmap_ent], bp  ; store the entry count
  222.     clc         ; there is "jc" on end of list to this point, so the carry must be cleared
  223.     ret
  224. .failed:
  225.     stc         ; "function unsupported" error exit
  226.     ret
  227.  
  228. ; Protected mode needs a list of where the segments are in memory and what privelages they get.
  229. GDTR    dw GDTEnd-1
  230.         dd GDT
  231. GDT
  232. nullsel equ $-GDT
  233. GDT0    dd 0
  234.         dd 0
  235. CodeSel equ $-GDT
  236.         dw 0ffffh
  237.         dw 0
  238.         db 0
  239.         db 09ah
  240.         db 0cfh
  241.         db 0h
  242. DataSel equ $-GDT
  243.         dw 0ffffh
  244.         dw 0h
  245.         db 0h
  246.         db 092h
  247.         db 0cfh
  248.         db 0
  249. GDTEnd
  250.  
  251.     mmap_ent db 0
  252. ; This part makes sure the bootsector is 512 bytes.
  253.     drive db 0  ; For storing which drive we boot from
  254.     ; The original version from FritzOS had AA55 in the wrong place!
  255.     times 510-($-$$) db 0   ; moved over
  256.     dw 0xAA55   ; BIOS checks this value to make sure it is AA55
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement