mirror of
https://github.com/gbowne1/ClassicOS.git
synced 2024-11-21 22:06:51 -08:00
adding bootloader files from the issue in gittea
This commit is contained in:
parent
a6f5bdb64c
commit
f4c5d59d8e
BIN
.vscode/browse.vc.db
vendored
BIN
.vscode/browse.vc.db
vendored
Binary file not shown.
BIN
.vscode/browse.vc.db-shm
vendored
BIN
.vscode/browse.vc.db-shm
vendored
Binary file not shown.
BIN
.vscode/browse.vc.db-wal
vendored
BIN
.vscode/browse.vc.db-wal
vendored
Binary file not shown.
@ -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:
|
start:
|
||||||
; Processor initialization (only stack segment register needed)
|
xor ax, ax ; set up segment registers to segment 0 since
|
||||||
mov ss, 0x1000 ; Set stack segment register
|
mov ds, ax ; our addresses are already relative to 0x7C00
|
||||||
mov sp, 0x7C00 ; Set stack pointer (SP)
|
mov es, ax
|
||||||
mov ds, ss ; Set data segment register (DS)
|
|
||||||
|
|
||||||
; Identify boot device using BIOS calls
|
mov [disknum], dl ; save disk number to memory
|
||||||
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)
|
|
||||||
; ...
|
|
||||||
|
|
||||||
is_floppy:
|
mov ah, 0x01 ; set cursor shape
|
||||||
; Perform floppy disk access (assuming AH=0x02 for read sectors)
|
mov cx, 0x0100 ; hide cursor by setting ch = 1 and cl = 0x00
|
||||||
mov ah, 0x02 ; Read sectors
|
int 0x10 ; video interrupt
|
||||||
mov al, 1 ; Number of sectors to read (1)
|
|
||||||
|
|
||||||
; Set CH, CL, DH, DL for floppy based on your system configuration
|
mov ah, 0x08 ; read page number into bh
|
||||||
; (Replace these values with appropriate settings for your floppy drive)
|
int 0x10
|
||||||
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)
|
|
||||||
|
|
||||||
; Set ES:BX to the memory address where you want to store the read data
|
mov si, welcome1 ; print welcome
|
||||||
mov es, 0x1000 ; Example segment (adjust as needed)
|
call printstr
|
||||||
mov bx, 0x0 ; Memory offset within the segment (example)
|
|
||||||
|
|
||||||
|
mov si, disktype ; print first part of disk type
|
||||||
|
call printstr
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
hddload:
|
||||||
|
mov si, diskhdd ; print disk type
|
||||||
|
call printstr
|
||||||
|
|
||||||
|
jmp halt ; not implemented!
|
||||||
|
|
||||||
|
fddload:
|
||||||
|
mov si, diskfdd ; print disk type
|
||||||
|
call printstr
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
mov ah, 0x00 ; otherwise, reset function (int 0x13)
|
||||||
int 0x13
|
int 0x13
|
||||||
jc error_floppy
|
jc fddload_reset ; if jc (error), we try again
|
||||||
|
|
||||||
; Implement error handling (omitted here for brevity)
|
fddload_onto_load:
|
||||||
; Process the read data from the floppy sector (load second stage bootloader, etc.)
|
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
|
||||||
|
|
||||||
is_harddrive:
|
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
|
||||||
|
|
||||||
; Sample code (not guaranteed to work universally)
|
fddload_done:
|
||||||
mov ah, 0x02 ; Set function for read sectors
|
mov si, loaded ; we have successfully loaded the data
|
||||||
mov al, 0x01 ; Read one sector
|
call printstr
|
||||||
; Set CH, CL, DH for desired sector location (e.g., first sector)
|
jmp halt ; this will be jmp 0x1000:0x0000
|
||||||
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
|
|
||||||
|
|
||||||
int 13h ; Raise BIOS interrupt for disk read
|
fddload_err:
|
||||||
|
call printstr ; print
|
||||||
|
jmp halt ; and die
|
||||||
|
|
||||||
; Check Carry flag for error handling
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
jc harddrive_not_found ; Jump if Carry flag is set (potential error)
|
; 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
|
||||||
|
|
||||||
; Hard drive likely present (further processing can occur)
|
|
||||||
|
|
||||||
; ... (rest of your bootloader code)
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
; halt routine - infinite loop ;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
halt:
|
||||||
|
cli
|
||||||
|
jmp halt
|
||||||
|
|
||||||
harddrive_not_found:
|
;;;;;;;;;;;
|
||||||
; Handle error condition (missing drive or other issue)
|
; 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
|
||||||
|
|
||||||
; ... (error handling logic)
|
;;;;;;;;;;;;;;;;;;
|
||||||
|
; BIOS signature ;
|
||||||
memory_error:
|
;;;;;;;;;;;;;;;;;;
|
||||||
; ... (error handling or continue with limited memory)
|
dw 0xAA55
|
||||||
|
|
||||||
; 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
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
int 13h ; Raise BIOS interrupt for disk read
|
|
||||||
|
|
||||||
; 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
|
|
||||||
|
@ -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:
|
start:
|
||||||
; Initialize stack
|
xor ax, ax ; set up segment registers to segment 0 since
|
||||||
MOV AX, 0x0000 ; Set up a segment for the stack
|
mov ds, ax ; our addresses are already relative to 0x8000
|
||||||
MOV SS, AX
|
mov es, ax
|
||||||
MOV SP, 0xFFFF ; Stack grows downwards from the top of the segment
|
|
||||||
|
|
||||||
; Copy boot sector data to a safe location
|
mov si, kername ; print kernel file name
|
||||||
call mCopyBootSector
|
call printstr
|
||||||
; Load the kernel
|
|
||||||
CALL load_kernel
|
|
||||||
|
|
||||||
switch_to_protected_mode:
|
; Load the kernel into memory
|
||||||
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
|
|
||||||
|
|
||||||
enable_a20:
|
; Set up GDT, IDT, IVT
|
||||||
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
|
|
||||||
|
|
||||||
; Wait for keyboard controller to be ready
|
; Switch to protected mode
|
||||||
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
|
|
||||||
|
|
||||||
; Enter kernel space and jump to the kernel entry point
|
; Set up stack and start executing kernel's code
|
||||||
JMP 0x1000:0x0000
|
; ...
|
||||||
|
|
||||||
; Code to set up flat memory model for protected mode
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
; This involves setting up the segment registers with selectors
|
; printstr routine, prints the string pointed by si using int 0x10 ;
|
||||||
; that point to descriptors in the GDT that define a flat memory model
|
; 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 ;
|
||||||
; Placeholder instruction to satisfy NASM
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
dummy_instruction DB 0x90 ; NOP instruction as a placeholder
|
halt:
|
||||||
|
|
||||||
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
|
cli
|
||||||
|
jmp halt
|
||||||
|
|
||||||
; Setup disk parameters
|
;;;;;;;;;;;
|
||||||
; ... (set CH, CL, DH, DL for LBA, set DX for drive number)
|
; 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
|
||||||
|
|
||||||
; Calculate load address for kernel
|
;;;;;;;;;;;;;;;;;;
|
||||||
; ... (set ES:BX to the target memory address)
|
; BIOS signature ;
|
||||||
|
;;;;;;;;;;;;;;;;;;
|
||||||
; Read sectors from disk into memory
|
dw 0xAA55
|
||||||
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
|
|
||||||
|
Loading…
Reference in New Issue
Block a user