From 172549080e5f094aeff4bad4d9508e7539bea878 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 20 Dec 2024 23:29:22 -0500 Subject: [PATCH 01/11] Fixed boot sector bug preventing booting on some hardware!!! Still needs to be cleaned up though. --- src/boot/boot_sect.asm | 181 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 174 insertions(+), 7 deletions(-) diff --git a/src/boot/boot_sect.asm b/src/boot/boot_sect.asm index cc04946..ddfdf92 100644 --- a/src/boot/boot_sect.asm +++ b/src/boot/boot_sect.asm @@ -3,9 +3,28 @@ OS_OFFSET equ 0x1000 [bits 16] begin: + jmp code + RETRY_COUNT dw 0 + DRIVE_N_HEADS db 0 + DRIVE_SECTS_PER_TRACK db 0 +code: mov [BOOT_DRIVE], dl + mov ax, 0 + mov ds, ax + mov ss, ax + mov es, ax + mov fs, ax + mov gs, ax mov bp, 0x9000 mov sp, bp + +;;; Get Drive Parameters + mov ah, 8 + int 0x13 + add dh, 1 + mov [DRIVE_N_HEADS], dh + and cl, 0x3f + mov [DRIVE_SECTS_PER_TRACK], cl jmp load_kernel %include "src/boot/gdt.asm" @@ -13,15 +32,163 @@ begin: [bits 16] load_kernel: - mov ah, 2 ;read BIOS chs - mov al, 42 ;sectors to read - mov cl, 0x02 ;start at sector 2 - mov ch, 0x00 ;cylinder - mov dh, 0x00 ;head + +;;; Read Drive + mov bl, 1 +read: + mov al, bl ;sector to read + call read_drive + add bl, 1 + cmp bl, 24 + jne read + + mov ax, [OS_OFFSET] + cmp ax, 0x03e8 + ;; jne error + call enter_pm + +error: + mov bx, OS_OFFSET + mov cx, bx + add cx, 0x200 +error_out: + mov ax, [bx] + call print_word + call print_nl + add bx, 4 + cmp bx, cx + jne error_out + jmp $ + +;;; Reads from drive in reg dl, read sector LBA al +read_drive: + push bx + push cx + +;;; Calculate Offset for Kernel + mov cl, al + mov ch, 0 + sub cl, 1 + shl cx, 9 mov bx, OS_OFFSET + add bx, cx + push bx + +;;; Calculate C,H,S using algorithm from OSDev: +;;; https://wiki.osdev.org/Disk_access_using_the_BIOS_(INT_13h) + mov ah, 0 + div byte [DRIVE_SECTS_PER_TRACK] + add ah, 1 + mov bl, ah + mov ah, 0 + div byte [DRIVE_N_HEADS] + mov dh, ah + mov ch, al + mov cl, bl + + pop bx + push ax + mov ax, es + call print_word + call print_cm + mov ax, 0 + mov es, ax + pop ax + mov al, 1 + mov dl, [BOOT_DRIVE] + clc + mov ah, 2 int 0x13 ;do read - call enter_pm + mov bx, 0 + mov es, bx + call print_word + call print_nl + + pop cx + pop bx + ret + +retry_drive: +;;; Print Sectors Transferred + push ax ; Save error code + add al, 48 + call print_char + mov al, 44 + call print_char + pop ax ; Retreive error code + mov al, ah + add al, 48 + call print_char + mov al, 10 + call print_char + + mov ax, [RETRY_COUNT] + add ax, 1 + mov [RETRY_COUNT], ax + cmp ax, 1000 + jne load_kernel + jmp $ + +;;; Prints character in register al +print_char: + push ax + push bx + mov ah, 0x0e + mov bl, 1 + mov bh, 0 + int 0x10 + pop bx + pop ax + ret + +print_half_byte: + and al, 0x0F + add al, 48 + cmp al, 57 + jle skip_hex + add al, 7 +skip_hex: + call print_char + ret + +print_byte: + push ax + + mov ax, [esp] + shr al, 4 + call print_half_byte + mov ax, [esp] + mov ah, 0 + call print_half_byte + + pop ax + ret + +print_word: + push ax + mov al, ah + call print_byte + mov ax, [esp] + call print_byte + pop ax + ret + +print_nl: + push ax + mov al, 32 + call print_char + mov al, 32 + call print_char + pop ax + ret +print_cm: + push ax + mov al, 44 + call print_char + pop ax + ret + [bits 32] begin_pm: call OS_OFFSET @@ -34,4 +201,4 @@ times 509 - ($ - $$) db 0 ;padding BOOT_DRIVE db 0 ;0x7dfd ;above is data that can always be found at 0x7dfd - n during boot process -dw 0xaa55 ;magic boot sector number \ No newline at end of file +dw 0xaa55 ;magic boot sector number From ae7faeba307d708cd5c9c94513b7b9d318fee1f1 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 24 Dec 2024 00:42:45 -0500 Subject: [PATCH 02/11] Improved error handling of boot sector code and other changes. --- src/boot/boot_sect.asm | 140 ++++++++++++++++++++--------------------- 1 file changed, 67 insertions(+), 73 deletions(-) diff --git a/src/boot/boot_sect.asm b/src/boot/boot_sect.asm index ddfdf92..ed21111 100644 --- a/src/boot/boot_sect.asm +++ b/src/boot/boot_sect.asm @@ -1,13 +1,10 @@ [org 0x7c00] OS_OFFSET equ 0x1000 +MAX_READ_TRIES equ 3 +SECTORS_TO_READ equ 22 [bits 16] begin: - jmp code - RETRY_COUNT dw 0 - DRIVE_N_HEADS db 0 - DRIVE_SECTS_PER_TRACK db 0 -code: mov [BOOT_DRIVE], dl mov ax, 0 mov ds, ax @@ -20,7 +17,21 @@ code: ;;; Get Drive Parameters mov ah, 8 + mov dl, [BOOT_DRIVE] + mov di, 0 + clc int 0x13 + jnc get_params_no_error +;;; Print and stop if there is an error reading the drive parameters + mov al, ah + call print_byte + call print_cm + mov al, 'p' + call print_char + jmp $ + +get_params_no_error: +;;; Save some of the drive parameters add dh, 1 mov [DRIVE_N_HEADS], dh and cl, 0x3f @@ -33,101 +44,80 @@ code: [bits 16] load_kernel: -;;; Read Drive +;;; Read drive one sector at a time mov bl, 1 read: - mov al, bl ;sector to read + mov al, bl ; current sector to read call read_drive add bl, 1 - cmp bl, 24 - jne read - - mov ax, [OS_OFFSET] - cmp ax, 0x03e8 - ;; jne error + cmp bl, SECTORS_TO_READ + jle read call enter_pm -error: - mov bx, OS_OFFSET - mov cx, bx - add cx, 0x200 -error_out: - mov ax, [bx] - call print_word - call print_nl - add bx, 4 - cmp bx, cx - jne error_out - jmp $ - -;;; Reads from drive in reg dl, read sector LBA al +;;; Reads one sector from the drive at the given LBA into the kernel memory +;;; space at the appropriate offset (assumming 512 byte sectors). +;;; Input: +;;; [al] = LBA of sector to read +;;; Output: +;;; [cf] = Set on error +;;; [ah] = status, as returned by INT 0x13/AH=0x02 +;;; [al] = sectors transferred, as returned by INT 0x13/AH=0x02 read_drive: - push bx push cx - + push bx + push ax + + mov byte [READ_TRY_COUNT], 0 +read_drive_retry: + add byte [READ_TRY_COUNT], 1 + mov cx, 0 + mov es, cx ; Ensure segment register [es] is zero for interrupt ;;; Calculate Offset for Kernel mov cl, al - mov ch, 0 sub cl, 1 shl cx, 9 mov bx, OS_OFFSET add bx, cx - push bx ;;; Calculate C,H,S using algorithm from OSDev: ;;; https://wiki.osdev.org/Disk_access_using_the_BIOS_(INT_13h) - mov ah, 0 + mov ah, 0 ; Ensure top half of [ax] is zero so that [al] behaves as dividend div byte [DRIVE_SECTS_PER_TRACK] add ah, 1 - mov bl, ah + mov cl, ah mov ah, 0 div byte [DRIVE_N_HEADS] mov dh, ah mov ch, al - mov cl, bl - - pop bx - push ax - mov ax, es - call print_word - call print_cm - mov ax, 0 - mov es, ax - pop ax mov al, 1 + mov ah, 2 mov dl, [BOOT_DRIVE] clc - mov ah, 2 int 0x13 ;do read - mov bx, 0 - mov es, bx - call print_word + jnc read_drive_no_error + +;;; If an error occurred during the read: + call print_byte + call print_cm + mov al, ah + call print_byte + call print_cm + mov bl, [READ_TRY_COUNT] + mov al, bl + call print_byte + call print_cm + mov ax, [esp] ; Restore [al] (LBA of sector to read from) + call print_byte call print_nl + cmp bl, MAX_READ_TRIES + jl read_drive_retry + jmp $ - pop cx +read_drive_no_error: + pop bx ; Pop old value of ax pop bx + pop cx ret - -retry_drive: -;;; Print Sectors Transferred - push ax ; Save error code - add al, 48 - call print_char - mov al, 44 - call print_char - pop ax ; Retreive error code - mov al, ah - add al, 48 - call print_char - mov al, 10 - call print_char - - mov ax, [RETRY_COUNT] - add ax, 1 - mov [RETRY_COUNT], ax - cmp ax, 1000 - jne load_kernel - jmp $ ;;; Prints character in register al print_char: @@ -142,6 +132,7 @@ print_char: ret print_half_byte: + pushfd and al, 0x0F add al, 48 cmp al, 57 @@ -149,6 +140,7 @@ print_half_byte: add al, 7 skip_hex: call print_char + popfd ret print_byte: @@ -175,9 +167,9 @@ print_word: print_nl: push ax - mov al, 32 + mov al, 10 call print_char - mov al, 32 + mov al, 13 call print_char pop ax ret @@ -195,9 +187,11 @@ begin_pm: hlt -times 509 - ($ - $$) db 0 ;padding - +times 506 - ($ - $$) db 0 ;padding +READ_TRY_COUNT db 0 +DRIVE_N_HEADS db 0 +DRIVE_SECTS_PER_TRACK db 0 BOOT_DRIVE db 0 ;0x7dfd ;above is data that can always be found at 0x7dfd - n during boot process From 9d848e99c4685a0147f2f49d717c44feb5ee8a87 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 24 Dec 2024 00:43:18 -0500 Subject: [PATCH 03/11] Added code in makefile to handle size of mOS.bin binary. On QEMU, the new error handling code in the boot sector will fail since the file generated is not 512*42 bytes large (some calls to the INT 0x13/AH=0x02 interrrupt will fail, due to the size of the drive created/mounted by QEMU). The Makefile was updated both to make the mOS.bin file large enough if necessary (using truncate), and to give an error if the generated mOS.bin file is too large (larger than 512*42 bytes). Note: This has not been an issue though for booting off of floppy disks on real hardware. --- Makefile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Makefile b/Makefile index e8d4009..0c0522a 100644 --- a/Makefile +++ b/Makefile @@ -44,6 +44,8 @@ ASM_OS_ENTRY_SOURCE := ./src/boot/os_entry.asm BOOT_OBJ := boot.o OS_BIN := mOS.bin +OS_BIN_MAX_SECTORS := 42 +OS_BIN_MAX_SIZE := $$((512*$(OS_BIN_MAX_SECTORS))) C_FILES = $(shell find ./ -name '*.[ch]') @@ -64,6 +66,12 @@ $(OS_BIN): $(OBJ_NAMES) $(BOOT_OBJ) $(LD) $(LFLAGS) -T link.ld $(OBJ_NAMES) -o mOS.elf $(OBJCOPY) -O binary mOS.elf intermediate.bin cat $(BOOT_OBJ) intermediate.bin > $(OS_BIN) + @if [ $$(du -b mOS.bin | grep -o "[0-9]*") -gt $(OS_BIN_MAX_SIZE) ]; \ + then \ + echo "ERROR: mOS.bin too large!"; \ + false; \ + fi + truncate -s ">$(OS_BIN_MAX_SIZE)" $(OS_BIN) $(BOOT_OBJ): $(ASM_BOOT_SECT_SOURCE) nasm $^ -f bin -o $@ $(DEBUG_NASM_FLAGS) From 2ef4e5b8e9a433e2a9e5c69029a0d1198be2f907 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 15 Aug 2025 15:23:11 -0400 Subject: [PATCH 04/11] Clean up code and add more comments. --- src/boot/boot_sect.asm | 68 +++++++++++++++++++++++++++++++++--------- 1 file changed, 54 insertions(+), 14 deletions(-) diff --git a/src/boot/boot_sect.asm b/src/boot/boot_sect.asm index ed21111..bd09f7b 100644 --- a/src/boot/boot_sect.asm +++ b/src/boot/boot_sect.asm @@ -23,11 +23,9 @@ begin: int 0x13 jnc get_params_no_error ;;; Print and stop if there is an error reading the drive parameters + call print_error mov al, ah call print_byte - call print_cm - mov al, 'p' - call print_char jmp $ get_params_no_error: @@ -54,6 +52,7 @@ read: jle read call enter_pm +;;; function read_drive: ;;; Reads one sector from the drive at the given LBA into the kernel memory ;;; space at the appropriate offset (assumming 512 byte sectors). ;;; Input: @@ -96,30 +95,40 @@ read_drive_retry: int 0x13 ;do read jnc read_drive_no_error -;;; If an error occurred during the read: +;;; If an error occurred during the read, print out the following, separated by +;;; commas: +;;; - [al] : The actual number of sectors read. +;;; - [ah] : The return code from interrupt 0x13. +;;; - READ_TRY_COUNT : The amount of times a read has been tried so far. +;;; - Original value of [al] when read_drive was called which is the sector +;;; at which the read was attempted. +;;; After printing this info, try reading again if the number of retries has not +;;; exceeded MAX_READ_TRIES, otherwise stop. + call print_error call print_byte - call print_cm + call print_comma mov al, ah call print_byte - call print_cm + call print_comma mov bl, [READ_TRY_COUNT] mov al, bl call print_byte - call print_cm + call print_comma mov ax, [esp] ; Restore [al] (LBA of sector to read from) call print_byte - call print_nl + call print_newline cmp bl, MAX_READ_TRIES jl read_drive_retry jmp $ read_drive_no_error: - pop bx ; Pop old value of ax + pop bx ; Pop old value of ax which is no longer needed pop bx pop cx ret -;;; Prints character in register al +;;; function print_char: +;;; Prints the character in register [al]. print_char: push ax push bx @@ -131,6 +140,8 @@ print_char: pop ax ret +;;; function print_half_byte: +;;; Print the 4 least significant bits in the register [al]. print_half_byte: pushfd and al, 0x0F @@ -142,7 +153,9 @@ skip_hex: call print_char popfd ret - + +;;; function print_byte: +;;; Print the byte in register [al]. print_byte: push ax @@ -156,6 +169,8 @@ print_byte: pop ax ret +;;; function print_word: +;;; Print a 16-bit word in the register [ax]. print_word: push ax mov al, ah @@ -165,7 +180,9 @@ print_word: pop ax ret -print_nl: +;;; function print_newline: +;;; Print a newline character. Takes no arguments. +print_newline: push ax mov al, 10 call print_char @@ -174,13 +191,36 @@ print_nl: pop ax ret -print_cm: +;;; function print_comma: +;;; Print a comma character. Takes no arguments. +print_comma: push ax mov al, 44 call print_char pop ax ret - + +;;; function print_error: +;;; Print the string "ERROR: ". Takes no arguments. +print_error: + push ax + mov al, 'E' + call print_char + mov al, 'R' + call print_char + mov al, 'R' + call print_char + mov al, 'O' + call print_char + mov al, 'R' + call print_char + mov al, ':' + call print_char + mov al, ' ' + call print_char + pop ax + ret + [bits 32] begin_pm: call OS_OFFSET From e42542b7ed70dab70115eda0b784037911ca3ce4 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 15 Aug 2025 16:57:29 -0400 Subject: [PATCH 05/11] Increase the total number of sectors read back to 42. --- src/boot/boot_sect.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/boot/boot_sect.asm b/src/boot/boot_sect.asm index bd09f7b..ff6f352 100644 --- a/src/boot/boot_sect.asm +++ b/src/boot/boot_sect.asm @@ -1,7 +1,7 @@ [org 0x7c00] OS_OFFSET equ 0x1000 MAX_READ_TRIES equ 3 -SECTORS_TO_READ equ 22 +SECTORS_TO_READ equ 41 [bits 16] begin: From 6d91507cf9fab5920adbe30901eb1c7f51cb550a Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 26 Aug 2025 19:16:03 -0400 Subject: [PATCH 06/11] Change variable names and add comments. --- Makefile | 14 +++++++++----- src/boot/boot_sect.asm | 13 +++++++++++-- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 3d07c63..0b5f96f 100644 --- a/Makefile +++ b/Makefile @@ -43,9 +43,13 @@ ASM_BOOT_SECT_SOURCE := ./src/boot/boot_sect.asm ASM_OS_ENTRY_SOURCE := ./src/boot/os_entry.asm BOOT_OBJ := boot.o -OS_BIN := mOS.bin -OS_BIN_MAX_SECTORS := 42 -OS_BIN_MAX_SIZE := $$((512*$(OS_BIN_MAX_SECTORS))) +OS_BIN := mOS.bin\ + +# The total number of 512-byte sectors for the size of the OS binary. +# WARNING: This MUST be equal to the identically named constant in the +# file 'src/boot/boot_sect.asm'. +OS_BIN_TOTAL_SECTORS := 42 +OS_BIN_SIZE_BYTES := $$((512*$(OS_BIN_TOTAL_SECTORS))) C_FILES = $(shell find ./ -name '*.[ch]') @@ -64,12 +68,12 @@ $(OS_BIN): $(OBJ_NAMES) $(BOOT_OBJ) $(LD) $(LFLAGS) -T link.ld $(OBJ_NAMES) -o mOS.elf $(OBJCOPY) -O binary mOS.elf intermediate.bin cat $(BOOT_OBJ) intermediate.bin > $(OS_BIN) - @if [ $$(du -b mOS.bin | grep -o "[0-9]*") -gt $(OS_BIN_MAX_SIZE) ]; \ + @if [ $$(du -b mOS.bin | grep -o "[0-9]*") -gt $(OS_BIN_SIZE_BYTES) ]; \ then \ echo "ERROR: mOS.bin too large!"; \ false; \ fi - truncate -s ">$(OS_BIN_MAX_SIZE)" $(OS_BIN) + truncate -s ">$(OS_BIN_SIZE_BYTES)" $(OS_BIN) $(BOOT_OBJ): $(ASM_BOOT_SECT_SOURCE) nasm $^ -f bin -o $@ $(DEBUG_NASM_FLAGS) diff --git a/src/boot/boot_sect.asm b/src/boot/boot_sect.asm index ff6f352..826ce85 100644 --- a/src/boot/boot_sect.asm +++ b/src/boot/boot_sect.asm @@ -1,7 +1,16 @@ [org 0x7c00] OS_OFFSET equ 0x1000 MAX_READ_TRIES equ 3 -SECTORS_TO_READ equ 41 + + +;;; Total number of sectors to read from the boot drive, including the boot +;;; sector. +;;; WARNING: This MUST be equal to the identically named constant in the +;;; Makefile. +OS_BIN_TOTAL_SECTORS equ 42 +;;; The number of sectors to read from the boot drive in addition to the boot +;;; sector. +ADDITIONAL_SECTORS_TO_READ equ OS_BIN_TOTAL_SECTORS-1 [bits 16] begin: @@ -48,7 +57,7 @@ read: mov al, bl ; current sector to read call read_drive add bl, 1 - cmp bl, SECTORS_TO_READ + cmp bl, ADDITIONAL_SECTORS_TO_READ jle read call enter_pm From a046e98b11a6890f2ae5b09e7188aa994a58d972 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 26 Aug 2025 20:56:16 -0400 Subject: [PATCH 07/11] Update docs for changes to 'boot_sect.asm'. --- docs/boot/boot.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/docs/boot/boot.md b/docs/boot/boot.md index 9e9ca22..0b59e39 100644 --- a/docs/boot/boot.md +++ b/docs/boot/boot.md @@ -9,7 +9,7 @@ Finally, we get to the OS, BIOS will load the first sector (512-bytes) of the di ## Boot Sector -The boot sector (see [boot_sect.asm](../../src/boot/boot_sect.asm)) is the very first code that we write that gets executed. It is important to keep in mind at this point we only have 512-bytes of code/data loaded, which is not much. In addition we also need the "magic word" 0xaa55 as the last word in the sector to signify that this is a bootable sector. `times 509 - ($ - $$) db 0` is a neat assembly trick that gets our binary to exactly 512-bytes. +The boot sector (see [boot_sect.asm](../../src/boot/boot_sect.asm)) is the very first code that we write that gets executed. It is important to keep in mind at this point we only have 512-bytes of code/data loaded, which is not much. In addition we also need the "magic word" 0xaa55 as the last word in the sector to signify that this is a bootable sector. `times 506 - ($ - $$) db 0` is a neat assembly trick that gets our binary to exactly 512-bytes. You may have noticed `[bits 16]` in the assembly, this is because BIOS starts us out in "real mode" which is fancy for 16-bit. Real mode uses segmentation heavily, but discussing segmentation is outside of the scope of this document since we don't have to deal with it. First we store the boot drive in a defined place in memory. BIOS puts the boot drive in `dl` on boot. Next we set the stack to be at 0x9000 (`bp` and `sp` are the 16-bit stack registers). Our next step is to load the rest of the kernel. BIOS uses Cylinder Head Sector (CHS) addressing for disk access, here are some important details: @@ -17,8 +17,20 @@ First we store the boot drive in a defined place in memory. BIOS puts the boot d - A cylinder is a ring on a platter that is indexed from 0. - A head is the physical reader that is also indexed from 0. -Since we want the second sector (first is the boot sector) onwards, we only need the very first cylinder and head. Now we want to tell the BIOS to execute a read operation. -We move `2` into `ah` to signify we want to read. Then `42` into `al` to signify we want to read 42 sectors (512 * 42 = 21504-bytes). Then `cl` gets 2 for the sector, `ch` and `dh` get 0 for cylinder and head respectively. Then `OS_OFFSET` (0x1000) is put in `bx`, this tells BIOS where we want the result of our read to be stored in memory. Finally, we do `int 0x13` which is the disk interrupt for BIOS. +CHS addressing is not super convenient to use; it would be better if we could use Logical Block Addresses (LBA) instead, which would just give us a simple linear address space for our drive. +Thus, to aid in loading the rest of the binary for our OS, we define an assembly routine called `read_drive` which takes an LBA in register `al`, converts the LBA to a CHS address, reads from the drive, and returns the status of the read in the registers `cf`, `ah`, and `al` (see [boot_sect.asm](../../src/boot/boot_sect.asm)). LBAs are converted to CHS addresses using an algorithm described on OSDev (see [https://wiki.osdev.org/Disk_access_using_the_BIOS_(INT_13h)]). + +The `read_drive` routine is implemented on top of the `int 0x13` BIOS interrupt, which provides functionality for manipulating drives (see https://en.wikipedia.org/wiki/INT_13H). In our case we call `int 0x13` with the following register arguments: + - `ah=2` -- 2 tells it to do a read. + - `al=1` -- Read just one sector. + - `cl=sector` -- Where `sector` is computed from the LBA. + - `ch=cylinder` -- Where `cylinder` is computed from the LBA. + - `dh=head` -- Where `head` is computed from the LBA. + - `dl=drive` -- Where `drive` is the drive number to read from. + - `es=0:bx=offset` -- Where `offset` is computed from the LBA (that was passed in to `read_drive`) such that `offset=((LBA-1)*512)+0x1000`, which has the effect of mapping LBA 1 onward onto the memory region starting at 0x1000. + +The `read_drive` routine is used inside of a loop that reads the rest of the OS binary one sector at a time. If a read for any given sector fails, we attempt to read that that sector at most two more times before giving up on booting entirely. + Now that we have the OS loaded, we need to get into 32-bit mode (also known as protected mode, long mode is 64-bit). Now we switch over to [enter_pm.asm](../../src/boot/enter_pm.asm) and [gdt.asm](../../src/boot/gdt.asm). ### Protected Mode From d8f9908bd865741bed296359a0a205b0550ae8f1 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 5 Sep 2025 13:54:45 -0400 Subject: [PATCH 08/11] Remove stray '\'. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0b5f96f..b0a3d17 100644 --- a/Makefile +++ b/Makefile @@ -43,7 +43,7 @@ ASM_BOOT_SECT_SOURCE := ./src/boot/boot_sect.asm ASM_OS_ENTRY_SOURCE := ./src/boot/os_entry.asm BOOT_OBJ := boot.o -OS_BIN := mOS.bin\ +OS_BIN := mOS.bin # The total number of 512-byte sectors for the size of the OS binary. # WARNING: This MUST be equal to the identically named constant in the From 53c9af8ce27bf0f23620f3bbbb9053adf373669c Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 5 Sep 2025 13:56:21 -0400 Subject: [PATCH 09/11] Fix mispelled word. 'assumming' -> 'assuming'. --- src/boot/boot_sect.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/boot/boot_sect.asm b/src/boot/boot_sect.asm index 826ce85..a41558a 100644 --- a/src/boot/boot_sect.asm +++ b/src/boot/boot_sect.asm @@ -63,7 +63,7 @@ read: ;;; function read_drive: ;;; Reads one sector from the drive at the given LBA into the kernel memory -;;; space at the appropriate offset (assumming 512 byte sectors). +;;; space at the appropriate offset (assuming 512 byte sectors). ;;; Input: ;;; [al] = LBA of sector to read ;;; Output: From 161b505c0fa3ed96b803d27e737359f879df6075 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 5 Sep 2025 14:01:50 -0400 Subject: [PATCH 10/11] Replace magic numbers with character literals in boot_sect.asm. --- src/boot/boot_sect.asm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/boot/boot_sect.asm b/src/boot/boot_sect.asm index a41558a..874a27b 100644 --- a/src/boot/boot_sect.asm +++ b/src/boot/boot_sect.asm @@ -154,8 +154,8 @@ print_char: print_half_byte: pushfd and al, 0x0F - add al, 48 - cmp al, 57 + add al, '0' + cmp al, '9' jle skip_hex add al, 7 skip_hex: @@ -193,9 +193,9 @@ print_word: ;;; Print a newline character. Takes no arguments. print_newline: push ax - mov al, 10 + mov al, `\n` call print_char - mov al, 13 + mov al, `\r` call print_char pop ax ret @@ -204,7 +204,7 @@ print_newline: ;;; Print a comma character. Takes no arguments. print_comma: push ax - mov al, 44 + mov al, ',' call print_char pop ax ret From 756a5466635e4b71444d3e4bc51ee42a3cac963b Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 5 Sep 2025 14:04:05 -0400 Subject: [PATCH 11/11] Removed redundant mov instruction in boot_sect.asm. --- src/boot/boot_sect.asm | 1 - 1 file changed, 1 deletion(-) diff --git a/src/boot/boot_sect.asm b/src/boot/boot_sect.asm index 874a27b..43ff72b 100644 --- a/src/boot/boot_sect.asm +++ b/src/boot/boot_sect.asm @@ -168,7 +168,6 @@ skip_hex: print_byte: push ax - mov ax, [esp] shr al, 4 call print_half_byte mov ax, [esp]