Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- %define BUFFER_OFF 0x8000
- %define BUFFER_SEG 0x0000
- %define LOAD_SEG 0x0c00
- %define LOAD_OFF 0x0000
- [bits 16]
- [org 0x7c00]
- jmp short start
- nop
- ;DISK DESCRIPTION(BIOS PARAMETER BLOCK)
- OEMLabel db "BOOT "
- BytesPerSector dw 512
- SectorsPerCluster db 1
- ReservedForBoot dw 1
- NumberOfFats db 2
- RootDirEntries dw 224 ; Number of entries in root dir
- ; (224 * 32 = 7168 = 14 sectors to read)
- LogicalSectors dw 2880
- MediumByte db 0F0h
- SectorsPerFat dw 9
- SectorsPerTrack dw 18 ; Sectors per track (36/cylinder)
- Sides dw 2
- HiddenSectors dd 0
- LargeSectors dd 0
- DriveNo dw 0
- Signature db 0x29
- VolumeID dd 00000000h
- VolumeLabel db "myOS "
- FileSystem db "FAT12 "
- ;BOOTLOADER
- start:
- xor ax, ax
- mov ds, ax
- cli
- mov ss, ax
- mov sp, 0x7c00
- sti
- cld
- mov [drive], dl
- mov si, BUFFER_SEG ; ES=buffer segment. Only has to be set once
- mov es, si
- mov bx, BUFFER_OFF
- load_root:
- mov ax, 19 ; Root directory starts at LBA 19
- call lba_to_hts
- mov ax, (2<<8) | 14 ; Root directory for this media fits in 14 sectors
- ; Combine 2 moves (AH/AL) into one
- ; same as 'mov ah, 2' and 'mov al, 14'
- int 13h
- jc reset
- mov si, load_root_str
- call print
- search_file:
- mov di, BUFFER_OFF
- mov cx, word [RootDirEntries]
- xor ax, ax
- .loop_search:
- xchg cx, dx
- mov si, filename
- mov cx, 11
- rep cmpsb
- je file_found
- add ax, 32
- mov di, BUFFER_OFF
- add di, ax
- xchg dx, cx
- loop .loop_search
- jmp file_not_found
- file_found:
- mov ax, word [di+15] ; Buffer and Bootloader now in same segment DS
- ; Don't need ES:
- mov [cluster], ax
- mov ax, 1
- call lba_to_hts
- mov bx, BUFFER_OFF
- mov ax, (2<<8) | 9 ; Combine 2 moves (AH/AL) into one
- ; same as 'mov ah, 2' and 'mov al, 9'
- load_FAT:
- mov si, FAT_str
- call print
- int 13h
- jnc load_file
- call reset
- jnc load_FAT
- jmp disk_error
- load_file:
- mov si, load_file_str
- call print
- mov ax, LOAD_SEG ; ES=load segment for kernel
- mov es, ax
- load_sector:
- mov ax, word [cluster] ; Get cluster number to read
- add ax, 33-2 ; Add 31 to cluster since FAT data area
- ; starts at Logical Block Address (LBA) 33
- ; and we need to subtract 2 since valid
- ; cluster numbers start at 2
- call lba_to_hts
- xor bx, bx ; Always read a kernel sector to offset 0
- mov ax, (2<<8) | 1 ; AH=2 is read, AL=1 read 1 sector
- ; Combine 2 moves (AH/AL) into one
- ; same as 'mov ah, 2' and 'mov al, 1'
- int 13h
- jnc next_cluster
- call reset
- jmp load_sector
- next_cluster:
- mov bx, [cluster] ; BX = current cluster number
- mov ax, bx ; AX = copy of cluster number
- shl bx, 1 ; BX = BX * 2
- add bx, ax ; BX = BX + AX (BX now contains BX * 3)
- shr bx, 1 ; Divide BX by 2
- mov ax, [bx+BUFFER_OFF] ; Get cluster entry from FAT table
- jnc .even ; If carry not set by SHR then result was even
- .odd:
- shr ax, 4 ; If cluster entry is odd then cluster number is AX >> 4
- jmp short finish_load
- .even:
- and ah, 0Fh ; If cluster entry is even then cluster number is AX & 0fffh
- ; We just need to and AH with 0fh to achieve the same result
- finish_load:
- mov word [cluster], ax
- cmp ax, 0FF8h
- jae .jump_to_file
- mov ax, es
- add ax, 32 ; Increasing segment by 1 advances 16 bytes (paragraph)
- ; in memory. Adding 32 is same advancing 512 bytes (32*16)
- mov es, ax ; Advance ES to point at next 512 byte block to read into
- jmp load_sector ; Go back and load the next sector
- .jump_to_file:
- mov dl, byte [drive]
- jmp 0x0000:(LOAD_SEG<<4)
- ;SUBROUTINES
- file_not_found:
- mov si, not_found_str
- call print
- jmp reboot
- print:
- pusha
- mov ah, 0x0E
- .next:
- lodsb
- cmp al,0
- je .done
- int 0x10
- jmp .next
- .done:
- popa
- ret
- lba_to_hts:
- div byte [SectorsPerTrack] ; 16-bit by 8-bit DIV : LBA / SPT
- mov cl, ah ; CL = S = LBA mod SPT
- inc cl ; CL = S = (LBA mod SPT) + 1
- xor ah, ah ; Upper 8-bit of 16-bit value set to 0 for DIV
- div byte [Sides] ; 16-bit by 8-bit DIV : (LBA / SPT) / HEADS
- mov ch, al ; CH = C = (LBA / SPT) / HEADS
- mov dh, ah ; DH = H = (LBA / SPT) mod HEADS
- mov dl, [drive] ; boot device, not necessary to set but convenient
- ret
- reset:
- mov ah, 0
- int 13h ;reset disk
- jc disk_error ;if failed jump to search fail
- ret
- disk_error:
- mov si, disk_error_str
- call print
- reboot:
- mov si, reboot_pmpt
- call print
- mov ax, 0
- int 16h
- mov ax, 0
- int 19h
- ;DATA
- load_root_str db 'Loading Root',13,10,0
- disk_error_str db 'Disk Error!',13,10,0
- reboot_pmpt db 'PRESS A KEY TO REBOOT',13,10,0
- not_found_str db 'KERNEL NOT FOUND',13,10,0
- FAT_str db 'Loading FAT',13,10,0
- load_file_str db 'Loading KERNEL',13,10,0
- drive dw 0
- cluster dw 0
- filename db 'KERNEL BIN',0
- ;PADDING AND SIGNATURE
- times (510-($-$$)) db 0x00
- dw 0AA55h
- org 0xc000
- [bits 16] ;16-bit binary format
- ;KERNEL
- os_main:
- mov ax, cs ;CS is segment where we were loaded
- cli
- mov ss, ax
- xor sp, sp
- sti
- cld
- mov ds, ax
- mov es, ax
- mov fs, ax
- mov gs, ax
- mov si, hello ;print welcome
- call print
- call A20_line
- call load_gdt
- call set_mode
- ; cli
- ; hlt
- ;SUBROUTINES
- A20_line:
- in al, 0xee
- mov si, A20_enable_str
- call print
- ret
- load_gdt:
- cli
- lgdt [toc]
- sti
- mov si, load_gdt_str
- call print
- ret
- set_mode:
- mov si, set_mode_str
- call print
- cli
- mov eax, cr0
- or al, 1
- mov cr0, eax
- jmp 08h:ENTER_PROTECTED_MODE
- print:
- mov ah, 0x0e
- .next:
- lodsb
- cmp al,0
- je .done
- int 0x10
- jmp .next
- .done:
- ret
- ;DATA
- hello db 'Hello',13,10,0
- A20_enable_str db 'A20 Line enabled',13,10,0
- load_gdt_str db 'Loading GDT',13,10,0
- set_mode_str db 'Entering Protected Mode',13,10,0
- ;GLOBAL DESCRIPTOR TABLE
- gdt_data:
- dd 0 ;null descriptor
- dd 0
- dw 0FFFFh ;code descriptor
- dw 0
- db 0
- db 10011010b
- db 11001111b
- db 0
- dw 0FFFFh ;data descriptor
- dw 0
- db 0
- db 10010010b
- db 11001111b
- db 0
- end_of_gdt:
- toc:
- dw end_of_gdt - gdt_data - 1
- dd gdt_data
- ;PROTECTED MODE
- [bits 32]
- ENTER_PROTECTED_MODE:
- VIDMEM equ 0xB8000
- mov ax, 0x10
- mov es, ax
- mov ds, ax
- mov fs, ax
- mov gs, ax
- mov esp, 0x90000
- mov eax, 0x0f54
- mov [VIDMEM], eax
- cli
- hlt
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement