thor-os/bootloader/stage2.asm

184 lines
3.6 KiB
NASM

;=======================================================================
; Copyright Baptiste Wicht 2013.
; Distributed under the Boost Software License, Version 1.0.
; (See accompanying file LICENSE_1_0.txt or copy at
; http://www.boost.org/LICENSE_1_0.txt)
;=======================================================================
[BITS 16]
jmp second_step
%include "intel_16.asm"
%include "sectors.asm"
KERNEL_BASE equ 0x100 ; 0x100:0x0 = 0x1000
DAP:
.size db 0x10
.null db 0x0
.count dw 0
.offset dw 0
.segment dw 0x0
.lba dd 0
.lba48 dd 0
; Loaded at 0x90:0x0
second_step:
; Set data segment
mov ax, 0x90
mov ds, ax
; Used for disk access
xor ax, ax
mov gs, ax
mov si, load_kernel
call print_line_16
; 1. Read the MBR to get partition table
mov byte [DAP.count], 1
mov word [DAP.offset], 0x1000
mov word [DAP.segment], 0
mov dword [DAP.lba], 0
mov ah, 0x42
mov si, DAP
mov dl, 0x80
int 0x13
jc read_failed
mov di, [gs:(0x1000 + 446 + 8)]
mov [partition_start], di
call print_int_16
call new_line_16
; 2. Read the VBR of the partition to get FAT informations
mov byte [DAP.count], 1
mov word [DAP.offset], 0x1000
mov word [DAP.segment], 0
mov di, [partition_start]
mov word [DAP.lba], di
mov ah, 0x42
mov si, DAP
mov dl, 0x80
int 0x13
jc read_failed
mov ah, [gs:(0x1000 + 13)]
mov [sectors_per_cluster], ah
movzx di, ah
call print_int_16
call new_line_16
mov di, [gs:(0x1000 + 14)]
mov [reserved_sectors], di
call print_int_16
call new_line_16
mov ah, [gs:(0x1000 + 16)]
mov [number_of_fat], ah
movzx di, ah
call print_int_16
call new_line_16
mov di, [gs:(0x1000 + 36)]
mov [sectors_per_fat], di
call print_int_16
call new_line_16
mov di, [gs:(0x1000 + 44)]
mov [root_dir_start], di
call print_int_16
call new_line_16
; fat_begin = partition_start + reserved_sectors
mov di, [partition_start]
mov si, [reserved_sectors]
add di, si
mov [fat_begin], di
call print_int_16
call new_line_16
; cluster_begin = (number_of_fat * sectors_per_fat) + fat_begin
mov ax, [sectors_per_fat]
movzx bx, [number_of_fat]
mul bx
mov bx, [fat_begin]
add ax, bx
mov [cluster_begin], ax
mov di, ax
call print_int_16
call new_line_16
; 3. Read the root directory to find the kernel executable
mov ah, [sectors_per_cluster]
mov byte [DAP.count], ah
mov word [DAP.offset], 0x1000
mov word [DAP.segment], 0
; Compute LBA from root_dir_start
mov ax, [root_dir_start]
sub ax, 2
movzx bx, byte [sectors_per_cluster]
mul bx
mov bx, [cluster_begin]
add ax, bx
mov word [DAP.lba], ax
mov di, ax
call print_int_16
call new_line_16
mov ah, 0x42
mov si, DAP
mov dl, 0x80
int 0x13
jc read_failed
; TODO Find kernel.bin in the directory
jmp $
read_failed:
mov si, read_failed_msg
call print_line_16
error_end:
mov si, load_failed
call print_line_16
jmp $
; Variables
partition_start dw 0
reserved_sectors dw 0
number_of_fat db 0
sectors_per_fat dw 0
sectors_per_cluster db 0
root_dir_start dw 0
fat_begin dw 0
cluster_begin dw 0
; Constant Datas
load_kernel db 'Attempt to load the kernel...', 0
kernel_loaded db 'Kernel fully loaded', 0
star db '*', 0
read_failed_msg db 'Read disk failed', 0
load_failed db 'Kernel loading failed', 0
; Make it two sectors exactly
times 1024-($-$$) db 0