Trying to fix the boot2.asm second stage bootloader

This commit is contained in:
Gregory Kenneth Bowne 2024-02-09 16:36:16 -08:00
parent 19b61da1af
commit 8e7cdce87d
5 changed files with 195 additions and 116 deletions

BIN
.vscode/browse.vc.db vendored

Binary file not shown.

Binary file not shown.

2
.vscode/launch.json vendored
View File

@ -8,7 +8,7 @@
"name": "gcc-8 - Build and debug active file Level 1",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/${fileBasenameNoExtension}",
"program": "/home/gbowne1/Documents/ClassicOS/build/ClassicOS",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",

View File

@ -2,42 +2,123 @@
[ORG 0x0000]
start:
MOV AX, CS
MOV DS, AX
; Initialize stack
MOV AX, 0x0000 ; Set up a segment for the stack
MOV SS, AX
MOV SP, 0xFFFF
MOV SP, 0xFFFF ; Stack grows downwards from the top of the segment
MOV SI, msg
JMP println
; Copy boot sector data to a safe location
mCopyBootSector
JMP $
; Load the kernel
CALL load_kernel
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
; ...
RET
println:
.next_char:
LODSB
OR AL, AL
JZ .stop
MOV AH, 0x0E
MOV BH, 0x00
MOV BL, 0x07
INT 0x10
enable_a20:
; Enable A20 gate
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
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, 0x02 ; New output port data with A20 enabled
out 0x60, al ; Write new output port data
call a20wait ; Wait for the keyboard controller to be ready
sti ; Re-enable interrupts
ret
JMP .next_char
; 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
.stop:
MOV AH, 0x03 ; AH = 0x03 (Get Cursor Position and Shape)
XOR BH, BH ; BH = 0x00 (Video Page Number)
INT 0x10 ; Call video interrupt
; Enter kernel space and jump to the kernel entry point
JMP 0x1000:0x0000
INC DH
; 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
; ...
MOV AH, 0x02 ; Set cursor position
XOR BH, BH ; Page number
XOR DL, DL ; Column (start from 0)
INT 0x10 ; Call video interrupt
RET
; Jump to the kernel entry point
JMP 0x1000:0x0000 ; Assuming the kernel is loaded at 0x1000:0x0000
msg db "Second stage loaded, and Gbowne1 stinks.", 0
; 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

View File

@ -1,17 +1,15 @@
#include "cpu.h"
// Function to read a 32-bit value from a CPU register
uint32_t read_register(uint8_t reg)
{
uint32_t read_register(uint8_t reg) {
uint32_t value;
__asm__ volatile("mov %0, %%" + reg : "=r"(value));
__asm__ volatile("mov %0, %%" : "+r"(value) : "c"(reg));
return value;
}
// Function to write a 32-bit value to a CPU register
void write_register(uint8_t reg, uint32_t value)
{
__asm__ volatile("mov %0, %%" + reg : : "r"(value));
void write_register(uint8_t reg, uint32_t value) {
__asm__ volatile("mov %0, %%" : : "c"(reg), "r"(value));
}
// Function to read the value of the CR0 register