mirror of
https://github.com/wichtounet/thor-os.git
synced 2025-08-04 01:36:10 -04:00
184 lines
3.6 KiB
NASM
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 |