aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHimbeerserverDE <himbeerserverde@gmail.com>2023-05-06 13:07:50 +0200
committerHimbeerserverDE <himbeerserverde@gmail.com>2023-05-06 13:07:50 +0200
commita6e9ac82d8c8b683d1bd5f1d77b0633c85799496 (patch)
tree1d97ef2a1022a15947d11e68232abf703d6449ac
parentd4808be8c32d4b7821ca8358d95f6c1691cc7283 (diff)
generate asm mbr for x86 at compile time
-rw-r--r--.gitignore1
-rw-r--r--Makefile.toml10
-rw-r--r--boot.asm240
3 files changed, 251 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index ea8c4bf..ea1ad27 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
/target
+boot.bin
diff --git a/Makefile.toml b/Makefile.toml
new file mode 100644
index 0000000..64819c2
--- /dev/null
+++ b/Makefile.toml
@@ -0,0 +1,10 @@
+[tasks.boot]
+command = "nasm"
+args = ["-f", "bin", "-o", "boot.bin", "boot.asm"]
+
+[tasks.build]
+dependencies = ["boot"]
+
+[tasks.clean]
+command = "rm"
+args = ["-f", "boot.bin"]
diff --git a/boot.asm b/boot.asm
new file mode 100644
index 0000000..d3653f0
--- /dev/null
+++ b/boot.asm
@@ -0,0 +1,240 @@
+; Minimal Linux Bootloader
+; ========================
+
+; @ author: Sebastian Plotz
+; @ version: 1.0
+; @ date: 24.07.2012
+
+; Copyright (C) 2012 Sebastian Plotz
+
+; Minimal Linux Bootloader is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+
+; Minimal Linux Bootloader is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+
+; You should have received a copy of the GNU General Public License
+; along with Minimal Linux Bootloader. If not, see <http://www.gnu.org/licenses/>.
+
+; Memory layout
+; =============
+
+; 0x07c00 - 0x07dff Mininal Linux Bootloader
+; + partition table
+; + MBR signature
+; 0x10000 - 0x17fff Real mode kernel
+; 0x18000 - 0x1dfff Stack and heap
+; 0x1e000 - 0x1ffff Kernel command line
+; 0x20000 - 0x2fdff temporal space for
+; protected-mode kernel
+
+; base_ptr = 0x10000
+; heap_end = 0xe000
+; heap_end_ptr = heap_end - 0x200 = 0xde00
+; cmd_line_ptr = base_ptr + heap_end = 0x1e000
+
+org 0x7c00
+
+ cli
+ xor ax, ax
+ mov ds, ax
+ mov ss, ax
+ mov sp, 0x7c00 ; setup stack ...
+ mov ax, 0x1000
+ mov es, ax
+ sti
+
+read_cmdline:
+
+ mov eax, 0x0001 ; load one sector
+ xor bx, bx ; no offset
+ mov cx, 0x1e00 ; load Kernel command line at 0x1e000
+ mov esi, cmd_lba
+ call read_from_hdd
+
+read_kernel_bootsector:
+
+ mov eax, 0x0001 ; load one sector
+ xor bx, bx ; no offset
+ mov cx, 0x1000 ; load Kernel boot sector at 0x10000
+ mov esi, current_lba
+ call read_from_hdd
+
+read_kernel_setup:
+
+ xor eax, eax
+ mov al, [es:0x1f1] ; no. of sectors to load
+ cmp ax, 0 ; 4 if setup_sects = 0
+ jne read_kernel_setup.next
+ mov ax, 4
+.next:
+ mov bx, 512 ; 512 byte offset
+ mov cx, 0x1000
+ mov esi, current_lba
+ call read_from_hdd
+
+check_version:
+
+ cmp word [es:0x206], 0x204 ; we need protocol version >= 2.04
+ jb error
+ test byte [es:0x211], 1
+ jz error
+
+set_header_fields:
+
+ mov byte [es:0x210], 0xe1 ; set type_of_loader
+ or byte [es:0x211], 0x80 ; set CAN_USE_HEAP
+ mov word [es:0x224], 0xde00 ; set heap_end_ptr
+ ;mov byte [es:0x226], 0x00 ; set ext_loader_ver
+ mov byte [es:0x227], 0x01 ; set ext_loader_type (bootloader id: 0x11)
+ mov dword [es:0x228], 0x1e000 ; set cmd_line_ptr
+ cld ; copy cmd_line
+
+read_protected_mode_kernel:
+
+ mov edx, [es:0x1f4] ; edx stores the number of bytes to load
+ shl edx, 4
+.loop:
+ cmp edx, 0
+ je run_kernel
+ cmp edx, 0xfe00 ; less than 127*512 bytes remaining?
+ jb read_protected_mode_kernel_2
+ mov eax, 0x7f ; load 127 sectors (maximum)
+ xor bx, bx ; no offset
+ mov cx, 0x2000 ; load temporary to 0x20000
+ mov esi, current_lba
+ call read_from_hdd
+ mov cx, 0x7f00 ; move 65024 bytes (127*512 byte)
+ call do_move
+ sub edx, 0xfe00 ; update the number of bytes to load
+ add word [gdt.dest], 0xfe00
+ adc byte [gdt.dest+2], 0
+ jmp short read_protected_mode_kernel.loop
+
+read_protected_mode_kernel_2:
+
+ mov eax, edx
+ shr eax, 9
+ test edx, 511
+ jz read_protected_mode_kernel_2.next
+ inc eax
+.next:
+ xor bx, bx
+ mov cx, 0x2000
+ mov esi, current_lba
+ call read_from_hdd
+ mov ecx, edx
+ shr ecx, 1
+ call do_move
+
+run_kernel:
+
+ cli
+ mov ax, 0x1000
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+ mov sp, 0xe000
+ jmp 0x1020:0
+
+ ;; read_from_hdd:
+ ;; ax: count in 512-byte sectors [1, 127]
+ ;; bx: destination: offset
+ ;; cx: destination: segment
+ ;; esi: lba pointer (typically current_lba)
+read_from_hdd:
+
+ push edx
+ mov [dap.count], ax
+ mov [dap.offset], bx
+ mov [dap.segment], cx
+ mov edx, [esi]
+ mov [dap.lba], edx
+ add [esi], eax ; update current_lba
+ mov ah, 0x42
+ mov si, dap
+ mov dl, 0x80 ; first hard disk
+ int 0x13
+ jc error
+ pop edx
+ ret
+
+do_move:
+
+ push edx
+ push es
+ xor ax, ax
+ mov es, ax
+ mov ah, 0x87
+ mov si, gdt
+ int 0x15
+ jc error
+ pop es
+ pop edx
+ ret
+
+error:
+
+ mov si, error_msg
+
+msg_loop:
+
+ lodsb
+ and al, al
+ jz reboot
+ mov ah, 0xe
+ mov bx, 7
+ int 0x10
+ jmp short msg_loop
+
+reboot:
+
+ xor ax, ax
+ int 0x16
+ int 0x19
+ jmp 0xf000:0xfff0 ; BIOS reset code
+
+; Global Descriptor Table
+
+gdt:
+
+ times 16 db 0
+ dw 0xffff ; segment limit
+.src:
+ dw 0
+ db 2
+ db 0x93 ; data access rights
+ dw 0
+ dw 0xffff ; segment limit
+.dest:
+ dw 0
+ db 0x10 ; load protected-mode kernel to 100000h
+ db 0x93 ; data access rights
+ dw 0
+ times 16 db 0
+
+; Disk Address Packet
+
+dap:
+
+ db 0x10 ; size of DAP
+ db 0 ; unused
+.count:
+ dw 0 ; number of sectors
+.offset:
+ dw 0 ; destination: offset
+.segment:
+ dw 0 ; destination: segment
+.lba:
+ dd 0 ; low bytes of LBA address
+ dd 0 ; high bytes of LBA address
+
+error_msg db 'er', 0 ; /* FIXME: newline */
+current_lba dd 8218 ; initialize to first LBA address
+cmd_lba dd 8218 ; initialize to LBA address of cmdline.txt