aboutsummaryrefslogtreecommitdiff
path: root/src/bootloader
diff options
context:
space:
mode:
Diffstat (limited to 'src/bootloader')
-rw-r--r--src/bootloader/cd.asm (renamed from src/bootloader/loader.asm)3
-rw-r--r--src/bootloader/grub.cfg7
-rw-r--r--src/bootloader/hdd1.asm118
-rw-r--r--src/bootloader/hdd2.asm388
-rw-r--r--src/bootloader/make_initrd.c53
5 files changed, 507 insertions, 62 deletions
diff --git a/src/bootloader/loader.asm b/src/bootloader/cd.asm
index 28e4562..1e83a3a 100644
--- a/src/bootloader/loader.asm
+++ b/src/bootloader/cd.asm
@@ -6,7 +6,6 @@ mov [bootDriveID], dl
jmp start
-; The print function
print:
mov ah, 0x0E
xor bh, bh
@@ -441,4 +440,4 @@ lba_not_supported:
boot db "BOOT"
boot_len equ ($ - boot)
kernelbin db "KERNEL.BIN", 0x3B, "1"
-kernelbin_len equ ($ - kernelbin) \ No newline at end of file
+kernelbin_len equ ($ - kernelbin)
diff --git a/src/bootloader/grub.cfg b/src/bootloader/grub.cfg
deleted file mode 100644
index cb265b1..0000000
--- a/src/bootloader/grub.cfg
+++ /dev/null
@@ -1,7 +0,0 @@
-set timeout=0
-set default=0
-menuentry "Melvix" {
- multiboot /boot/melvix.bin
- module /boot/melvix.initrd
- boot
-} \ No newline at end of file
diff --git a/src/bootloader/hdd1.asm b/src/bootloader/hdd1.asm
new file mode 100644
index 0000000..c347625
--- /dev/null
+++ b/src/bootloader/hdd1.asm
@@ -0,0 +1,118 @@
+BITS 16
+ORG 0x7C00
+
+%define INODE_ADDRESS 0xF000
+%define INODE_NBLOCKS 20
+%define INODE_DBP0 24
+
+; Save the boot drive id
+mov [bootDriveID], dl
+
+jmp start
+
+print:
+ mov ah, 0x0E
+ xor bh, bh
+ .print_L:
+ lodsb
+ test al, al
+ jz .print_end
+ int 0x10
+ jmp .print_L
+ .print_end:
+ ret
+
+bootDriveID: db 0
+
+dapack:
+ dapack_size: db 0x10
+ dapack_null: db 0x00
+ dapack_blkcount: dw 0x0001
+ dapack_boffset: dw 0x8000
+ dapack_bsegment: dw 0x0000
+ dapack_start: dd 0x00000000
+ dapack_upper_lba_bits: dd 0x00000000
+
+readsector:
+ mov dword [dapack_start], eax
+ mov ah, 0x42
+ mov dl, [bootDriveID]
+ xor bx, bx
+ mov ds, bx
+ mov si, dapack
+ int 0x13
+ ret
+
+; 5K max
+readwholefile:
+ mov bx, word [dapack_boffset]
+ push bx
+ mov bx, INODE_ADDRESS
+ mov word [dapack_boffset], bx
+ call readsector
+ pop bx
+ mov word [dapack_boffset], bx
+
+ mov edx, [INODE_ADDRESS+INODE_NBLOCKS]
+
+ xor ecx, ecx
+ .readwholefile_L:
+ lea bx, [INODE_ADDRESS + INODE_DBP0 + (ecx*4)]
+ mov eax, dword [bx]
+
+ push dx
+ call readsector
+ pop dx
+
+ add dword [dapack_boffset], 512
+
+ inc cx
+ cmp cx, dx
+ jl .readwholefile_L
+ ret
+
+welcome db "Melvix", 0x0A, 0x0D, 0x00
+nolba db "BIOS lacks support for LBA addressing.", 0x00
+signaturebad db "Bad disk signature.", 0x00
+
+start:
+ mov ax, 0x0003
+ int 0x10
+
+ mov si, welcome
+ call print
+
+ mov ah, 0x41
+ mov bx, 0x55AA
+ int 0x13
+ jc lba_not_supported
+ cmp bx, 0xAA55
+ jnz lba_not_supported
+
+ mov eax, 1
+ call readsector
+
+ mov eax, [0x8000+0]
+ cmp eax, 0x34B59645
+ jnz signature_BAD
+ mov eax, [0x8000+4]
+ cmp eax, 0x1083B99F
+ jnz signature_BAD
+
+ mov eax, 2
+ call readwholefile
+
+ jmp 0x8000
+
+lba_not_supported:
+ mov si, nolba
+ call print
+ jmp $
+
+signature_BAD:
+ mov si, signaturebad
+ call print
+ jmp $
+
+times 510-($-$$) db 0
+dw 0xAA55 \ No newline at end of file
diff --git a/src/bootloader/hdd2.asm b/src/bootloader/hdd2.asm
new file mode 100644
index 0000000..e289c39
--- /dev/null
+++ b/src/bootloader/hdd2.asm
@@ -0,0 +1,388 @@
+BITS 16
+ORG 0x8000
+
+%define SECTOR_BUFFER 0x9000
+%define INODE_NBLOCKS 20
+%define INODE_DBP0 24
+%define INODE_SIBP 64
+%define INODE_DIBP 68
+%define INODE_TIBP 72
+%define INODE_QIBP 76
+
+mov esp, 0xFFFF
+jmp start
+
+checkA20:
+ ; Stolen from https://wiki.osdev.org/A20_Line
+ pushf
+ push ds
+ push es
+ push di
+ push si
+ cli
+ xor ax, ax
+ mov es, ax
+ not ax
+ mov ds, ax
+ mov di, 0x0500
+ mov si, 0x0510
+ mov al, byte [es:di]
+ push ax
+ mov al, byte [ds:si]
+ push ax
+ mov byte [es:di], 0x00
+ mov byte [ds:si], 0xFF
+ cmp byte [es:di], 0xFF
+ pop ax
+ mov byte [ds:si], al
+ pop ax
+ mov byte [es:di], al
+ mov ax, 0
+ jz checkA20_exit
+ mov ax, 1
+ checkA20_exit:
+ pop si
+ pop di
+ pop es
+ pop ds
+ popf
+ ret
+
+last_maxlevel db 0
+getrecursive:
+ push edi
+ push esi
+ push ecx
+
+ mov eax, edi
+ cmp al, byte [last_maxlevel]
+ jna .last_maxlevel_updated
+ mov byte [last_maxlevel], al
+ .last_maxlevel_updated:
+
+ mov eax, esi
+ call 0x7c26
+
+ mov eax, dword [esp]
+ sub eax, 10
+
+ cmp byte [last_maxlevel], 1
+ jna .check1
+ mov ebx, 1
+ shl ebx, 7
+ sub eax, ebx
+ .check1:
+ cmp byte [last_maxlevel], 2
+ jna .check2
+ mov ebx, 1
+ shl ebx, 14
+ sub eax, ebx
+ .check2:
+ cmp byte [last_maxlevel], 3
+ jna .check3
+ mov ebx, 1
+ shl ebx, 21
+ sub eax, ebx
+ .check3:
+ mov ecx, dword [esp+8]
+ dec ecx
+ push ecx
+ shl ecx, 3
+ sub ecx, dword [esp]
+ add esp, 4
+ shr eax, cl
+
+ mov eax, dword [SECTOR_BUFFER+(4*eax)]
+
+ cmp dword [esp+8], 1
+ jna .finish_recursion
+ mov edi, [esp+8]
+ dec edi
+ mov esi, eax
+ mov ecx, [esp]
+ call getrecursive
+ .finish_recursion:
+ mov byte [last_maxlevel], 0
+
+ pop ecx
+ pop esi
+ pop edi
+ ret
+
+get_block:
+ push ecx
+ push ebx
+
+ xor ebx, ebx
+ inc ebx
+ shl ebx, 21
+ add ebx, 9
+ cmp ecx, ebx
+ jna .gtb1
+
+ mov edi, 4
+ mov esi, dword [SECTOR_BUFFER+INODE_QIBP]
+ call getrecursive
+ jmp .get_block_end
+
+ .gtb1:
+ xor ebx, ebx
+ inc ebx
+ shl ebx, 14
+ add ebx, 9
+ cmp ecx, ebx
+ jna .gtb2
+
+ mov edi, 3
+ mov esi, dword [SECTOR_BUFFER+INODE_TIBP]
+ call getrecursive
+ jmp .get_block_end
+
+ .gtb2:
+ xor ebx, ebx
+ inc ebx
+ shl ebx, 7
+ add ebx, 9
+ cmp ecx, ebx
+ jna .gtb3
+
+ mov edi, 2
+ mov esi, dword [SECTOR_BUFFER+INODE_DIBP]
+ call getrecursive
+ jmp .get_block_end
+
+ .gtb3:
+ cmp ecx, 9
+ jna .gtb4
+
+ mov edi, 1
+ mov esi, dword [SECTOR_BUFFER+INODE_SIBP]
+ call getrecursive
+ jmp .get_block_end
+
+ .gtb4:
+ mov eax, SECTOR_BUFFER+INODE_DBP0
+ mov eax, dword [eax+(4*ecx)]
+
+ .get_block_end:
+ pop ebx
+ pop ecx
+ ret
+
+noa20 db "A20 could not be enabled.", 0
+loading db "Loading kernel...", 0x0A, 0x0D, 0x00
+booting db "Booting...", 0x0A, 0x0D, 0x00
+nomem db "BIOS does not support memory detection!", 0
+memno20 db "BIOS returns memory detection with 24 bytes. This has never been seen!", 0
+
+start:
+ call checkA20
+ test ax, ax
+ jnz A20_ENABLED
+
+ in al, 0x92
+ or al, 2
+ out 0x92, al
+
+ call checkA20
+ test ax, ax
+ jnz A20_ENABLED
+
+ mov si, noa20
+ call 0x7c07
+ jmp $
+
+A20_ENABLED:
+ ; Inspired by https://wiki.osdev.org/Unreal_Mode
+ cli
+ push ds
+ lgdt [gdtinfo]
+
+ mov eax, cr0
+ or al, 1
+ mov cr0, eax
+
+ jmp $+2
+
+ mov bx, 0x08
+ mov ds, bx
+
+ and al, 0xFE
+ mov cr0, eax
+ pop ds
+
+ mov si, loading
+ call 0x7c07
+
+ mov word [0x7c1a], SECTOR_BUFFER
+
+ mov eax, 3
+ call 0x7c26
+ mov edx, dword [SECTOR_BUFFER + INODE_NBLOCKS]
+
+ xor ecx, ecx
+LOAD_KERNEL:
+ push edx
+
+ mov eax, 3
+ call 0x7c26
+ call get_block
+ call 0x7c26
+
+ mov eax, ecx
+ shl eax, 9
+ add eax, 0x200000
+
+ push ecx
+ xor ecx, ecx
+ .LOAD_KERNEL_L:
+ mov ebx, ecx
+ add ebx, SECTOR_BUFFER
+ mov ebx, dword [ebx]
+
+ mov edx, ebx
+ mov ebx, eax
+ add ebx, ecx
+ mov dword [ebx], edx
+
+ add ecx, 4
+ cmp ecx, 2048
+ jl .LOAD_KERNEL_L
+ pop ecx
+
+ inc ecx
+ pop edx
+ cmp ecx, edx
+ jl LOAD_KERNEL
+
+mov si, booting
+call 0x7c07
+
+mov dl, [0x7c15]
+mov byte [0x9000], dl
+
+mov di, 0xA000
+mov eax, 0xE820
+xor ebx, ebx
+mov ecx, 24
+mov edx, 0x534D4150
+int 0x15
+
+jc BIOS_NO_MEM
+cmp eax, 0x534D4150
+jnz BIOS_NO_MEM
+cmp cl, 20
+jnz BIOS_MEM_NO20
+
+MEM_L:
+ test ebx, ebx
+ jz MEM_FINISHED
+
+ mov ax, di
+ xor ch, ch
+ add ax, cx
+ mov di, ax
+
+ mov eax, 0xE820
+ mov ecx, 24
+ int 0x15
+ jmp MEM_L
+
+MEM_FINISHED:
+ mov eax, cr0
+ or al, 1
+ mov cr0, eax
+
+ mov ax, 0x08
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+; Infomation: https://wiki.osdev.org/ELF
+mov ebx, 0x20002C
+mov dl, byte [ebx]
+push dx
+
+mov ebx, 0x20001C
+mov ebx, dword [ebx]
+push ebx
+
+xor dh, dh
+PHT:
+ xor eax, eax
+ mov al, dh
+ shl eax, 5
+ add eax, dword [esp]
+ add eax, 0x200000
+ mov ebx, eax
+
+ mov eax, dword [ebx]
+ cmp eax, 1
+ jnz .PHT_ignore
+
+ add ebx, 4
+ mov eax, dword [ebx]
+ add eax, 0x200000
+ push eax
+
+ add ebx, 4
+ mov eax, dword [ebx]
+ push eax
+
+ add ebx, 8
+ mov eax, dword [ebx]
+ push eax
+
+ push dx
+ xor ecx, ecx
+ .MOVE_KERNEL_L:
+ mov ebx, [esp+10]
+ add ebx, ecx
+ mov ebx, dword [ebx]
+
+ mov eax, ebx
+ mov ebx, dword [esp+6]
+ add ebx, ecx
+ mov dword [ebx], eax
+
+ add ecx, 4
+ cmp ecx, dword [esp+2]
+ jl .MOVE_KERNEL_L
+ pop dx
+ add esp, 12
+
+ .PHT_ignore:
+ inc dh
+ cmp dh, dl
+ jl PHT
+
+jmp (codedesc - gdt):protectedMode
+
+protectedMode:
+ BITS 32
+ mov ebx, 0x100000
+ mov eax, dword [ebx]
+ jmp eax
+
+BITS 16
+BIOS_NO_MEM:
+ mov si, nomem
+ call 0x7c07
+ jmp $
+BIOS_MEM_NO20:
+ mov si, memno20
+ call 0x7c07
+ jmp $
+
+gdtinfo:
+ dw gdt_end - gdt - 1
+ dd gdt
+ gdt dd 0, 0
+ flatdesc db 0xff, 0xff, 0, 0, 0, 10010010b, 11001111b, 0
+ codedesc db 0xff, 0xff, 0, 0, 0, 10011010b, 11001111b, 0
+ gdt_end:
+
+kernelbin db "KERNEL.BIN", 0x3B, "1"
+kernelbin_len equ ($ - kernelbin)
diff --git a/src/bootloader/make_initrd.c b/src/bootloader/make_initrd.c
deleted file mode 100644
index 6c2e7a0..0000000
--- a/src/bootloader/make_initrd.c
+++ /dev/null
@@ -1,53 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-struct initrd_header {
- unsigned char magic;
- char name[64];
- unsigned int offset;
- unsigned int length;
-};
-
-int main(char argc, char **argv) {
- int nheaders = (argc - 1) / 2;
- struct initrd_header headers[64];
- printf("size of header: %d\n", (int) sizeof(struct initrd_header));
- unsigned int off = sizeof(struct initrd_header) * 64 + sizeof(int);
-
- for (int i = 0; i < nheaders; i++) {
- printf("writing file %s->%s at 0x%x\n", argv[i * 2 + 1], argv[i * 2 + 2], off);
- strcpy(headers[i].name, argv[i * 2 + 2]);
- headers[i].name[strlen(argv[i * 2 + 2])] = '\0';
- headers[i].offset = off;
- FILE *stream = fopen(argv[i * 2 + 1], "r");
- if (stream == 0) {
- printf("Error: file not found: %s\n", argv[i * 2 + 1]);
- return 1;
- }
- fseek(stream, 0, SEEK_END);
- headers[i].length = ftell(stream);
- off += headers[i].length;
- fclose(stream);
- headers[i].magic = 0xBF;
- }
-
- FILE *wstream = fopen("./initrd.img", "w");
- unsigned char *data = (unsigned char *) malloc(off);
- fwrite(&nheaders, sizeof(int), 1, wstream);
- fwrite(headers, sizeof(struct initrd_header), 64, wstream);
-
- for (int i = 0; i < nheaders; i++) {
- FILE *stream = fopen(argv[i * 2 + 1], "r");
- unsigned char *buf = (unsigned char *) malloc(headers[i].length);
- fread(buf, 1, headers[i].length, stream);
- fwrite(buf, 1, headers[i].length, wstream);
- fclose(stream);
- free(buf);
- }
-
- fclose(wstream);
- free(data);
-
- return 0;
-}