Last bit for the day, the current linker script hack:
Code: Select all
OUTPUT_FORMAT("elf64-x86-64")
ENTRY("_start")
SECTIONS {
. = ALIGN(0x1000);
.init 0xFFFFFFFFD0000000 : AT(0x90000) {
*(.init*)
init_ctors_begin = .;
*(.ctors)
init_ctors_end = .;
}
. = ALIGN(0x1000);
.text 0xFFFFFFFFC0000000 : AT(0x100000) {
*(.text*)
*(.rodata)
}
. = ALIGN(0x1000);
.data 0xFFFFFFFFC4000000 : AT(0x100000 + SIZEOF(.text)) {
*(.data)
*(COMMON)
kernel_max_mem = .;
}
.bss (ADDR(.data) + SIZEOF(.data)) : AT(LOADADDR(.data) + SIZEOF(.data)) {
*(.bss)
}
/DISCARD/ : {
*(.eh_frame)
*(.fini*)
*(.dtors)
*(_Z*)
*(.comment)
}
}
The output of objdump -p
Code: Select all
disk/kernel/kernel.x86_64-pc-elf
disk/kernel/kernel.x86_64-pc-elf: file format elf64-x86-64
Program Header:
LOAD off 0x0000000000000000 vaddr 0xffffffffcff00000 paddr 0xfffffffffff90000 align 2**20
filesz 0x00000000001000a0 memsz 0x00000000001000a0 flags rwx
LOAD off 0x0000000000200000 vaddr 0xffffffffc0000000 paddr 0x0000000000100000 align 2**20
filesz 0x0000000000006273 memsz 0x0000000000006273 flags r-x
LOAD off 0x0000000000300000 vaddr 0xffffffffc4000000 paddr 0x0000000000106273 align 2**20
filesz 0x0000000000000048 memsz 0x0000000000003210 flags rw-
I strongly suspect (almost know for sure) that it's ending up with these addresses because it's somehow wanted to align the segments on megabyte boundaries (as seen in the last bit) and that it should have the lowest 20 bits identical with the virtual address (which is, in theory, good). The problem is that I can't figure out why it is aligning stuff on megabyte boundaries, nor how I can convince it to align on, say, 4-kilobyte boundaries. I've tried to use something called BLOCK too, but that didn't appear to help (error when adding it as loose value, causing lots of relocation overflows when added to the address).
I'm using GCC 4.1.1 crosscompiled for the x86_64-pc-elf target. No special options were given to the linker. The compiler output is aligned, max, to 12 bits (which is the gdt in the bss section). I'm compiling with the following ccflags:
Code: Select all
CCFLAGS = -mtune=nocona -m64 -mcmodel=kernel -fno-exceptions -Iinclude -fshort-enums -Wno-long-long -fno-rtti -std=gnu++98 -Wall -Werror -Wextra -pedantic -pedantic-errors
.
The compile should be for my machine (just a tryout whether that helped - didn't), 64-bit (same), kernel-model (helped with relocations, not much with the rest). The rest are for the compiler to shout at me as much as it can and to not use some stupid default values (kernel needs no exceptions, no rtti, I need my includes, I want short enums as per the standard and I don't care that c++ doesn't have long longs, I need them).