Optimization and cleanup

Do string comparison two byte at a time
Output error messages for unsupported FAT32 features
This commit is contained in:
Baptiste Wicht 2014-01-02 17:14:14 +01:00
parent c21164d102
commit 8d8bfc3ea1

View File

@ -10,7 +10,6 @@
jmp second_step jmp second_step
%include "intel_16.asm" %include "intel_16.asm"
%include "sectors.asm"
FREE_BASE equ 0x4500 FREE_BASE equ 0x4500
KERNEL_BASE equ 0x600 ; 0x600:0x0 (0x6000) KERNEL_BASE equ 0x600 ; 0x600:0x0 (0x6000)
@ -24,6 +23,18 @@ DAP:
.lba dd 0 .lba dd 0
.lba48 dd 0 .lba48 dd 0
; Perform an extended read using BIOS
; On error, jump to read_failed and never returns
extended_read:
mov ah, 0x42
mov si, DAP
mov dl, 0x80
int 0x13
jc read_failed
ret
; Loaded at 0x410:0x0 (0x4100) ; Loaded at 0x410:0x0 (0x4100)
second_step: second_step:
; Set data segment ; Set data segment
@ -44,12 +55,7 @@ second_step:
mov word [DAP.segment], 0 mov word [DAP.segment], 0
mov dword [DAP.lba], 0 mov dword [DAP.lba], 0
mov ah, 0x42 call extended_read
mov si, DAP
mov dl, 0x80
int 0x13
jc read_failed
mov ax, [gs:(FREE_BASE + 446 + 8)] mov ax, [gs:(FREE_BASE + 446 + 8)]
mov [partition_start], ax mov [partition_start], ax
@ -63,12 +69,7 @@ second_step:
mov di, [partition_start] mov di, [partition_start]
mov word [DAP.lba], di mov word [DAP.lba], di
mov ah, 0x42 call extended_read
mov si, DAP
mov dl, 0x80
int 0x13
jc read_failed
mov ah, [gs:(FREE_BASE + 13)] mov ah, [gs:(FREE_BASE + 13)]
mov [sectors_per_cluster], ah mov [sectors_per_cluster], ah
@ -79,6 +80,11 @@ second_step:
mov ah, [gs:(FREE_BASE + 16)] mov ah, [gs:(FREE_BASE + 16)]
mov [number_of_fat], ah mov [number_of_fat], ah
mov ax, [gs:(FREE_BASE + 38)]
test ax, ax
jne sectors_per_fat_too_high
; sectors_per_fat (only low part)
mov ax, [gs:(FREE_BASE + 36)] mov ax, [gs:(FREE_BASE + 36)]
mov [sectors_per_fat], ax mov [sectors_per_fat], ax
@ -100,9 +106,8 @@ second_step:
mov [cluster_begin], ax mov [cluster_begin], ax
; entries per cluster = (512/32) * sectors_per_cluster ; entries per cluster = (512/32) * sectors_per_cluster
mov ax, 32 movzx ax, byte [sectors_per_cluster]
movzx bx, byte [sectors_per_cluster] shl ax, 4
mul bx
mov [entries_per_cluster], ax mov [entries_per_cluster], ax
; 3. Read the root directory to find the kernel executable ; 3. Read the root directory to find the kernel executable
@ -122,12 +127,7 @@ second_step:
mov word [DAP.lba], ax mov word [DAP.lba], ax
mov ah, 0x42 call extended_read
mov si, DAP
mov dl, 0x80
int 0x13
jc read_failed
mov si, FREE_BASE mov si, FREE_BASE
xor cx, cx xor cx, cx
@ -139,48 +139,28 @@ second_step:
test ah, ah test ah, ah
je .end_of_directory je .end_of_directory
; Verify char by char if it is KERNEL.BIN mov ax, [gs:si]
cmp ah, 75 cmp ax, 0x454B ; EK
jne .continue jne .continue
mov ah, [gs:(si+1)] mov ax, [gs:(si+2)]
cmp ah, 69 cmp ax, 0x4E52 ; NR
jne .continue jne .continue
mov ah, [gs:(si+2)] mov ax, [gs:(si+4)]
cmp ah, 82 cmp ax, 0x4C45 ; LE
jne .continue jne .continue
mov ah, [gs:(si+3)] mov ax, [gs:(si+6)]
cmp ah, 78 cmp ax, 0x2020 ; space space
jne .continue jne .continue
mov ah, [gs:(si+4)] mov ax, [gs:(si+8)]
cmp ah, 69 cmp ax, 0x4942; IB
jne .continue
mov ah, [gs:(si+5)]
cmp ah, 76
jne .continue
mov ah, [gs:(si+6)]
cmp ah, 32
jne .continue
mov ah, [gs:(si+7)]
cmp ah, 32
jne .continue
mov ah, [gs:(si+8)]
cmp ah, 66
jne .continue
mov ah, [gs:(si+9)]
cmp ah, 73
jne .continue jne .continue
mov ah, [gs:(si+10)] mov ah, [gs:(si+10)]
cmp ah, 78 cmp ah, 0x4E ; N
jne .continue jne .continue
; cluster high ; cluster high
@ -191,14 +171,6 @@ second_step:
mov ax, [gs:(si+26)] mov ax, [gs:(si+26)]
mov [cluster_low], ax mov [cluster_low], ax
; file_size low
mov ax, [gs:(si+28)]
mov [size_low], ax
; file_size high
mov ax, [gs:(si+30)]
mov [size_high], ax
jmp .found jmp .found
.continue: .continue:
@ -210,6 +182,11 @@ second_step:
jne .next jne .next
.end_of_cluster: .end_of_cluster:
mov si, multicluster_directory
call print_line_16
jmp error_end
.end_of_directory: .end_of_directory:
mov si, kernel_not_found mov si, kernel_not_found
call print_line_16 call print_line_16
@ -223,6 +200,10 @@ second_step:
; 4. Load the kernel into memory ; 4. Load the kernel into memory
mov ax, [cluster_high]
test ax, ax
jne cluster_too_high
mov ax, [cluster_low] mov ax, [cluster_low]
mov [current_cluster], ax mov [current_cluster], ax
mov word [current_segment], KERNEL_BASE mov word [current_segment], KERNEL_BASE
@ -248,12 +229,7 @@ second_step:
mov word [DAP.lba], ax mov word [DAP.lba], ax
mov ah, 0x42 call extended_read
mov si, DAP
mov dl, 0x80
int 0x13
jc read_failed
; Compute next cluster ; Compute next cluster
@ -270,12 +246,7 @@ second_step:
mov word [DAP.segment], 0x0 mov word [DAP.segment], 0x0
mov word [DAP.lba], ax mov word [DAP.lba], ax
mov ah, 0x42 call extended_read
mov si, DAP
mov dl, 0x80
int 0x13
jc read_failed
mov si, [current_cluster] mov si, [current_cluster]
and si, 512 - 1 ; current_cluster % 512 and si, 512 - 1 ; current_cluster % 512
@ -296,6 +267,9 @@ second_step:
jge .fully_loaded jge .fully_loaded
.ok: .ok:
test bx, bx
jne cluster_too_high
mov [current_cluster], ax mov [current_cluster], ax
movzx ax, byte [sectors_per_cluster] movzx ax, byte [sectors_per_cluster]
@ -314,6 +288,18 @@ second_step:
jmp $ jmp $
cluster_too_high:
mov si, cluster_too_high_msg
call print_line_16
jmp error_end
sectors_per_fat_too_high:
mov si, sectors_per_fat_too_high_msg
call print_line_16
jmp error_end
corrupted: corrupted:
mov si, corrupted_disk mov si, corrupted_disk
call print_line_16 call print_line_16
@ -344,8 +330,6 @@ error_end:
cluster_high dw 0 cluster_high dw 0
cluster_low dw 0 cluster_low dw 0
size_high dw 0
size_low dw 0
current_cluster dw 0 current_cluster dw 0
current_segment dw 0 current_segment dw 0
@ -354,15 +338,17 @@ error_end:
load_kernel db 'Attempt to load the kernel...', 0 load_kernel db 'Attempt to load the kernel...', 0
kernel_found db 'Kernel found. Starting kernel loading...', 0 kernel_found db 'Kernel found. Starting kernel loading...', 0
kernel_not_found db 'Kernel not found...', 0
kernel_loaded db 'Kernel fully loaded', 0 kernel_loaded db 'Kernel fully loaded', 0
corrupted_disk db 'The disk seeems to be corrupted', 0
star db '*', 0 star db '*', 0
dix db '|', 0
kernel_not_found db 'Kernel not found...', 0
corrupted_disk db 'The disk seeems to be corrupted', 0
sectors_per_fat_too_high_msg db 'Error 1. The disk is probably too big', 0
multicluster_directory db 'Error 2. Multicluster directory not supported', 0
cluster_too_high_msg db 'Error 3. Only 16bit cluster are supported', 0
read_failed_msg db 'Read disk failed', 0 read_failed_msg db 'Read disk failed', 0
load_failed db 'Kernel loading failed', 0 load_failed db 'Kernel loading failed', 0
; Make it two sectors exactly ; Make it sector-aligned
times 1024-($-$$) db 0 times 1024-($-$$) db 0