mirror of
https://github.com/gbowne1/ClassicOS.git
synced 2025-10-13 13:15:07 -07:00
fixed bootloader by adding lba conversion from chs
This commit is contained in:
@@ -21,25 +21,26 @@ start:
|
|||||||
mov es, ax
|
mov es, ax
|
||||||
|
|
||||||
; Load second-stage bootloader (boot1.asm) to 0x7E00
|
; Load second-stage bootloader (boot1.asm) to 0x7E00
|
||||||
mov si, 0x7E00 ; Destination offset (ES already zero, so physical 0x7E00)
|
mov ax, 1 ; LBA of boot1.asm (starts at sector 1)
|
||||||
mov al, 1 ; Number of sectors to read (adjust if needed)
|
call lba_to_chs
|
||||||
mov cl, 1 ; Starting sector (CHS - sector number, 1-based)
|
mov si, 0x7E00
|
||||||
|
mov al, 4 ; Number of sectors to read
|
||||||
call read_chs
|
call read_chs
|
||||||
jc disk_error ; Jump if carry set (read error)
|
|
||||||
|
|
||||||
; Load kernel to 0x100000 (1 MB)
|
; Load kernel to 0x100000 (1 MB)
|
||||||
mov si, 0x0000 ; Destination offset
|
mov si, 0x0000 ; Destination offset
|
||||||
mov ax, 0x1000 ; ES = 0x1000 (0x1000:0x0000 = 1 MB)
|
mov ax, 0x1000 ; ES = 0x1000 (0x1000:0x0000 = 1 MB)
|
||||||
mov es, ax
|
mov es, ax
|
||||||
xor bx, bx
|
xor bx, bx
|
||||||
mov al, 16 ; Number of sectors for kernel (example)
|
mov ax, 5 ; LBA of kernel start (boot1 is 4 sectors: LBA 1–4 → kernel at LBA 5)
|
||||||
mov cl, 2 ; Starting sector (adjust as per your disk layout)
|
call lba_to_chs
|
||||||
|
mov al, 16 ; Number of sectors for kernel
|
||||||
call read_chs
|
call read_chs
|
||||||
jc disk_error
|
jc disk_error
|
||||||
|
|
||||||
; Memory Validation: Verify checksum of second stage bootloader
|
; Memory Validation: Verify checksum of second stage bootloader
|
||||||
mov si, 0x7E00 ; Start of second stage
|
mov si, 0x7E00 ; Start of second stage
|
||||||
mov cx, 512 ; Size in bytes (adjust if more sectors loaded)
|
mov cx, 512 * 4 ; Size in bytes (adjust if more sectors loaded)
|
||||||
call verify_checksum
|
call verify_checksum
|
||||||
jc disk_error ; Jump if checksum fails
|
jc disk_error ; Jump if checksum fails
|
||||||
|
|
||||||
@@ -100,16 +101,52 @@ verify_checksum:
|
|||||||
; AL = number of sectors
|
; AL = number of sectors
|
||||||
; CL = starting sector (1-based)
|
; CL = starting sector (1-based)
|
||||||
; SI = destination offset (Segment:ES already set)
|
; SI = destination offset (Segment:ES already set)
|
||||||
|
; Inputs:
|
||||||
|
; AL = sector count
|
||||||
|
; CH = cylinder
|
||||||
|
; DH = head
|
||||||
|
; CL = sector (1–63, with top 2 bits as high cylinder bits)
|
||||||
|
; SI = destination offset (segment ES must be set)
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------
|
||||||
|
; Convert LBA to CHS
|
||||||
|
; Inputs:
|
||||||
|
; AX = LBA sector number (0-based)
|
||||||
|
; Outputs:
|
||||||
|
; CH = cylinder
|
||||||
|
; DH = head
|
||||||
|
; CL = sector (1-63, top 2 bits are upper cylinder bits)
|
||||||
|
|
||||||
|
lba_to_chs:
|
||||||
|
pusha
|
||||||
|
xor dx, dx
|
||||||
|
mov bx, [sectors_per_track]
|
||||||
|
div bx ; AX = LBA / sectors_per_track, DX = LBA % spt
|
||||||
|
mov si, ax ; temp quotient
|
||||||
|
mov cx, [heads_per_cylinder]
|
||||||
|
xor dx, dx
|
||||||
|
div cx ; AX = cylinder, DX = head
|
||||||
|
mov ch, al ; CH = cylinder low
|
||||||
|
mov dh, dl ; DH = head
|
||||||
|
mov cl, sil ; CL = sector number (0-based)
|
||||||
|
inc cl ; Sector is 1-based
|
||||||
|
mov ah, al
|
||||||
|
and ah, 0xC0 ; upper 2 bits of cylinder
|
||||||
|
or cl, ah ; insert upper cylinder bits into CL
|
||||||
|
popa
|
||||||
|
ret
|
||||||
|
|
||||||
read_chs:
|
read_chs:
|
||||||
pusha
|
pusha
|
||||||
push dx
|
push dx
|
||||||
|
|
||||||
mov cx, 5
|
mov cx, 5
|
||||||
.retry:
|
.retry:
|
||||||
mov ah, 0x02 ; BIOS read sector
|
mov ah, 0x02 ; BIOS: Read sectors
|
||||||
mov dl, [bootdev] ; Drive number
|
mov dl, [bootdev] ; Boot device
|
||||||
|
; Assume CH, DH, CL already set before this call
|
||||||
int 0x13
|
int 0x13
|
||||||
|
jc .error
|
||||||
jc .error ; Carry flag set = error
|
|
||||||
pop dx
|
pop dx
|
||||||
popa
|
popa
|
||||||
ret
|
ret
|
||||||
@@ -123,27 +160,58 @@ read_chs:
|
|||||||
|
|
||||||
; ----------------------------------------------------------------
|
; ----------------------------------------------------------------
|
||||||
enable_a20:
|
enable_a20:
|
||||||
; Fast A20 gate method
|
; Try fast A20 gate method
|
||||||
in al, 0x92
|
in al, 0x92
|
||||||
or al, 0x02
|
or al, 0x02
|
||||||
|
and al, 0xFE ; Clear bit 0 to avoid fast A20 bugs
|
||||||
out 0x92, al
|
out 0x92, al
|
||||||
; Fallback method (keyboard controller)
|
|
||||||
jc .fallbackenable_a20:
|
|
||||||
; Fast A20 method
|
|
||||||
in al, 0x92
|
|
||||||
or al, 0x02
|
|
||||||
and al, 0xFE ; Clear bit 0 to avoid fast A20 issues on some systems
|
|
||||||
out 0x92, al
|
|
||||||
; Verify A20
|
; Verify A20
|
||||||
call check_a20
|
call check_a20
|
||||||
jnc .done
|
jnc .done ; Success
|
||||||
; Fallback method
|
|
||||||
mov al, 0xAD
|
; Fallback: use keyboard controller method
|
||||||
out 0x64, al
|
call .fallback
|
||||||
; ... (rest of keyboard controller code)
|
|
||||||
.done:
|
.done:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
.fallback:
|
||||||
|
mov al, 0xAD ; Disable keyboard
|
||||||
|
out 0x64, al
|
||||||
|
call .wait_input_clear
|
||||||
|
|
||||||
|
mov al, 0xD0 ; Command: read output port
|
||||||
|
out 0x64, al
|
||||||
|
call .wait_output_full
|
||||||
|
in al, 0x60
|
||||||
|
or al, 0x02 ; Set A20 enable bit
|
||||||
|
mov bl, al
|
||||||
|
|
||||||
|
call .wait_input_clear
|
||||||
|
mov al, 0xD1 ; Command: write output port
|
||||||
|
out 0x64, al
|
||||||
|
call .wait_input_clear
|
||||||
|
mov al, bl
|
||||||
|
out 0x60, al
|
||||||
|
|
||||||
|
call .wait_input_clear
|
||||||
|
mov al, 0xAE ; Enable keyboard
|
||||||
|
out 0x64, al
|
||||||
|
ret
|
||||||
|
|
||||||
|
.wait_input_clear:
|
||||||
|
in al, 0x64
|
||||||
|
test al, 0x02
|
||||||
|
jnz .wait_input_clear
|
||||||
|
ret
|
||||||
|
|
||||||
|
.wait_output_full:
|
||||||
|
in al, 0x64
|
||||||
|
test al, 0x01
|
||||||
|
jz .wait_output_full
|
||||||
|
ret
|
||||||
|
|
||||||
check_a20:
|
check_a20:
|
||||||
in al, 0x64 ; Read keyboard controller status
|
in al, 0x64 ; Read keyboard controller status
|
||||||
test al, 0x02 ; Check if input buffer is full
|
test al, 0x02 ; Check if input buffer is full
|
||||||
@@ -166,19 +234,6 @@ check_a20:
|
|||||||
clc ; Clear carry flag to indicate success
|
clc ; Clear carry flag to indicate success
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.fallback:
|
|
||||||
mov al, 0xAD
|
|
||||||
out 0x64, al
|
|
||||||
mov al, 0xD0
|
|
||||||
out 0x64, al
|
|
||||||
in al, 0x60
|
|
||||||
or al, 0x02
|
|
||||||
mov al, 0xD1
|
|
||||||
out 0x64, al
|
|
||||||
mov al, 0xAE
|
|
||||||
out 0x64, al
|
|
||||||
ret
|
|
||||||
|
|
||||||
; ----------------------------------------------------------------
|
; ----------------------------------------------------------------
|
||||||
gdt_start:
|
gdt_start:
|
||||||
dq 0x0000000000000000 ; Null descriptor
|
dq 0x0000000000000000 ; Null descriptor
|
||||||
|
Reference in New Issue
Block a user