From f4c5d59d8e40c308bc4411e113dd46b354a9e2fe Mon Sep 17 00:00:00 2001 From: Greg Bowne Date: Sun, 24 Mar 2024 21:09:02 -0700 Subject: [PATCH] adding bootloader files from the issue in gittea --- .vscode/browse.vc.db | Bin 33939456 -> 33939456 bytes .vscode/browse.vc.db-shm | Bin 32768 -> 32768 bytes .vscode/browse.vc.db-wal | Bin 82192 -> 0 bytes src/boot/boot.asm | 253 ++++++++++++++++++++++----------------- src/boot/boot2.asm | 210 +++++++++++++------------------- 5 files changed, 224 insertions(+), 239 deletions(-) diff --git a/.vscode/browse.vc.db b/.vscode/browse.vc.db index 0dd233d22fe6b1b65416e2b1c0c6b25d3716b07b..0da4a0d04bee1133668435113af3e84f76119f17 100644 GIT binary patch delta 2778 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 diff --git a/.vscode/browse.vc.db-shm b/.vscode/browse.vc.db-shm index 393371e9adfd62d87381ce987d3247ef5cc5a839..795ab0e70a110a7b1ee150a6ed2f1cf0414f0801 100644 GIT binary patch delta 267 zcmZo@U}|V!s+V}A%K!p$K+MR%pa5d)3otP3_|5rQFYBOyxXFpSmXaII4Cl92Zw-@O zPO5s4c`)!F2|&dr)^pl20olwzYzM@AKsWFMu{aP*0kJ#~;}Qq!+qjX}iJ6UoXX8e7 zW@bhP{*4=dGchwU2yEPVo{5>Afp_D^&wR`r4160m%JVX_FmQq8SsA!DZk*4@%*?>K IabqPL0HWbO#Q*>R delta 211 zcmZo@U}|V!s+V}A%K!qbK+MR%puh#B^#vFh{vBCls1|eYz?vD6id)y)Y-QU%)w{t& zd^)M>L1u#h$lU)(04&JBFtMIfl?BKKS&x_Ac#+X*;{z{FPDTc1plWso&W#tpGI25i Nb+IvUFmM6o4FU1zGR6P^ diff --git a/.vscode/browse.vc.db-wal b/.vscode/browse.vc.db-wal index a58895a7e3aaae2b5ce0f223c908db513acd7b10..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 GIT binary patch literal 0 HcmV?d00001 literal 82192 zcmeI*PiUKE9Ki92sRv}FcCI8Qw{L4ZYa~E`009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7csfjtly(q6z^XWiY62kC`UrkpM2N`-W;oL|ajii?GOI#tZx*9-V`_U7{F z&DAfqdI8;9K&b42q?aH-fB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C6Bk(VK z0mtICBct8h@a3r6@U@F;^+tWIez|dcKzjijezVg=irJ2oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FoI>0)y8JIM$N_h@^J)v*bDdvIs9&r diff --git a/src/boot/boot.asm b/src/boot/boot.asm index 9ed4f16..926dd31 100644 --- a/src/boot/boot.asm +++ b/src/boot/boot.asm @@ -1,131 +1,166 @@ -[BITS 16] -[ORG 0x7c00] +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Stage 1 bootloader for ClassicOS ; +; -------------------------------- ; +; Determines if it was loaded from ; +; a floppy disk or an hard disk ; +; drive, and then loads stage 2 ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +; Assembler directives ; +;;;;;;;;;;;;;;;;;;;;;;;; + +; tells the assembler that the program will be loaded at 0x7C00 +; this is done by the BIOS +org 0x7C00 + +; we are targeting (x86) 16-bit real mode +bits 16 + +;;;;;;;;;;;;;;;;; +; Jump to start ; +;;;;;;;;;;;;;;;;; +jmp start + +;;;;;;;; +; Data ; +;;;;;;;; +; fdd geometry & options +fddsamt db 8 ; how many sectors to load +fddretr db 5 ; max retries for fdd operations +fddcretr db 0 ; current retries left + +; misc strings +welcome1 db "Welcome to the ClassicOS Stage 1 bootloader.", 13, 10, 0 +disktype db "Drive type: ", 0 +diskfdd db "FDD", 13, 10, 0 +diskhdd db "HDD", 13, 10, 0 +loaded db "Data loaded!", 13, 10, 0 + +; errors +fdderes db "FDD reset failed.", 13, 10, 0 +fddeload db "FDD read failed.", 13, 10, 0 + +; storage +disknum db 0 + +;;;;;;;;;;; +; Program ; +;;;;;;;;;;; start: - ; Processor initialization (only stack segment register needed) - mov ss, 0x1000 ; Set stack segment register - mov sp, 0x7C00 ; Set stack pointer (SP) - mov ds, ss ; Set data segment register (DS) + xor ax, ax ; set up segment registers to segment 0 since + mov ds, ax ; our addresses are already relative to 0x7C00 + mov es, ax -; Identify boot device using BIOS calls -identify_drive: - mov ah, 0x0E ; Get Interrupt Vector for INT 13h (Disk Services) - int 0x80 - cmp cl, 0x41 ; Check for floppy drive interrupt vector (example) - je is_floppy - cmp cl, 0x80 ; Check for hard disk interrupt vector (example) - je is_harddrive - ; Handle invalid drive type (error handling) - ; ... + mov [disknum], dl ; save disk number to memory -is_floppy: - ; Perform floppy disk access (assuming AH=0x02 for read sectors) - mov ah, 0x02 ; Read sectors - mov al, 1 ; Number of sectors to read (1) + mov ah, 0x01 ; set cursor shape + mov cx, 0x0100 ; hide cursor by setting ch = 1 and cl = 0x00 + int 0x10 ; video interrupt - ; Set CH, CL, DH, DL for floppy based on your system configuration - ; (Replace these values with appropriate settings for your floppy drive) - mov ch, 0 ; Cylinder (example, adjust based on your floppy) - mov cl, 1 ; Sector number (example, adjust based on boot sector location) - mov dh, 0 ; Head number (example, typically 0 for single-sided floppies) - mov dl, 0x00 ; Drive number (0x00 for floppy drive A) + mov ah, 0x08 ; read page number into bh + int 0x10 - ; Set ES:BX to the memory address where you want to store the read data - mov es, 0x1000 ; Example segment (adjust as needed) - mov bx, 0x0 ; Memory offset within the segment (example) + mov si, welcome1 ; print welcome + call printstr - int 0x13 - jc error_floppy + mov si, disktype ; print first part of disk type + call printstr - ; Implement error handling (omitted here for brevity) - ; Process the read data from the floppy sector (load second stage bootloader, etc.) + mov dl, [disknum] ; restore disk number - should not be + ; strictly necessary but you never know + and dl, 0x80 ; sets zf if disk is floppy + jz fddload -is_harddrive: +hddload: + mov si, diskhdd ; print disk type + call printstr - ; Sample code (not guaranteed to work universally) - mov ah, 0x02 ; Set function for read sectors - mov al, 0x01 ; Read one sector - ; Set CH, CL, DH for desired sector location (e.g., first sector) - mov dl, 0x80 ; Drive number (assuming drive A is boot device) - mov es, segment_address ; Set ES for buffer to store read data - mov bx, buffer_offset ; Set BX for offset within the buffer + jmp halt ; not implemented! - int 13h ; Raise BIOS interrupt for disk read +fddload: + mov si, diskfdd ; print disk type + call printstr - ; Check Carry flag for error handling - jc harddrive_not_found ; Jump if Carry flag is set (potential error) +fddload_onto_reset: + mov ah, [fddretr] ; load max retries in memory + mov [fddcretr], ah +fddload_reset: + mov si, fdderes ; load error message pointer + dec byte [fddcretr] ; decrement the retries counter + jz fddload_err ; if it is 0, we stop trying - ; Hard drive likely present (further processing can occur) + mov ah, 0x00 ; otherwise, reset function (int 0x13) + int 0x13 + jc fddload_reset ; if jc (error), we try again - ; ... (rest of your bootloader code) +fddload_onto_load: + mov ah, [fddretr] ; reset retries counter + mov [fddcretr], ah + mov ax, 0x1000 ; need to stay within real mode limits + mov es, ax +fddload_load: ; loads 512*fddsamt bytes from sector 2 on. + mov si, fddeload + dec byte [fddcretr] + jz fddload_err - harddrive_not_found: - ; Handle error condition (missing drive or other issue) + mov dh, 0 ; head 0 + mov ch, 0 ; cyl/track 0 + mov cl, 2 ; start sector + mov bx, 0 ; memory location + mov al, [fddsamt] ; how many sectors to read + mov ah, 0x02 ; read function (int 0x13) + int 0x13 + jc fddload_load ; if jc (error), we try again + cmp al, [fddsamt] ; also if al is not 1, we have a problem + jnz fddload_load - ; ... (error handling logic) +fddload_done: + mov si, loaded ; we have successfully loaded the data + call printstr + jmp halt ; this will be jmp 0x1000:0x0000 -memory_error: - ; ... (error handling or continue with limited memory) +fddload_err: + call printstr ; print + jmp halt ; and die -; Second stage loading (simplified example) -; Here's an improved version of the load_second_stage section with the placeholder jump replaced by actual loading logic: -; Code snippet +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; printstr routine, prints the string pointed by si using int 0x10 ; +; sets the direction flag to 0 ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +printstr: + cld ; clear df flag - lodsb increments si +printstr_loop: + lodsb ; load next character into al, increment si + or al, al ; sets zf if al is 0x00 + jz printstr_end + mov ah, 0x0E ; teletype output (int 0x10) + int 0x10 ; print character + jmp printstr_loop +printstr_end: + ret ; return to caller address -load_second_stage: - ; Calculate address of second stage bootloader (assuming offset from boot sector) - mov dx, 0x0000 ; Clear DX register for better calculation - add dx, sector_count ; Add number of sectors to skip (adjust as needed) - shl dx, 5 ; Multiply by sector size (512 bytes) - add dx, 0x7C00 ; Add boot sector address offset - ; Read second stage bootloader from calculated address - mov ah, 0x02 ; Function for reading sectors - mov al, 1 ; Number of sectors to read (1 for second stage) - mov es, dx ; Set ES segment register to calculated address - mov bx, 0x0000 ; Set BX offset within the segment (example) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; halt routine - infinite loop ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +halt: + cli + jmp halt - int 13h ; Raise BIOS interrupt for disk read +;;;;;;;;;;; +; Padding ; +;;;;;;;;;;; +; $ is the address of the current line, $$ is the base address for +; this program. +; the expression is expanded to 510 - ($ - 0x7C00), or +; 510 + 0x7C00 - $, which is, in other words, the number of bytes +; before the address 510 + 0x7C00 (= 0x7DFD), where the 0xAA55 +; signature shall be put. +times 510 - ($ - $$) db 0x00 - ; Check Carry flag for error handling - jc memory_error ; Jump if Carry flag is set (potential error) - - ; Second stage likely loaded successfully, jump to it - jmp second_stage_address ; Direct jump to the defined address - -error_floppy: - ; Display a basic error message (optional) - mov ah, 0x0E ; BIOS video call for displaying text (educational purposes) - mov bh, 0x00 ; Set background color (black) - mov bl, 0x07 ; Set text color (white) - mov dx, error_floppy_message ; Address of error message string - int 0x10 ; BIOS video interrupt - - ; Halt the boot process (replace with a retry or more advanced error handling) - hlt ; Halt instruction - -error_floppy_message db 'Floppy disk read error!', 0x0 - -memory_error: - ; Check for available memory (replace with actual method) - ; ... (e.g., call BIOS service for memory size or use a constant value) - cmp available_memory, memory_threshold ; Compare with minimum required memory - jb limited_memory_boot ; Jump if below threshold - - ; ... (standard error handling for other scenarios) - -limited_memory_boot: - ; Perform minimal setup for limited memory boot - ; ... (disable non-essential features, adjust kernel parameters) - - ; Load and jump to second stage bootloader (potentially with adjustments) - ; ... (modify loading logic if necessary) - -; Define variables used for calculation (adjust as needed) -sector_count db 1 ; Number of sectors to skip before second stage (change if needed) -second_stage_address equ 0x8000 ; Replace with actual address of your second stage bootloader -available_memory equ 0x100000 ; Replace with actual memory size detection (1MB in this example) -memory_threshold equ 0x0A0000 ; Example minimum memory required (adjust based on needs) - -; Padding and magic number (standard practice) -times 510-($-$$) db 0 -dw 0xaa55 +;;;;;;;;;;;;;;;;;; +; BIOS signature ; +;;;;;;;;;;;;;;;;;; +dw 0xAA55 diff --git a/src/boot/boot2.asm b/src/boot/boot2.asm index fffde1f..cf5c437 100644 --- a/src/boot/boot2.asm +++ b/src/boot/boot2.asm @@ -1,141 +1,91 @@ -[BITS 16] -[ORG 0x0000] +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Stage 2 bootloader for ClassicOS ; +; -------------------------------- ; +; Loads the kernel, sets up tables, ; +; and transitions to protected mode ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;; +; Assembler directives ; +;;;;;;;;;;;;;;;;;;;;;;;; + +; tells the assembler that the program will be loaded at 0x8000 +; this is done by the first stage bootloader +org 0x8000 + +; we are targeting (x86) 16-bit real mode +bits 16 + +;;;;;;;;;;;;;;;;; +; Jump to start ; +;;;;;;;;;;;;;;;;; +jmp start + +;;;;;;;; +; Data ; +;;;;;;;; +; kernel file name +kername db "KERNEL.BIN", 0 + +;;;;;;;;;;; +; Program ; +;;;;;;;;;;; start: - ; Initialize stack - MOV AX, 0x0000 ; Set up a segment for the stack - MOV SS, AX - MOV SP, 0xFFFF ; Stack grows downwards from the top of the segment + xor ax, ax ; set up segment registers to segment 0 since + mov ds, ax ; our addresses are already relative to 0x8000 + mov es, ax - ; Copy boot sector data to a safe location - call mCopyBootSector - ; Load the kernel - CALL load_kernel + mov si, kername ; print kernel file name + call printstr -switch_to_protected_mode: - CLI ; Disable interrupts - lgdt [gdt_descriptor] ; Load the global descriptor table - MOV EAX, CR0 - OR EAX, 0x1 ; Set the PE (Protection Enable) bit - MOV CR0, EAX - ; Far jump to flush CPU queue after changing to protected mode - JMP CODE_SEG:init_pm ; CODE_SEG is the segment selector for code segment in GDT -init_pm: - ; Update segment registers here - ; Set code segment register (CS) to point to code segment descriptor (selector 1) - mov ax, 0x0001 - mov ds, ax ; Set data segment register (DS) to point to data segment descriptor (selector 2) - mov es, ax ; Set other segment registers (ES, SS, etc.) as needed - RET + ; Load the kernel into memory + ; ... -enable_a20: - cli ; Disable interrupts to prevent interference - call a20wait ; Wait for the keyboard controller to be ready - mov al, 0xAD ; Command to disable keyboard - out 0x64, al ; Send command to keyboard controller command port - call a20wait ; Wait for the keyboard controller to be ready - mov al, 0xD0 ; Command to read output port - out 0x64, al ; Send command to keyboard controller command port - call a20wait ; Wait for the keyboard controller to be ready - in al, 0x60 ; Read current state of output port - or al, 0x02 ; Set A20 bit - out 0x64, al ; Send command to keyboard controller command port - call a20wait ; Wait for the keyboard controller to be ready - mov al, 0xD1 ; Command to write output port - out 0x64, al ; Send command to keyboard controller command port - call a20wait ; Wait for the keyboard controller to be ready - mov al, 0xAE ; Command to re-enable keyboard - out 0x64, al ; Send command to keyboard controller command port - sti ; Re-enable interrupts - ret + ; Set up GDT, IDT, IVT + ; ... -; Wait for keyboard controller to be ready -a20wait: - in al, 0x64 ; Read keyboard controller status port - test al, 0x02 ; Check if input buffer is full - jnz a20wait ; Wait until it's not full - ret + ; Switch to protected mode + ; ... -; Enter kernel space and jump to the kernel entry point -JMP 0x1000:0x0000 + ; Set up stack and start executing kernel's code + ; ... -; Code to set up flat memory model for protected mode -; This involves setting up the segment registers with selectors -; that point to descriptors in the GDT that define a flat memory model +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; printstr routine, prints the string pointed by si using int 0x10 ; +; sets the direction flag to 0 ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +printstr: + cld ; clear df flag - lodsb increments si +printstr_loop: + lodsb ; load next character into al, increment si + or al, al ; sets zf if al is 0x00 + jz printstr_end + mov ah, 0x0E ; teletype output (int 0x10) + int 0x10 ; print character + jmp printstr_loop +printstr_end: + ret ; return to caller address -limit = 0x00CFFFFFh ; Define limit as a separate variable within gdt_struct +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; halt routine - infinite loop ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +halt: + cli + jmp halt -; Placeholder instruction to satisfy NASM -dummy_instruction DB 0x90 ; NOP instruction as a placeholder +;;;;;;;;;;; +; Padding ; +;;;;;;;;;;; +; $ is the address of the current line, $$ is the base address for +; this program. +; the expression is expanded to 510 - ($ - 0x8000), or +; 510 + 0x8000 - $, which is, in other words, the number of bytes +; before the address 510 + 0x8000 (= 0x80FD), where the 0xAA55 +; signature shall be put. +times 510 - ($ - $$) db 0x00 -gdt_struct: - - base_addr equ 0x0000000 - - ; Null descriptor (ignored) - dd base_addr, 0 ; Both values are zero for a null descriptor - - ; Code segment descriptor (flat memory model) - dd base_addr, limit - db 0x9A - db 0xCF - - ; Data segment descriptor (flat memory model) - dd base_addr, limit - db 0x92 - db 0xCF - -; Macro to copy boot sector data to a safe location -mCopyBootSector: - pusha ; Save all general-purpose registers - mov si, 0x7C00 ; Source address: where BIOS loads the boot sector - mov di, 0x6000 ; Destination address: safe memory area - mov cx, 512 ; Number of bytes to copy (size of boot sector) - cld ; Clear direction flag to increment SI and DI -copy_loop: - lodsb ; Load byte at address DS:SI into AL, increment SI - stosb ; Store byte from AL to address ES:DI, increment DI - loop copy_loop ; Decrement CX; if CX != 0, repeat loop - popa ; Restore all general-purpose registers - ret - -; Subroutine to load the kernel -load_kernel: - ; Disable interrupts - cli - - ; Setup disk parameters - ; ... (set CH, CL, DH, DL for LBA, set DX for drive number) - - ; Calculate load address for kernel - ; ... (set ES:BX to the target memory address) - - ; Read sectors from disk into memory - mov ah, 0x02 ; Read sectors function - mov al, 1 ; Number of sectors to read - int 0x13 ; BIOS disk services - - ; Check for read error - jc .disk_error ; Carry flag set means an error occurred - - ; Enable A20 line if necessary - ; ... (implementation depends on your system) - - ; Jump to the kernel's entry point - jmp 0x1000:0x0000 ; Assuming the kernel is loaded at 0x1000:0x0000 - -.disk_error: - ; Handle disk read error - ; ... (display error message or halt) - - hlt ; Halt the system - -; Function or Subroutine to switch to protected mode -switch_to_protected_mode: - CLI ; Disable interrupts - LGDT [gdt_descriptor] ; Load the global descriptor table - MOV EAX, CR0 - OR EAX, 0x1 ; Set the PE (Protection Enable) bit - MOV CR0, EAX - ; Far jump to flush CPU queue after changing to protected mode - JMP CODE_SEG:init_pm ; CODE_SEG is the segment selector for code segment in GDT \ No newline at end of file +;;;;;;;;;;;;;;;;;; +; BIOS signature ; +;;;;;;;;;;;;;;;;;; +dw 0xAA55