Feat: CPU Exceptions and load errors are now shown.

This commit is contained in:
AfonsoCMSousa 2025-11-18 22:58:28 +00:00
parent c1068d34e2
commit 9e4224793b
7 changed files with 692 additions and 238 deletions

BIN
SoraOS

Binary file not shown.

257
boot.asm
View File

@ -1,221 +1,94 @@
; File: boot.asm ; File: boot.asm
[org 0x7c00] ; BIOS loads us at 0x7C00 ; Stage 1 Bootloader (Master Boot Record - exactly 512 bytes)
[bits 16] ; We start in 16-bit Real Mode ; Job: Load Stage 2 from disk and jump to it
[org 0x7c00]
[bits 16]
STAGE2_OFFSET equ 0x7e00 ; Load stage2 right after boot sector
start: start:
; Set up segments
xor ax, ax xor ax, ax
mov ds, ax mov ds, ax
mov es, ax mov es, ax
mov ss, ax mov ss, ax
mov sp, 0x7c00 mov sp, 0x7c00
; IMPORTANT: Save boot drive number (BIOS passes it in DL)
push dx
; Clear screen
mov ah, 0x00 mov ah, 0x00
mov al, 0x03 mov al, 0x03
int 0x10 int 0x10
mov si, real_msg ; Print loading message
mov si, msg_loading
call print_string call print_string
cli ; Load Stage 2 from disk
; Read 5 sectors (sectors 2-6) - gives us 2.5KB for Stage 2
pop dx ; Restore boot drive
push dx ; Save it again for stage 2
mov bx, STAGE2_OFFSET ; Destination
mov dh, 5 ; Number of sectors
; DL already has drive number
call load_disk
lgdt [gdt_descriptor] ; Jump to Stage 2 (DL still has boot drive number)
pop dx ; Pass drive number to stage 2 in DL
jmp STAGE2_OFFSET
; ============================================================
; LOAD DISK - Read sectors using BIOS INT 0x13
; ============================================================
load_disk:
push dx
mov eax, cr0 mov ah, 0x02 ; Read function
or eax, 0x1 mov al, dh ; Number of sectors
mov cr0, eax mov ch, 0 ; Cylinder 0
mov cl, 2 ; Start at sector 2
mov dh, 0 ; Head 0
int 0x13
jc disk_error
pop dx
cmp al, dh
jne disk_error
ret
; Far jump into 32-bit mode. disk_error:
jmp 0x08:init_pm mov si, msg_error
call print_string
jmp $
; --- Helper: Print String (BIOS INT 0x10) --- ; ============================================================
; PRINT STRING
; ============================================================
print_string: print_string:
pusha pusha
mov ah, 0x0e ; INT 0x10 "Teletype Output" function mov ah, 0x0e
.loop: .loop:
lodsb ; Load byte at [SI] into AL, increment SI lodsb
cmp al, 0 ; Check for null terminator test al, al
je .done jz .done
int 0x10 ; Call BIOS video interrupt int 0x10
jmp .loop jmp .loop
.done: .done:
popa popa
ret ret
real_msg: db '[REAL] - Loaded successfully.', 0x0D, 0x0A, 0 ; ============================================================
; DATA
; ============================================================
msg_loading: db '[STAGE1] Loading SoraOS...', 0x0D, 0x0A, 0
msg_error: db '[ERROR] Disk read failed!', 0x0D, 0x0A, 0
; --- GDT (Global Descriptor Table) --- ; ============================================================
align 8 ; BOOT SIGNATURE
gdt_start: ; ============================================================
gdt_null:
dq 0x0
gdt_code32: ; 32-bit code segment (selector 0x08)
dw 0xffff ; Limit 0:15
dw 0x0000 ; Base 0:15
db 0x00 ; Base 16:23
db 10011010b ; Access: present, ring 0, code, executable, readable
db 11001111b ; Flags: 4KB granularity, 32-bit | Limit 16:19
db 0x00 ; Base 24:31
gdt_data32: ; 32-bit data segment (selector 0x10)
dw 0xffff
dw 0x0000
db 0x00
db 10010010b ; Access: present, ring 0, data, writable
db 11001111b
db 0x00
gdt_code64: ; 64-bit code segment (selector 0x18)
dw 0xffff
dw 0x0000
db 0x00
db 10011010b ; Access: present, ring 0, code, executable, readable
db 10101111b ; Flags: 4KB granularity, 64-bit, limit 16:19
db 0x00
gdt_data64: ; 64-bit data segment (selector 0x20)
dw 0xffff
dw 0x0000
db 0x00
db 10010010b
db 10101111b
db 0x00
gdt_end:
gdt_descriptor:
dw gdt_end - gdt_start - 1
dd gdt_start
; ==================================================
; 32-BIT PROTECTED MODE
; ==================================================
[bits 32]
init_pm:
; Set up segments
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov esp, 0x90000
; Print message in Protected Mode
; Print to VGA memory
mov edi, 0xb8000
mov al, 'P'
mov ah, 0x0f
mov [edi], ax
add edi, 2
mov al, 'M'
mov [edi], ax
add edi, 2
mov al, '3'
mov [edi], ax
add edi, 2
mov al, '2'
mov [edi], ax
; Set up page tables for identity mapping first 2MB
; PML4[0] -> PDPT
mov edi, 0x1000
mov dword [edi], 0x2003 ; Present, Writable, points to 0x2000
add edi, 4
mov dword [edi], 0
; PDPT[0] -> PD
mov edi, 0x2000
mov dword [edi], 0x3003 ; Present, Writable, points to 0x3000
add edi, 4
mov dword [edi], 0
; PD[0] -> 2MB page at physical 0x0
mov edi, 0x3000
mov dword [edi], 0x83 ; Present, Writable, Page Size (2MB)
add edi, 4
mov dword [edi], 0
; Load CR3 with PML4 address
mov eax, 0x1000
mov cr3, eax
; Enable PAE (Physical Address Extension)
mov eax, cr4
or eax, 0x20
mov cr4, eax
; Enable Long Mode in EFER MSR
mov ecx, 0xC0000080
rdmsr
or eax, 0x100
wrmsr
; Enable Paging (activates Long Mode)
mov eax, cr0
or eax, 0x80000000
mov cr0, eax
; Far jump to 64-bit code
jmp 0x18:long_mode_start
jmp $
; --- 64-bit Long Mode ---
[bits 64]
long_mode_start:
; Set up segments (most are ignored in 64-bit mode)
mov ax, 0x20
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
; Set up stack
mov rsp, 0x90000
; Clear screen and print "SORA OS 64"
mov rdi, 0xb8000
mov rcx, 80*25
mov ax, 0x0f20 ; White space
rep stosw
; Print message
mov rdi, 0xb8000
mov rsi, long_msg
call print_string_64
; Hang
jmp $
; --- 64-bit Print String ---
print_string_64:
mov ah, 0x0f ; White on black
.loop:
lodsb
test al, al
jz .done
stosw ; Write character + attribute
jmp .loop
.done:
ret
long_msg: db 'SoraOS 64-BIT', 0
; --- The Magic Boot Sector Footer ---
; Fill the rest of the 512 bytes with zeros
times 510-($-$$) db 0 times 510-($-$$) db 0
; The BIOS signature (must be at the very end)
dw 0xAA55 dw 0xAA55
section .bss
align 4096
pml4_table:
resb 4096
pdpt_table:
resb 4096
pd_table:
resb 4096

View File

@ -1,12 +1,71 @@
#!/bin/sh #!/bin/bash
export PATH=/usr/local/cross/bin:$PATH # Complete build script for SoraOS with 2-stage bootloader
# 1. Assemble raw binary set -e # Exit on any error
echo ">>> Assembling boot.asm to boot.bin..."
echo "==================================="
echo " SoraOS Build System v1.0"
echo "==================================="
# Colors
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Step 1: Assemble Stage 1 bootloader (MBR - 512 bytes)
echo -e "${BLUE}[1/6]${NC} Assembling Stage 1 bootloader (MBR)..."
nasm -f bin boot.asm -o boot.bin nasm -f bin boot.asm -o boot.bin
# 2. Run QEMU as a raw disk drive # Step 2: Assemble Stage 2 bootloader (extended loader)
echo ">>> Running QEMU with boot.bin..." echo -e "${BLUE}[2/6]${NC} Assembling Stage 2 bootloader..."
qemu-system-x86_64 -drive format=raw,file=boot.bin nasm -f bin elevator.asm -o elevator.bin
echo "Done!" # Step 3: Assemble kernel entry point
echo -e "${BLUE}[3/6]${NC} Assembling kernel entry..."
nasm -f elf64 kernel.asm -o kernel.asm.o
# Step 4: Compile kernel C code
echo -e "${BLUE}[4/6]${NC} Compiling kernel..."
gcc -ffreestanding -c kernel.c -o kernel.c.o -mcmodel=large -mno-red-zone -fno-pic -fno-pie -static -fno-stack-protector -nostdlib -mno-mmx -mno-sse -mno-sse2 -m64
# Step 5: Link kernel
echo -e "${BLUE}[5/6]${NC} Linking kernel..."
ld -T linker.ld -o kernel.bin kernel.asm.o kernel.c.o --oformat binary
# Step 6: Create OS image
echo -e "${BLUE}[6/6]${NC} Creating OS image..."
cat boot.bin elevator.bin kernel.bin > os-image.bin
# Pad to floppy size (1.44MB)
truncate -s 1440K os-image.bin
echo ""
echo -e "${GREEN}✓ Build complete!${NC}"
echo ""
echo "==================================="
echo "File Layout:"
echo "==================================="
echo "Sector 1: Stage 1 (MBR)"
echo "Sectors 2-6: Stage 2 (Extended Bootloader)"
echo "Sectors 7+: Kernel"
echo ""
# Show sizes
echo "File Sizes:"
printf "%-15s %10s\n" "File" "Size"
printf "%-15s %10s\n" "----" "----"
printf "%-15s %10d bytes\n" "boot.bin" $(stat -f%z boot.bin 2>/dev/null || stat -c%s stage1.bin 2>/dev/null)
printf "%-15s %10d bytes\n" "elevator.bin" $(stat -f%z elevator.bin 2>/dev/null || stat -c%s stage2.bin 2>/dev/null)
printf "%-15s %10d bytes\n" "kernel.bin" $(stat -f%z kernel.bin 2>/dev/null || stat -c%s kernel.bin 2>/dev/null)
printf "%-15s %10d bytes\n" "os-image.bin" $(stat -f%z os-image.bin 2>/dev/null || stat -c%s os-image.bin 2>/dev/null)
echo ""
echo -e "${YELLOW}Running QEMU...${NC}"
echo "==================================="
echo "Press Ctrl+C to exit QEMU"
echo ""
qemu-system-x86_64 -drive format=raw,file=os-image.bin -no-reboot -d cpu_reset
echo -e "${GREEN}Done!${NC}"

490
elevator.asm Normal file
View File

@ -0,0 +1,490 @@
; File: elevator.asm
; Stage 2 Bootloader - No size limit!
; Job: Load kernel, set up GDT, switch to 64-bit mode, jump to kernel
[org 0x7e00]
[bits 16]
KERNEL_OFFSET equ 0x10000 ; Load kernel at 64KB (safer than 0x1000)
BOOT_DRIVE: db 0 ; Store boot drive number
ERROR_CODE: db 0 ; Store error code from disk read
stage2_start:
; Print stage 2 message
mov si, msg_stage2
call print_string
; Save boot drive number (passed from stage1 in DL)
mov [BOOT_DRIVE], dl
; Load kernel from disk
call load_kernel
; Verify kernel was loaded - check for signature
; Check if there's actual code at 0x10000
mov ax, 0x1000
mov es, ax
xor bx, bx
mov ax, [es:bx] ; Read first 2 bytes of kernel
; Show what we read (for debugging)
push ax
xor ax, ax
mov es, ax
mov si, msg_kernel_check
call print_string
pop ax
call print_hex_word ; Print the word we read
; If it's 0x0000, kernel didn't load
test ax, ax
jz kernel_load_failed
mov si, msg_kernel_ok
call print_string
; Disable interrupts
cli
; Load GDT
lgdt [gdt_descriptor]
; Enable Protected Mode
mov eax, cr0
or eax, 0x1
mov cr0, eax
; Far jump to 32-bit code
jmp 0x08:protected_mode
; ============================================================
; LOAD KERNEL FROM DISK
; ============================================================
load_kernel:
push ax
push bx
push cx
push dx
; Reset disk system first
mov ah, 0x00
mov dl, [BOOT_DRIVE]
int 0x13
; Set up ES:BX for the destination
; KERNEL_OFFSET is 0x10000, so we need ES=0x1000, BX=0x0000
mov ax, 0x1000
mov es, ax
xor bx, bx ; BX = 0, so ES:BX = 0x1000:0x0000 = 0x10000
; Now try loading kernel
mov ah, 0x02 ; Read function
mov al, 10 ; Number of sectors
mov ch, 0 ; Cylinder 0
mov cl, 7 ; Start at sector 7
mov dh, 0 ; Head 0
mov dl, [BOOT_DRIVE] ; Drive number
int 0x13
jc kernel_error
; Restore ES to 0
xor ax, ax
mov es, ax
pop dx
pop cx
pop bx
pop ax
ret
kernel_error:
; Restore ES
xor ax, ax
mov es, ax
; Save error code
mov byte [ERROR_CODE], ah
mov si, msg_kernel_error
call print_string
; Show error code
mov si, msg_error_code
call print_string
; Print error code as hex
mov al, [ERROR_CODE]
call print_hex
; Show drive number we tried to use
mov si, msg_drive
call print_string
mov al, [BOOT_DRIVE]
call print_hex
jmp $
kernel_load_failed:
xor ax, ax
mov es, ax
mov si, msg_verify_failed
call print_string
jmp $
; ============================================================
; PRINT STRING (16-bit)
; ============================================================
print_string:
pusha
mov ah, 0x0e
.loop:
lodsb
test al, al
jz .done
int 0x10
jmp .loop
.done:
popa
ret
; ============================================================
; PRINT HEX BYTE (for debugging)
; ============================================================
print_hex:
push ax
push bx
mov bl, al
shr al, 4 ; Get high nibble
call print_nibble
mov al, bl
and al, 0x0F ; Get low nibble
call print_nibble
pop bx
pop ax
ret
print_nibble:
cmp al, 9
jle .digit
add al, 7 ; Convert to A-F
.digit:
add al, '0'
mov ah, 0x0e
int 0x10
ret
; Print a 16-bit word as hex
print_hex_word:
push ax
mov al, ah ; Print high byte first
call print_hex
pop ax
call print_hex ; Print low byte
ret
; ============================================================
; MESSAGES
; ============================================================
msg_stage2: db '[STAGE2] Extended bootloader loaded', 0x0D, 0x0A, 0
msg_kernel_loaded: db '[STAGE2] Kernel loaded, switching to Protected Mode...', 0x0D, 0x0A, 0
msg_kernel_error: db '[ERROR] Kernel load failed!', 0x0D, 0x0A, 0
msg_kernel_check: db '[STAGE2] Verifying kernel load: Read word = 0x', 0
msg_kernel_ok: db '[STAGE2] Kernel load verified.', 0x0D, 0x0A, 0
msg_verify_failed: db '[ERROR] Kernel verification failed!', 0x0D, 0x0A, 0
msg_error_code: db ' Error code: 0x', 0
msg_drive: db ' Drive number: 0x', 0
; ============================================================
; GDT - Global Descriptor Table
; ============================================================
align 8
gdt_start:
gdt_null:
dq 0x0
gdt_code32: ; Selector 0x08
dw 0xffff
dw 0x0000
db 0x00
db 10011010b
db 11001111b
db 0x00
gdt_data32: ; Selector 0x10
dw 0xffff
dw 0x0000
db 0x00
db 10010010b
db 11001111b
db 0x00
gdt_code64: ; Selector 0x18
dw 0xffff
dw 0x0000
db 0x00
db 10011010b
db 10101111b
db 0x00
gdt_data64: ; Selector 0x20
dw 0xffff
dw 0x0000
db 0x00
db 10010010b
db 10101111b
db 0x00
gdt_end:
gdt_descriptor:
dw gdt_end - gdt_start - 1 ; Limit (size - 1)
dd gdt_start ; Base address (org already adjusts this)
; ============================================================
; 32-BIT PROTECTED MODE
; ============================================================
[bits 32]
protected_mode:
; Set up segments
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov esp, 0x90000
; Print to VGA
mov edi, 0xb8000
mov esi, pm_msg
call print_pm
; Clear page table area (12KB starting at 0x1000)
mov edi, 0x1000
mov ecx, 3072 ; 12KB / 4 bytes = 3072 dwords
xor eax, eax
rep stosd
; Set up page tables
; PML4[0] -> PDPT at 0x2000
mov dword [0x1000], 0x2003
; PDPT[0] -> PD at 0x3000
mov dword [0x2000], 0x3003
; Identity map first 4MB (two 2MB pages)
; PD[0] -> First 2MB
mov dword [0x3000], 0x00000083
mov dword [0x3004], 0x00000000
; PD[1] -> Second 2MB (covers 0x200000 - 0x3FFFFF)
mov dword [0x3008], 0x00200083
mov dword [0x300C], 0x00000000
; Load page table
mov eax, 0x1000
mov cr3, eax
; Enable PAE
mov eax, cr4
or eax, 0x20
mov cr4, eax
; Enable Long Mode
mov ecx, 0xC0000080
rdmsr
or eax, 0x100
wrmsr
; Enable Paging
mov eax, cr0
or eax, 0x80000000
mov cr0, eax
; Jump to 64-bit mode
jmp 0x18:long_mode
; Print in 32-bit protected mode
print_pm:
mov ah, 0x0f
.loop:
lodsb
test al, al
jz .done
stosw
jmp .loop
.done:
ret
pm_msg: db '[PM32] Setting up Long Mode...', 0
; ============================================================
; 64-BIT LONG MODE
; ============================================================
[bits 64]
long_mode:
; Set up segments
mov ax, 0x20
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov rsp, 0x90000
; Set up a minimal IDT to prevent triple faults
; Point all interrupts to a dummy handler
call setup_idt
; Print message on line 3
mov rdi, 0xb8000 + (160 * 2)
mov rsi, lm_msg
call print_64
; Write a marker before jumping to kernel (for debugging)
mov rdi, 0xb8000 + (160 * 3)
mov rsi, before_kernel_msg
call print_64
; JUMP TO KERNEL!
call KERNEL_OFFSET
; If kernel returns, show error
mov rdi, 0xb8000 + (160 * 4)
mov rsi, kernel_return_msg
call print_64
jmp $
; Set up a minimal IDT
setup_idt:
; Fill IDT with different handlers for different exceptions
mov rdi, 0x4000 ; IDT location
; Set up first 32 entries (CPU exceptions) with specific handlers
mov rcx, 32
mov rax, exception_handler
.fill_exceptions:
mov word [rdi], ax ; Offset low
mov word [rdi + 2], 0x18 ; Code segment
mov byte [rdi + 4], 0 ; IST
mov byte [rdi + 5], 0x8E ; Present, interrupt gate
shr rax, 16
mov word [rdi + 6], ax ; Offset middle
shr rax, 16
mov dword [rdi + 8], eax ; Offset high
mov dword [rdi + 12], 0 ; Reserved
mov rax, exception_handler ; Restore for next iteration
add rdi, 16
loop .fill_exceptions
; Fill remaining entries (32-255) with dummy handler
mov rcx, 224
mov rax, dummy_handler
.fill_rest:
mov word [rdi], ax
mov word [rdi + 2], 0x18
mov byte [rdi + 4], 0
mov byte [rdi + 5], 0x8E
shr rax, 16
mov word [rdi + 6], ax
shr rax, 16
mov dword [rdi + 8], eax
mov dword [rdi + 12], 0
mov rax, dummy_handler
add rdi, 16
loop .fill_rest
; Load IDT
lidt [idt_descriptor]
ret
; Exception handler - shows what went wrong
exception_handler:
; Save registers
push rax
push rbx
; Get exception number from stack
; (not perfectly accurate but good enough for debugging)
; Write "EXCEPTION!" in red at line 5
mov rbx, 0xb8000 + (160 * 5)
mov rax, 0x0C450C580C430C45 ; "ECXE" in red
mov [rbx], rax
mov rax, 0x0C4F0C490C540C50 ; "PTIO" in red
mov [rbx + 8], rax
mov word [rbx + 16], 0x0C21 ; "!" in red
; Show the instruction pointer where it failed
mov rax, [rsp + 16] ; Get RIP from stack (after our 2 pushes)
mov rbx, 0xb8000 + (160 * 6)
; Write "RIP: "
mov word [rbx], 0x0F52 ; 'R'
mov word [rbx + 2], 0x0F49 ; 'I'
mov word [rbx + 4], 0x0F50 ; 'P'
mov word [rbx + 6], 0x0F3A ; ':'
mov word [rbx + 8], 0x0F20 ; ' '
; Print RIP value as hex
mov rcx, 16
mov rbx, 0xb8000 + (160 * 6) + 10
.print_rip:
rol rax, 4
mov dl, al
and dl, 0x0F
cmp dl, 9
jle .digit
add dl, 7
.digit:
add dl, '0'
mov byte [rbx], dl
mov byte [rbx + 1], 0x0F
add rbx, 2
dec rcx
jnz .print_rip
; Restore and halt
pop rbx
pop rax
; Infinite loop instead of iretq
cli
hlt
jmp $
; Dummy interrupt handler for IRQs (not CPU exceptions)
dummy_handler:
iretq
idt_descriptor:
dw (256 * 16) - 1 ; Limit (256 entries * 16 bytes)
dq 0x4000 ; Base address
; Print in 64-bit mode
print_64:
mov ah, 0x0f
.loop:
lodsb
test al, al
jz .done
stosw
jmp .loop
.done:
ret
lm_msg: db '[64-BIT] Long mode active...', 0
before_kernel_msg: db '[64-BIT] Calling kernel...', 0
kernel_return_msg: db '[KERNEL] Returned unexpectedly!', 0

15
kernel.asm Normal file
View File

@ -0,0 +1,15 @@
; File: kernel.asm
; Assembly entry point for the kernel
[bits 64]
[extern kmain] ; kmain is defined in kernel.c
global _start ; Make _start visible to linker
_start:
; We're already in 64-bit mode with stack set up
; Just call the C kernel
call kmain
; If kmain returns, hang
jmp $

View File

@ -1,15 +1,42 @@
// file: kerlnel.c // File: kernel.c
// SoraOS Kernel - Main entry point
// Simple helper to write a character at a specific position
static inline void write_char(int row, int col, char c, unsigned char color) {
volatile unsigned short *vga = (volatile unsigned short *)0xB8000;
int pos = (row * 80) + col;
vga[pos] = (color << 8) | c;
}
// Simple helper to write a string
static void write_string(int row, int col, const char *str, unsigned char color) {
int i = 0;
while (str[i] != '\0') {
write_char(row, col + i, str[i], color);
i++;
}
}
// Clear the entire screen
static void clear_screen(void) {
volatile unsigned short *vga = (volatile unsigned short *)0xB8000;
int i;
for (i = 0; i < 80 * 25; i++) {
vga[i] = (0x00 << 8) | ' ';
}
}
void kmain(void) { void kmain(void) {
// Kernel main function // Clear screen
// Set VGA memory address clear_screen();
volatile unsigned short *VGA_mem = (unsigned short *)0xB8000;
// Write messages
VGA_mem[0] = (0x07 << 8) | 'S'; write_string(10, 30, "SORA OS KERNEL", 0x0A); // Green
VGA_mem[1] = (0x07 << 8) | 'O'; write_string(12, 25, "64-bit kernel running!", 0x0F); // White
VGA_mem[2] = (0x07 << 8) | 'R'; write_string(14, 28, "System Initialized", 0x0E); // Yellow
VGA_mem[3] = (0x07 << 8) | 'A';
VGA_mem[4] = (0x07 << 8) | ' '; // Infinite loop
VGA_mem[5] = (0x07 << 8) | 'O'; while (1) {
VGA_mem[6] = (0x07 << 8) | 'S'; __asm__ volatile ("hlt");
}
} }

View File

@ -1,36 +1,26 @@
/* Linker script for SoraOS kernel */
OUTPUT_FORMAT(binary) OUTPUT_FORMAT(binary)
ENTRY(_start) ENTRY(_start)
SECTIONS SECTIONS
{ {
/* Set the location counter to 0x100000 (1MB) */ /* Kernel loaded at 0x10000 (64KB) by stage2 bootloader */
. = 0x100000; . = 0x10000;
.multiboot : .text : {
{ *(.text)
KEEP(*(.multiboot)) }
}
/* Define the .text section at the current location */ .rodata : {
.text : *(.rodata)
{ }
/* Put all .text sections from all input files here */
*(.text)
}
/* Define the .data section immediately after .text */ .data : {
.data : *(.data)
{ }
/* Put all .data sections §from all input files here */
*(.data)
}
/* Define the .bss section immediately after .data */ .bss : {
.bss : *(.bss)
{ *(COMMON)
/* Put all .bss sections from all input files here */ }
*(.bss)
}
/* End of the linker script */
} }