I would, however, like to call some 32-bit C code from assembly while we're still in the lower half (kernel starts at 1MB) to initialize paging, load the gdt. This is presents a problem because said code is linked into the higher half of the kernel which results in an error. I tried to solve this by using GCC's section attribute to relocate the static variables and functions to a section in the lower half (1). Linking now succeeds, but the machine just triple faults and Bochs reports this error:
Code: Select all
bx_dbg_read_linear: physical memory read error (phy=0x000080101170, lin=0x0000000080101170)
Code: Select all
call paging_init
Code: Select all
lea paging_init, %eax
call *%eax
My ld script looks like this:
Code: Select all
VM_ADDR = 0xFFFFFFFF80000000;
SECTIONS
{
. = 0x100000;
.mboot ALIGN(4096) : {
*(.mboot)
. = ALIGN(4096);
}
.init ALIGN(4096) : {
*(.init)
*(.gdt)
}
. += VM_ADDR;
.text ALIGN(4096) : AT(ADDR(.text) - VM_ADDR) {
*(.text)
}
.data ALIGN(4096) : AT(ADDR(.data) - VM_ADDR) {
*(.data)
*(.rodata)
}
.bss ALIGN(4096) : AT(ADDR(.bss) - VM_ADDR) {
*(COMMON)
*(.bss)
}
/DISCARD/ : {
*(.eh_frame)
*(.comment)
}
}
Moving the section is done by prefixing this to functions:
Code: Select all
__attribute__ ((section(".init")))
(1) I can move the functions and variables to another section but I haven't found a way to give debugging information a new section, for now I'm just omitting 32-bit debug info using -g0. If you have a solution for this issue as well, that'd be awesome!
P.S. I don't like how my tabs (and tabs are 8 columns, mind you) are displayed as a mere 3 spaces on this forum.
EDIT: I've decided to get rid of the C code and just implement it in assembly. This works for me, though it'd still be nice to know how to tackle this problem in the future if (read when) it comes up again...