32_bit_os/boot/boot.asm
2022-12-19 23:55:10 -05:00

148 lines
2.9 KiB
NASM

ORG 0x7c00
BITS 16
CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start
jmp short start
nop
;FAT16 HEADER
OEMIdentifier db 'AOMUAOMU' ; Must be 8 bytes
BytesPerSector dw 0x200 ; 512 bytes per sector
SectorsPerCluster db 0x80 ;
ReservedSectors dw 0xC8 ; 200 reserved sectors for kernel
FATCopies db 0x02 ;
RootDirEntries dw 0x40 ;
NumSectors dw 0x00 ; Unused
MediaType db 0xF8 ; ?
SectorsPerFat dw 0x100 ; ?
SectorsPerTrack dw 0x20
NumberOfHeads dw 0x40
HiddenSectors dd 0x00
SectorsBig dd 0x773594 ; ??
; Extended BPB (Dos 4.0)
DriveNumber db 0x80
WinNTBit db 0x00
Signature db 0x29
VolumeID dd 0xd105
VolumeIDString db 'AOMUAOMUBOO' ; Must be 11 bytes
SystemIDString db 'FAT16 ' ; Must be 8 bytes
start:
jmp 0:step2 ; Set code segment
step2:
cli ; Clear Interrupts
mov ax, 0x00
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7c00
sti ; Enable Interrupts
.load_protected:
cli
lgdt[gdt_descriptor]
mov eax, cr0
or eax, 0x1
mov cr0, eax
jmp CODE_SEG:load32
;GDT
gdt_start:
gdt_null:
dd 0x0
dd 0x0
; offset 0x8
gdt_code: ; CS should point here
dw 0xffff ; Segment limit 0:15
dw 0 ; Base 0:15
db 0 ; Base 16:23
db 0x9a ; Access byte
db 11001111b; high 4 bit & low 4 bit flags
db 0 ; Base 24:31
gdt_data: ; DS, SS, ES, FS, GS
dw 0xffff ; Segment limit 0:15
dw 0 ; Base 0:15
db 0 ; Base 16:23
db 0x92 ; Access byte
db 11001111b ; high 4 bit & low 4 bit flags
db 0 ; Base 24:31
gdt_end:
gdt_descriptor:
dw gdt_end - gdt_start - 1
dd gdt_start
[BITS 32]
load32:
mov eax, 1 ; start sector
mov ecx, 100 ; number of sectors to read
mov edi, 0x0100000 ; destination address
call ata_lba_read
jmp CODE_SEG:0x0100000
ata_lba_read:
mov ebx, eax ; backup eax for later
; send the highest 8 bits to the disk controller
shr eax, 24
or eax, 0xE0 ; select master drive
mov dx, 0x1F6
out dx, al
; send total sectors to read
mov eax, ecx
mov dx, 0x1F2
out dx, al
; send another 8 bits of the lba
mov eax, ebx
mov dx, 0x1F3
out dx, al
; send another 8 bits of the lba
mov dx, 0x1F4
mov eax, ebx ; restore the backup lba, just in case
shr eax, 8
out dx, al
; send upper 16 bits of lba
mov dx, 0x1F5
mov eax, ebx
shr eax, 16
out dx, al
mov dx, 0x1F7
mov al, 0x20
out dx, al
; Read all sectors into memory
.next_sector:
push ecx
; checking if we need to read
.try_again:
mov dx, 0x1F7
in al, dx
test al, 8
jz .try_again
; read 256 words at a time
mov ecx, 256
mov dx, 0x1F0
rep insw
pop ecx
loop .next_sector
ret
times 510- ($ - $$) db 0 ; pad with zeros to 510 bytes (+boot signature)
dw 0xAA55