multiboot stuff

This commit is contained in:
quackerd 2019-12-07 03:54:18 -05:00
parent 18830d645a
commit 4424d6401e
Signed by: d
GPG Key ID: 590A22374D0B819F
15 changed files with 269 additions and 194 deletions

View File

@ -36,7 +36,7 @@ set(CC_FLAGS
-std=c17
-c
-g
-Og
-O0
-Wall
-Wextra
-Wpedantic
@ -55,6 +55,7 @@ set(LD_FLAGS
-fuse-ld=${LD}
-nostdlib
-Wl,--fatal-warnings
-Wl,--build-id=none
${LD_FLAGS_${ARCH}})
set(PP_FLAGS
@ -92,7 +93,7 @@ set(TARGET ${proj}_elf)
set(OBJ_${TARGET} ${CMAKE_CURRENT_BINARY_DIR}/${proj}.elf)
add_custom_command(
OUTPUT ${OBJ_${TARGET}}
DEPENDS ${TARGETS}
DEPENDS ${TARGETS} ${OBJS}
COMMAND ${CC} ${LD_FLAGS} -Wl,-T, ${SCRIPT_LD} -o ${OBJ_${TARGET}} ${OBJS})
add_custom_target(${TARGET} ALL
@ -105,7 +106,7 @@ set(OBJ_${TARGET} ${CMAKE_CURRENT_BINARY_DIR}/${proj}.dmp)
add_custom_command(
OUTPUT ${OBJ_${TARGET}}
DEPENDS ${proj}_elf
DEPENDS ${proj}.elf
COMMAND ${DMP} ${DMP_FLAGS} ${OBJ_${proj}_elf} > ${OBJ_${TARGET}}
)
add_custom_target(${proj}_dmp ALL
@ -118,7 +119,7 @@ set(OBJ_${TARGET} ${CMAKE_CURRENT_BINARY_DIR}/${proj}.iso)
add_custom_command(
OUTPUT ${OBJ_${TARGET}}
DEPENDS ${proj}_elf ${TARGET_scripts}
DEPENDS ${proj}.elf
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/tmp_iso
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/tmp_iso/boot
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/tmp_iso/boot/grub

View File

@ -1,7 +1,7 @@
set(SUBMODULE arch)
set(CC_SRC
cpu.c
init.c
main.c
intr.c
mem.c
print.c

View File

@ -1,58 +1,81 @@
#define ASM_FILE
#include <arch/mlayout.h>
#include "multiboot2.h"
%define GET_PADDR(x) ((x) - KERNEL_IMG_VADDR)
%define BOCHS_BREAK xchg bx, bx
%define GET_PADDR(x) ((x) - KERN_BASE_START)
%define GET_PML4(vaddr) (((vaddr) >> 39 ) & 0x1FF)
%define GET_PDPT(vaddr) (((vaddr) >> 30 ) & 0x1FF)
%define GET_PDE(vaddr) (((vaddr) >> 21 ) & 0x1FF)
; make arch_init_32 visiable
global arch_init_32
; arch_main is the C long mode entry point
extern arch_main
section .text
bits 32
; the bootloader calls this dude, we switch to long mode with some basic setup:
; Identity map the first 4G memory, where the kernel binary and multiboot info is
; Map the first 4G memory to KERN_PMAP temporarily so we have access to printf
; Map the first 1G memory, which contains the kernel, to KERN_BASE_START
arch_init_32:
cli
cld
cmp eax, MULTIBOOT2_BOOTLOADER_MAGIC
jne .end
cli ; close interrupt
cld ; set direction
cmp eax, MULTIBOOT2_BOOTLOADER_MAGIC ; compare with multiboot2 magic
jne .end ; if not loaded by multiboot2 compliant bootloader, loop infinitely
BOCHS_BREAK
; save multiboot info
mov dword [GET_PADDR(multiboot_info_ptr)], ebx
; setup stack
call check_long_mode ; check support for long mode
cmp eax, 1
jne .end
; disable paging first
mov eax, cr0 ; Set the A-register to control register 0.
and eax, ~(1 << 31) & 0xFFFFFFFF ; Clear the PG-bit, which is bit 31, and hack to get rid of warning
mov cr0, eax ; Set control register 0 to the A-register.
; identity map the first 4G page
mov eax, GET_PADDR(kern_early_pml4)
add eax, GET_PML4(0) * 8 ; eax = offset of pml4e in pml4 for the 0th GB
mov dword [eax], GET_PADDR(kern_early_ident_pdpt) + 11b ; let the corresponding pml4e point to the kern_early_ident_pdpt
mov eax, GET_PADDR(kern_early_ident_pdpt)
add eax, GET_PDPT(0) * 8
mov ebx, 10000011b ; ebx lower bits is attribute = R/W + SU + 1G page, high bits = physical 0th GB
mov ecx, 4 ; 4 times = 4GB
.l0:
mov dword [eax], ebx ; set the corresponding pdpte to map 1GB pages in ebx
add ebx, 1*1024*1024*1024 ; add another 1G to ebx higher bits
add eax, 8 ; increment to next pdpte
loop .l0
; map the first 4G to pmap
mov eax, GET_PADDR(kern_early_pml4)
add eax, GET_PML4(KERN_PMAP_START) * 8 ; eax = offset of pml4e in pml4 for PMAP region
mov dword [eax], GET_PADDR(kern_early_pmap_pdpt) + 11b ; let the corresponding pml4e point to the kern_early_pmap_pdpt
mov eax, GET_PADDR(kern_early_pmap_pdpt)
add eax, GET_PDPT(KERN_PMAP_START) * 8
mov ebx, 10000011b ; ebx lower bits is attribute = R/W + SU + 1G page, high bits = physical 0th GB
mov ecx, 4 ; 4 times = 4GB
.l1:
mov dword [eax], ebx ; set the corresponding pdpte to map 1GB pages in ebx
add ebx, 1*1024*1024*1024 ; add another 1G to ebx higher bits
add eax, 8 ; increment to next pdpte
loop .l1
; map the first 1G to kern_base
; point the first PML4 entry to the identity pdpt
mov eax, GET_PADDR(init_pml4)
mov dword [eax], GET_PADDR(init_pdpt_iden) + 11b ; write the lower bits, higher = 0
; point the nth PML4 entry to the kernel pdpt
add eax, GET_PML4(KERNEL_SPACE_VADDR) * 8
mov dword [eax], GET_PADDR(init_pdpt_kern) + 11b
mov eax, GET_PADDR(kern_early_pml4)
add eax, GET_PML4(KERN_BASE_START) * 8
mov dword [eax], GET_PADDR(kern_early_img_pdpt) + 11b ; let the corresponding pml4e point to the kern_early_img_pdpt
; identity map the first 4GB
mov eax, GET_PADDR(init_pdpt_iden)
mov ebx, 10000011b ; R/W + SU + 1G page
mov ecx, 4 ; loop 4 times
.l0:
mov dword [eax], ebx
add ebx, 1*1024*1024*1024 ; 1G
add eax, 8
loop .l0
mov eax, GET_PADDR(kern_early_img_pdpt)
add eax, GET_PDPT(KERN_BASE_START) * 8
mov dword [eax], 10000011b ; ebx lower bits is attribute = R/W + SU + 1G page, high bits = physical 0th GB
; map the first 1 GB, which contains the kernel, to KERNEL_BASE_VADDR
mov eax, GET_PADDR(init_pdpt_kern)
; extract the PML4 entry
add eax, GET_PDPT(KERNEL_SPACE_VADDR) * 8
mov ebx, 10000011b ; R/W + SU + 1G page
mov dword [eax], ebx
BOCHS_BREAK
; enable PAE
mov eax, cr4 ; Set the A-register to control register 4.
@ -66,56 +89,25 @@ arch_init_32:
wrmsr ; Write to the model-specific register.
; let cr3 point at page table
mov eax, GET_PADDR(init_pml4)
mov eax, GET_PADDR(kern_early_pml4)
mov cr3, eax
xchg bx, bx
; enable paging, enter compatibility mode
mov eax, cr0 ; Set the A-register to control register 0.
or eax, 1 << 31 ; Set the PG-bit, which is bit 31.
mov cr0, eax ; Set control register 0 to the A-register.
; now we are in compat mode
; load the long mode GDT
lgdt [GET_PADDR(init_gdt.ptr)]
lgdt [GET_PADDR(kern_early_gdt.ptr)]
; switch to long mode
jmp init_gdt.code:GET_PADDR(arch_init_64)
jmp kern_early_gdt.code:GET_PADDR(arch_init_64)
; should not reach this point
.end:
jmp $
check_long_mode:
push ebp
mov ebp,esp
pushfd
pop eax
mov ecx, eax
xor eax, 1 << 21
push eax
popfd
pushfd
pop eax
push ecx
popfd
xor eax, ecx
jz .not_supported
mov eax, 0x80000000 ; Set the A-register to 0x80000000.
cpuid ; CPU identification.
cmp eax, 0x80000001 ; Compare the A-register with 0x80000001.
jb .not_supported ; It is less, there is no long mode.
mov eax, 0x80000001 ; Set the A-register to 0x80000001.
cpuid ; CPU identification.
test edx, 1 << 29 ; Test if the LM-bit, which is bit 29, is set in the D-register.
jz .not_supported ; They arent, there is no long mode.
mov eax,1
jmp .end
.not_supported:
xor eax,eax
.end:
mov esp,ebp
pop ebp
ret
section .data
bits 32
multiboot_info_ptr:
@ -130,7 +122,7 @@ arch_init_64:
jmp rax
.high:
; set proper segment registers
mov ax,init_gdt.data
mov ax,kern_early_gdt.data
mov ds,ax
mov es,ax
mov fs,ax
@ -138,49 +130,53 @@ arch_init_64:
mov ss,ax
; initial kernel stack, 4k
mov rsp, init_stack
mov rsp, kern_early_stack
xor rdi, rdi
mov edi, dword [multiboot_info_ptr]
; init arch
call arch_main
.end:
hlt
; should not reach this point
jmp $
section .data
bits 64
align KERNEL_PAGE_SIZE
times KERNEL_PAGE_SIZE db 0
init_stack:
align 0x1000
times KERN_PAGE_SZ db 0
kern_early_stack:
init_pml4:
align KERNEL_PAGE_SIZE
times KERNEL_PAGE_SIZE db 0
align 0x1000
kern_early_pml4:
times 0x1000 db 0
init_pdpt_iden:
align KERNEL_PAGE_SIZE
times KERNEL_PAGE_SIZE db 0
align 0x1000
kern_early_ident_pdpt:
times 0x1000 db 0
init_pdpt_kern:
align KERNEL_PAGE_SIZE
times KERNEL_PAGE_SIZE db 0
align 0x1000
kern_early_pmap_pdpt:
times 0x1000 db 0
init_gdt: ; Global Descriptor Table (long mode).
.null: equ $ - init_gdt ; The null descriptor.
align 0x1000
kern_early_img_pdpt:
times 0x1000 db 0
kern_early_gdt: ; Global Descriptor Table (long mode).
.null: equ $ - kern_early_gdt ; The null descriptor.
dw 0 ; Limit (low).
dw 0 ; Base (low).
db 0 ; Base (middle)
db 0 ; Access.
db 0 ; Granularity.
db 0 ; Base (high).
.code: equ $ - init_gdt ; The code descriptor.
.code: equ $ - kern_early_gdt ; The code descriptor.
dw 0 ; Limit (low).
dw 0 ; Base (low).
db 0 ; Base (middle)
db 10011010b ; Access (exec/read).
db 00100000b ; Granularity.
db 0 ; Base (high).
.data: equ $ - init_gdt ; The data descriptor.
.data: equ $ - kern_early_gdt ; The data descriptor.
dw 0 ; Limit (low).
dw 0 ; Base (low).
db 0 ; Base (middle)
@ -189,5 +185,5 @@ init_gdt: ; Global Descriptor Table (long mode).
db 0 ; Base (high).
.ptr:
; GDT PTR
dw $ - init_gdt - 1 ; Limit.
dq GET_PADDR(init_gdt) ; Base.
dw $ - kern_early_gdt - 1 ; Limit.
dq GET_PADDR(kern_early_gdt) ; Base.

View File

@ -1,71 +0,0 @@
#include <kern/cdef.h>
#include <kern/print.h>
#include <arch/print.h>
#include <arch/brute.h>
// private headers
#include "multiboot2.h"
void arch_main(ATTR_UNUSED void* mb_info)
{
/* init printf related stuff */
arch_print_init();
kprintf("Initializing arch layer...\n");
arch_brute();
/* if (mb_info == NULL)
{
goto err;
}
char *cur_ptr = (char *) mb_info + 8;
char *bootloader_name = NULL;
while (1)
{
struct multiboot_tag *cur_tag = (struct multiboot_tag *) cur_ptr;
switch (cur_tag->type)
{
case MULTIBOOT_TAG_TYPE_MMAP:
hal_mem_init((struct multiboot_tag_mmap*) cur_ptr);
break;
case MULTIBOOT_TAG_TYPE_FRAMEBUFFER:
hal_print_init((struct multiboot_tag_framebuffer *) cur_ptr);
break;
case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME:
bootloader_name = ((struct multiboot_tag_string*)cur_ptr)->string;
break;
case MULTIBOOT_TAG_TYPE_ACPI_NEW:
default:
break;
}
if (cur_tag->type == MULTIBOOT_TAG_TYPE_END)
{
break;
}
cur_ptr += cur_tag->size;
cur_ptr = (char *) ALIGN(uintptr, cur_ptr, 8);
}
hal_halt_cpu();
hal_printf("Boot loader:%d\n", bootloader_name);
struct boot_info *boot_info = halloc(sizeof(struct boot_info));
// // obtain cpu info
// halp_obtain_cpu_info(boot_info);
// init interrupt
if (hal_interrupt_init() != 0)
{
hal_halt_cpu();
}
kmain(boot_info);
err:
hal_halt_cpu(); */
}

47
arch/main.c Normal file
View File

@ -0,0 +1,47 @@
#include <kern/cdef.h>
#include <kern/print.h>
#include <arch/print.h>
#include <arch/brute.h>
// private headers
#include "multiboot2.h"
ATTR_USED void
arch_main(void *mb_info)
{
/* init printf related stuff */
arch_print_init();
kprintf("Multiboot info: 0x%p\n", mb_info);
kprintf("Initializing arch layer...\n");
for (struct multiboot_tag *tag = (struct multiboot_tag *) ((uintptr) mb_info + 8);
tag->type != MULTIBOOT_TAG_TYPE_END;
tag = (struct multiboot_tag *) ((multiboot_uint8_t *) tag
+ ((tag->size + 7) & ~7u))) {
kprintf("Tag 0x%p: %d, Size %d\n", (void *) tag, tag->type, tag->size);
switch (tag->type) {
case MULTIBOOT_TAG_TYPE_MMAP:
for (struct multiboot_mmap_entry *entry = ((struct multiboot_tag_mmap *) tag)->entries;
(multiboot_uint8_t *) entry < (multiboot_uint8_t *) tag + tag->size;
entry = (multiboot_memory_map_t *) ((uintptr) entry +
((struct multiboot_tag_mmap *) tag)->entry_size))
kprintf(" base_addr = 0x%lx,"
" length = 0x%lx, type = 0x%x\n",
(ulong) entry->addr,
(ulong) entry->len,
entry->type);
break;
case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME:
kprintf("BoND is loaded by: %s\n", ((struct multiboot_tag_string *) tag)->string);
break;
default:
kprintf("Unhandled multiboot tag type: %d\n", tag->type);
break;
}
}
kprintf("Arch layer initialized.\n");
arch_brute();
}

View File

@ -2,14 +2,11 @@
#include "multiboot2.h"
#include <arch/mlayout.h>
extern hmain
global hal_main_32
ASM_MULTIBOOT_CHECK_SUM equ (0xFFFFFFFF - (MULTIBOOT2_HEADER_MAGIC + ASM_MULTIBOOT_HEADER_SIZE + MULTIBOOT_ARCHITECTURE_I386) + 1)
section .multiboot_header
bits 32
align KERNEL_PAGE_SIZE
align 0x1000
;====================
align MULTIBOOT_HEADER_ALIGN
start_hdr:

View File

@ -16,6 +16,8 @@ static void
_fb_scroll()
{
memmove(base, base + FB_COL * BYTE_PER_CHAR, FB_SZ - (FB_COL * BYTE_PER_CHAR));
// clear the last line
memset(base + (FB_ROW - 1) * FB_COL * BYTE_PER_CHAR, 0, FB_COL * BYTE_PER_CHAR);
text_pos = FB_SZ - (FB_COL * BYTE_PER_CHAR);
}

57
bochsrc Normal file
View File

@ -0,0 +1,57 @@
# configuration file generated by Bochs
plugin_ctrl: unmapped=1, biosdev=1, speaker=1, extfpuirq=1, parallel=1, serial=1, iodebug=1
config_interface: textconfig
display_library: x, options="gui_debug"
memory: host=256, guest=256
romimage: file="/usr/share/bochs/BIOS-bochs-latest", address=0x0, options=none
vgaromimage: file="/usr/share/bochs/VGABIOS-lgpl-latest"
boot: cdrom
floppy_bootsig_check: disabled=0
# no floppya
# no floppyb
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-master: type=none
ata0-slave: type=cdrom, path="bond.iso", status=inserted, model="Generic 1234", biosdetect=auto
ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15
ata1-master: type=none
ata1-slave: type=none
ata2: enabled=0
ata3: enabled=0
optromimage1: file=none
optromimage2: file=none
optromimage3: file=none
optromimage4: file=none
optramimage1: file=none
optramimage2: file=none
optramimage3: file=none
optramimage4: file=none
pci: enabled=1, chipset=i440fx
vga: extension=vbe, update_freq=5, realtime=1
cpu: count=1:1:1, ips=4000000, quantum=16, model=bx_generic, reset_on_triple_fault=0, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0
cpuid: level=6, stepping=3, model=3, family=6, vendor_string="AuthenticAMD", brand_string="AMD Athlon(tm) processor"
cpuid: mmx=1, apic=x2apic, simd=sse2, sse4a=0, misaligned_sse=0, sep=1, movbe=0, adx=0
cpuid: aes=0, sha=0, xsave=0, xsaveopt=0, x86_64=1, 1g_pages=1, pcid=0, fsgsbase=0
cpuid: smep=0, smap=0, mwait=1
print_timestamps: enabled=0
debugger_log: -
magic_break: enabled=1
port_e9_hack: enabled=0
private_colormap: enabled=0
clock: sync=none, time0=local, rtc_sync=0
# no cmosimage
# no loader
log: -
logprefix: %t%e%d
debug: action=ignore
info: action=report
error: action=report
panic: action=ask
keyboard: type=mf, serial_delay=250, paste_delay=100000, user_shortcut=none
mouse: type=ps2, enabled=0, toggle=ctrl+mbutton
speaker: enabled=1, mode=system
parport1: enabled=1, file=none
parport2: enabled=0
com1: enabled=1, mode=null
com2: enabled=0
com3: enabled=0
com4: enabled=0

View File

@ -6,5 +6,5 @@
static inline void *
arch_pmap_map(uintptr paddr, ATTR_UNUSED usize size)
{
return (void*)(paddr + KERNEL_PMAP_VADDR);
return (void*)(paddr + KERN_PMAP_START);
}

View File

@ -3,14 +3,14 @@
/**
* Kernel Memory Layout
* ----------------------- 0x0000,0000,0000,0000 - User Space
* Application SIZE: 0x0000,8000,0000,0000 (256x PML4)
* Application SIZE: 0x0000,8000,0000,0000 (256x PML4, 128TB)
* ----------------------- 0x0000,8000,0000,0000
* Non-canonical
* ----------------------- 0xFFFF,8000,0000,0000 - Kernel Space
* PMAP SIZE: 0x0000,4000,0000,0000 (128x PML4)
* ----------------------- 0xFFFF,C000,0000,0000
* Kernel Dynamic SIZE: 0x0000,3000,0000,0000
* ----------------------- 0xFFFF,F000,0000,0000
* Unused
* ----------------------- 0xFFFF,9000,0000,0000
* PMAP SIZE: 0x0000,0400,0000,0000 (8x PML4, 4TB)
* ----------------------- 0xFFFF,9400,0000,0000
* Unused
* ----------------------- 0xFFFF,FFFF,8000,0000
* Kernel Image SIZE: 0x0000,0000,8000,0000 (2GB)
@ -18,17 +18,30 @@
**/
/**
* kernel loaded at physical address 16MB
* 0x1000000 = 16777216 = 16 * 1024 * 1024
* kernel loaded at physical address 32MB
* 0x2000000 = 2 * 16777216 = 2 * 16 * 1024 * 1024
*/
#define KERNEL_IMG_PADDR (0x1000000)
#define KERNEL_PAGE_SIZE (0x1000)
#ifdef ASM_FILE
#define KERNEL_SPACE_VADDR (0xFFFF800000000000)
#define KERNEL_PMAP_VADDR (0xFFFF800000000000)
#define KERNEL_PMAP_SIZE (0x0000400000000000)
#define KERNEL_DYN_VADDR (0xFFFFFF8000000000)
#define KERNEL_DYN_SIZE (0x0000300000000000)
#define KERNEL_IMG_VADDR (0xFFFFFFFF80000000)
#define KERNEL_IMG_SIZE (0x000000007FFFFFFF)
#define KERN_IMG_PADDR 0x2000000
#define KERN_PAGE_SZ 0x1000
#define KERN_PMAP_START 0xFFFF900000000000
#define KERN_PMAP_STOP 0xFFFF940000000000
#define KERN_BASE_START 0xFFFFFFFF80000000
#define KERN_BASE_STOP 0x0000000000000000
#else
#define KERN_IMG_PADDR (0x2000000)
#define KERN_PAGE_SZ (0x1000)
extern const char KERN_IMG_START[];
extern const char KERN_IMG_STOP[];
#define KERN_PMAP_START (0xFFFF900000000000)
#define KERN_PMAP_STOP (0xFFFF940000000000)
#define KERN_BASE_START (0xFFFFFFFF80000000)
#define KERN_BASE_STOP (0x0000000000000000)
#endif

View File

@ -35,3 +35,5 @@ typedef unsigned int uint;
#define ATTR_SECTION(x) __attribute__ ((section (#x)))
#define ATTR_ALIGN(x) _Alignas(x)
#define ATTR_FMT_PRINTF __attribute__((format (printf, 1, 2)))
#define BOCHS_BREAK __asm__("xchg %bx, %bx")

View File

@ -4,7 +4,7 @@
#include <kern/print.h>
ATTR_FMT_PRINTF int
kprintf(const char *str, ...);
kprintf(const char *fmt, ...);
int
kvprintf(const char *str, va_list args);
kvprintf(const char *fmt, va_list args);

View File

@ -16,6 +16,12 @@ _printu(char *buf, uintmax num, uint base, int cap)
char c;
len = 0;
if (num == 0) {
buf[0] = '0';
return 1;
}
while (num > 0) {
c = dtoa(num % base);
if (cap) {
@ -57,6 +63,7 @@ _vprintf(const char *fmt, va_list args)
switch (*fmt) {
case 'p':
sz_ptr = 1;
base = 16;
goto pnum;
case 'd':
goto pnum;
@ -120,10 +127,11 @@ _vprintf(const char *fmt, va_list args)
}
len = _printu(nbuf, num, base, capf);
while (len) {
arch_putc(nbuf[len]);
len--;
for(int i = len - 1; i >= 0; i--) {
arch_putc(nbuf[i]);
}
ret += len;
}
}

View File

@ -2,5 +2,7 @@ set timeout=0
set default=0
menuentry "bond" {
multiboot2 bond.elf
multiboot2 /bond.elf
set gfxpayload=text
boot
}

View File

@ -5,10 +5,31 @@ ENTRY(arch_init_32)
SECTIONS
{
. = KERNEL_IMG_VADDR + KERNEL_IMG_PADDR;
. = KERN_BASE_START + KERN_IMG_PADDR;
.multiboot_header ALIGN(KERNEL_PAGE_SIZE) : AT(ADDR(.multiboot_header) - KERNEL_IMG_VADDR)
KERN_IMG_START = .;
.multiboot_header ALIGN(0x1000) : AT(ADDR(.multiboot_header) - KERN_BASE_START)
{
*(.multiboot_header)
}
.text ALIGN(0x1000) : AT(ADDR(.text) - KERN_BASE_START)
{
*(.text)
}
.data ALIGN(0x1000) : AT(ADDR(.data) - KERN_BASE_START)
{
*(.data)
*(.rodata*)
}
.bss ALIGN(0x1000) : AT(ADDR(.bss) - KERN_BASE_START)
{
*(.bss)
*(COMMON)
}
KERN_IMG_STOP = .;
}