Skip to content

Instantly share code, notes, and snippets.

@oriapp
Created November 14, 2022 20:44
Show Gist options
  • Save oriapp/972e433725549c6e6bd1777e01dd3c74 to your computer and use it in GitHub Desktop.
Save oriapp/972e433725549c6e6bd1777e01dd3c74 to your computer and use it in GitHub Desktop.
bootloader
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 'POTONGOS'
BytesPerSector dw 0x200
SectorsPerCluster db 0x80
ReservedSectors dw 200
FATCopies db 0x02
RootDirEntries dw 0x40
NumSectors dw 0x00
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 'POTONGOS BO'
SystemIDString db 'FAT16 '
start:
jmp 0: step2
step2:
cli
mov ax, 0x00
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7c00
sti
.load_protected:
cli
lgdt[gdt_descriptor]
mov eax, cr0
or eax, 0x1
mov cr0, eax
jmp CODE_SEG: load32 ; jmp 0x08: laod32
; GDT
gdt_start:
gdt_null:
dd 0x0
dd 0x0
; 64 bits of 0
; offset 0x8
gdt_code: ; CS SHOULD POINT TO THIS
dw 0xffff ; Segment limit 0-15 bits
dw 0 ; base first 0-15 bits
db 0 ; base 16-23 bits
db 0x9a ; access byte
db 11001111b; high 4 bit flags and the low 4 bit flags
db 0 ; base 24 - 31 bits
; offset 0x10
gdt_data: ; DS, SS, ES, FS, GS
dw 0xffff ; segment limit 0-15 bits
dw 0 ; base first 0-15 bits
db 0 ; base 16-23 bits
db 0x92 ; access byte
db 11001111b; high 4 bit flags and the low 4 bit flags
db 0 ; base 24 - 31 bits
gdt_end:
gdt_descriptor:
dw gdt_end - gdt_start - 1 ; size of the descriptor
dd gdt_start
[BITS 32]
load32: ; 0 is the boot sector
mov eax, 1 ; starting sector
mov ecx, 100 ; 100 sectors of null
mov edi, 0x0100000 ; 1MG (related to rep insw
call ata_lba_read
jmp CODE_SEG: 0x0100000
ata_lba_read:
mov ebx, eax ; Backup the LBA
; Send the highest 8 bits of the lba hard disk controller
shr eax, 24 ; Short eax register 24 bits to the right (32 - 24 = 8)
; EAX after the line above will contain the 8 highest bits of the LBA
or eax, 0xE0 ; Select the master drive (there is slave and master)
mov dx, 0x1F6
out dx, al ; AL is bits containing highest 8 bits of the LBA
; Finished sending the highest 8 bits of the LBA
; Send the total sectors to read
mov eax, ecx
mov dx, 0x1F2
out dx, al
; Finished sending the total sectors to read
; Send more bits of the LBA
mov eax, ebx ; Restore the backup LBA
mov dx, 0x1F3
out dx, al
; Finished sending more bits of the LBA
; Send more bits of the LBA
mov dx, 0x1F4
mov eax, ebx ; Restore the backup LBA
shr eax, 8
out dx, al
; Finished sending more bits of the LBA
; Send upper 16 bits of the LBA
mov dx, 0x1F5
mov eax, ebx ; Restore the backup LBA
shr eax, 16
out dx, al
; Finished sending upper 16 bits of the LBA
mov dx, 0x1F7
mov al, 0x20
out dx, al
; Read all sectors into memory
.next_sector:
push ecx
; check(ing) if we need to read
.try_again:
mov dx, 0x1F7
in al, dx
test al, 8
jz .try_again
; We need to read 256 words at a time
mov ecx, 256 ; 256 words is 512 bytes (: i.e one sector
; ^ Do the insw instruction 256 times
mov dx, 0x1F0
rep insw ; Input word from I/O port specified in DX into memory location specified in ES:(E)DI
; Reading from port 0x1F0 and storing it into "0x0100000"
pop ecx
loop .next_sector
; End of reading sectors into memory
ret
times 510-($ - $$) db 0
dw 0xAA55 ; Signature word
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment