From 453c3d130b34e317fa8368eeff104ccf219a3088 Mon Sep 17 00:00:00 2001
From: VinceAle7082 <vincenzo.brocato11@gmail.com>
Date: Wed, 24 Jul 2024 11:23:05 +0200
Subject: [PATCH] Many things pt.2 Now the bootloader (/src/boot.asm) has a
 FAT12 driver that searches the KERNEL.BIN file and loads it. Now the kernel
 has something in it, it just prints a Hello World message.

---
 Makefile                |   4 +-
 src/bootloader/boot.asm | 278 ++++++++++++++++++++++++++++++----------
 src/kernel/kernel.asm   |  56 ++++++++
 3 files changed, 266 insertions(+), 72 deletions(-)

diff --git a/Makefile b/Makefile
index 49d75cd..b76f2f2 100644
--- a/Makefile
+++ b/Makefile
@@ -42,4 +42,6 @@ always:
 #Clean
 
 clean:
-	rm -rf $(BUILD_DIR)/* 
\ No newline at end of file
+	rm -rf $(BUILD_DIR)/* 
+
+#Strumenti
\ No newline at end of file
diff --git a/src/bootloader/boot.asm b/src/bootloader/boot.asm
index e229366..1ad257c 100644
--- a/src/bootloader/boot.asm
+++ b/src/bootloader/boot.asm
@@ -8,19 +8,19 @@ bits 16
 jmp short start
 nop
 
-bdb_oem:					db 'MSWIN4.1'
-bdb_bytes_per_sector:		dw 512
-bdb_sectors_per_cluster:	db 1
-bdb_reserved_sectors:		dw 1
-bdb_fat_count:				db 2
-bdb_dir_entries_count:		dw 0E0h
-bdb_total_sectors:			dw 2880
-bdb_media_descriptor_type:	db 0F0h
-bdb_sectors_per_fat:		dw 9
-bdb_sectors_per_track:		dw 18
-bdb_heads:					dw 2
-bdb_hidden_sectors:			dd 0
-bdb_large_sector_count:		dd 0
+oem:					db 'MSWIN4.1'
+bytes_per_sector:		dw 512
+sectors_per_cluster:	db 1
+reserved_sectors:		dw 1
+fat_count:				db 2
+dir_entries_count:		dw 0E0h
+total_sectors:			dw 2880
+media_descriptor_type:	db 0F0h
+sectors_per_fat:		dw 9
+sectors_per_track:		dw 18
+heads:					dw 2
+hidden_sectors:			dd 0
+large_sector_count:		dd 0
 
 ebr_drive_number:			db 0
 							db 0
@@ -29,71 +29,158 @@ ebr_volume_id:				db 12h, 34h, 56h, 78h
 ebr_volume_label:			db 'XanvicOS   '
 ebr_system_id:				db 'FAT12   '
 
-;Codice
+;Codice del bootloader
 
 start:
-	jmp main
+	;Inizializza segmenti di dati
 
-puts:
-	push si
-	push ax
-	push bx
-	
-.loop:
-	lodsb 
-	or al, al
-	jz .fine
-
-	mov ah, 0x0E
-	mov bh, 0
-	int 0x10
-	
-	jmp .loop
-	
-.fine:
-	pop bx
-	pop ax
-	pop si
-	ret
-
-main:
 	mov ax, 0
 	mov ds, ax
 	mov es, ax
 
+	;Iniializza gli stack
+
 	mov ss, ax
 	mov sp, 0x7C00
 
-	mov si, msg_helloworld
+.dopo:
+
+	;Mostra il messaggio di caricamento
+
+	mov si, msg_caricamento
 	call puts
 
 	;Legge cose dal floppy
+
 	mov [ebr_drive_number], dl
 
-	mov ax, 1
-	mov cl, 1
-	mov bx, 0x7E00
+	;Legge i parametri del disco
+
+	push es
+	mov ah, 08h
+	int 13h
+	jc errore_floppy
+	pop es
+
+	and cl, 0x3F
+	xor ch, ch
+	mov [sectors_per_track], cx
+
+	inc dh
+	mov [heads], dh
+
+	;Calcola l'indirizzo LBA della root del filesystem FAT12
+
+	mov ax, [sectors_per_fat]
+	mov bl, [fat_count]
+	xor bh, bh
+	mul bx
+	add ax, [reserved_sectors]
+	push ax
+
+	;Calcola il peso della root
+
+	mov ax, [sectors_per_fat]
+	shl ax, 5
+	xor dx, dx
+	div word [bytes_per_sector]
+
+	test dx, dx
+	jz .root_dopo
+	inc ax 
+
+.root_dopo:
+	;Legge la root
+	mov cl, al
+	pop ax
+	mov dl, [ebr_drive_number]
+	mov bx, buffer
 	call lettura_disco
 
-	cli
-	hlt
+	;Cerca il kernel
+	xor bx, bx
+	mov di, buffer
 
-;Errori
+.cerca_kernel:
+	mov si, file_kernel_bin
+	mov cx, 11
+	push di
+	repe cmpsb
+	pop di
+	je .kernel_trovato
 
-errore_floppy:
-	mov si, msg_errore_lettura
+	add di, 32
+	inc bx
+	cmp bx, [dir_entries_count]
+	jl .cerca_kernel
+
+	;Kernel non trovato
+	jmp errore_kernel_non_trovato
+
+.kernel_trovato:
+	mov si, msg_kernel_trovato
 	call puts
+
+	mov ax, [di + 26]
+	mov [kernel_cluster], ax
+
+	mov ax, [reserved_sectors]
+	mov bx, buffer 
+	mov cl, [sectors_per_fat]
+	mov dl, [ebr_drive_number]
+	call lettura_disco
+
+	mov bx, KERNEL_LOAD_SEGMENT
+	mov es, bx
+	mov bx, KERNEL_LOAD_OFFSET
+
+.carica_kernel:
+	mov ax, [kernel_cluster]
+	add ax, 31
+
+	mov cl, 1
+	mov dl, [ebr_drive_number]
+	call lettura_disco
+
+	add bx, [bytes_per_sector]
+
+	mov ax, [kernel_cluster]
+	mov cx, 3
+	mul cx
+	mov cx, 2
+	div cx
+
+	mov si, buffer
+	add si, ax
+	mov ax, [ds:si]
+
+	or dx, dx
+	jz .pari
+
+.dispari:
+	shr ax, 4
+	jmp .prossimo_cluster
+
+.pari:
+	and ax, 0x0FFF
+
+.prossimo_cluster:
+	cmp ax, 0x0FF8
+	jae .fine_lettura
+
+	mov [kernel_cluster], ax
+	jmp .carica_kernel
+
+.fine_lettura:
+	mov dl, [ebr_drive_number]
+	
+	mov ax, KERNEL_LOAD_SEGMENT
+	mov ds, ax
+	mov es, ax
+
+	jmp KERNEL_LOAD_SEGMENT:KERNEL_LOAD_OFFSET
 	jmp premi_per_riavviare
 
-premi_per_riavviare:
-	mov ah, 0
-	int 16h
-	jmp 0FFFFh:0 
-
-.halt:
-	cli
-	hlt
-
 ;Trasforma/Converte un indirizzo LBA in uno CHS
 
 lba_to_chs:
@@ -101,13 +188,13 @@ lba_to_chs:
 	push dx
 	
 	xor dx, dx
-	div word [bdb_sectors_per_track]
+	div word [sectors_per_track]
 	
 	inc dx
 	mov cx, dx
 
 	xor dx, dx
-	div word [bdb_heads]
+	div word [heads]
 
 	mov dh, dl
 	mov ch, al
@@ -123,11 +210,7 @@ lba_to_chs:
 ;Legge i settori da un disco
 
 lettura_disco:
-;	push ax
-;	push bx
 	push cx
-;	push dx
-;	push di
 
 	call lba_to_chs
 	pop ax
@@ -155,11 +238,6 @@ lettura_disco:
 .fine:
 	popa
 
-;	pop di
-;	pop dx
-;	pop cx
-;	pop bx
-;	pop ax
 	ret
 
 disk_reset:
@@ -171,12 +249,70 @@ disk_reset:
 	popa
 	ret
 
-;Mostra una stringa sullo schermo
+puts:
+    ;Salva i registri
+    push si
+    push ax
+    push bx
+
+.loop:
+    lodsb            
+    or al, al           ; verify if next character is n
+    jz .fine
+
+    mov ah, 0x0E        ; call bios interrupt
+    mov bh, 0           ; set page number to 0
+    int 0x10
+
+    jmp .loop
+
+.fine:
+    pop bx
+    pop ax
+    pop si    
+    ret
+
+;Mostra delle stringhe sullo schermo
+
+msg_caricamento:
+	db 'Caricamento...', ENDL, 0
 
-msg_helloworld: 
-	db 'Hello World!', ENDL, 0
 msg_errore_lettura:
-	db 'Errore nella lettura del disco!'
+	db 'Errore del disco', ENDL, 0
+
+msg_kernel_non_trovato:
+	db 'Kernel non trovato', ENDL, 0
+
+msg_kernel_trovato:
+	db 'Kernel trovato', ENDL, 0
+
+;Errori
+
+errore_floppy:
+	mov si, msg_errore_lettura
+	call puts
+	jmp premi_per_riavviare
+
+errore_kernel_non_trovato:
+	mov si, msg_kernel_non_trovato
+	call puts
+	jmp premi_per_riavviare
+
+;Variabili
+
+file_kernel_bin:				db 'KERNEL  BIN'
+kernel_cluster:					dw 0
+KERNEL_LOAD_SEGMENT 			equ 0x2000
+KERNEL_LOAD_OFFSET				equ 0
+
+;Cose che non so dove mettere
+
+premi_per_riavviare:
+	mov ah, 0
+	int 16h
+	jmp 0FFFFh:0 
 
 times 510-($-$$) db 0
 dw 0AA55h
+
+buffer:
diff --git a/src/kernel/kernel.asm b/src/kernel/kernel.asm
index e69de29..0e5d752 100644
--- a/src/kernel/kernel.asm
+++ b/src/kernel/kernel.asm
@@ -0,0 +1,56 @@
+org 0x0
+bits 16
+
+
+%define ENDL 0x0D, 0x0A
+
+;Codice del kernel
+start:
+    mov si, msg_helloworld
+    call puts
+	call premi_per_riavviare
+
+.halt:
+    cli
+    hlt
+
+puts:
+    ; save registers we will modify
+    push si
+    push ax
+    push bx
+
+.loop:
+    lodsb
+    or al, al
+    jz .fine
+
+    mov ah, 0x0E
+    mov bh, 0
+    int 0x10
+
+    jmp .loop
+
+.fine:
+    pop bx
+    pop ax
+    pop si    
+    ret
+
+;Stringhe
+msg_helloworld: 
+	db 'Hello World dal kernel!', ENDL, 0
+
+msg_premi_per_riavviare:
+	db 'Premi un tasto per riavviare...', ENDL, 0
+;Errori
+
+;Variabili
+
+;Cose che non so dove mettere
+premi_per_riavviare:
+	mov si, msg_premi_per_riavviare
+	call puts
+	mov ah, 0
+	int 16h
+	jmp 0FFFFh:0 
\ No newline at end of file