nullplan wrote:What you describe is indicative of the .rodata section not being stored or linked correctly. Investigate where it is in your kernel file. Maybe you aren't loading enough sectors? I certainly heard of that before.
I know I'm loading enough sectors I have this for my loader code that happens while still in real mode:
Code: Select all
; start putting in values:
mov ah, 2h ; int13h function 2
mov al, 50 ; we want to read a lot of sectors I guess. 50 * 512 = ~25kb = a lot
mov ch, 0 ; from cylinder number 0
mov cl, 2 ; the sector number 2 - second sector (starts from 1, not 0)
mov dh, 0 ; head number 0
xor bx, bx
mov es, bx ; es should be 0
mov bx, 7e00h ; 512bytes from origin address 7e00h
int 13h
512*50 + 0x7e00= 0xE200 which *should* work since it's not copying more than 64kb.
One of the few things I haven't yet exhausted every possible thing I can possibly try is the way it links.
Now I had a lot of problems getting makefiles and linking to actually work. I wasn't able to get anything to compile using my own intuition. I wasn't able to get anything to work from looking at "working" examples either. I had to basically make a script that has g++ compile it into a standalone file, compile the assembly separately with nasm into a standalone file and then combine those 2 files together. This isn't the same as that elf and link.ld business everyone else does but it makes everything except string literals work which is more than any of my attempts at using elfs and the ld linker was able to achieve.
My compile script is:
Code: Select all
g++ -march=i486 -m32 -nostartfiles -ffreestanding -nostdlib -nolibc -nodefaultlibs -Ttext 0x7e00 system.cpp -o system
objcopy -O binary -j .text system system.raw
nasm bootloader.asm -o bootloader.bin
cat system >> bootloader.bin
This does introduce the problem of rodata indeed not getting compiled. I can get rodata with "objcopy -O binary -j .rodata system system_rodata.raw" of course but it's essentially useless because gcc has a special place in memory ro data is supposed to go and copying it to bootloader.bin with cat doesn't put it in the right place. There doesn't seem to be a easy way to make g++ put rodata where you want like you can with the text block via the "-Ttext 0x7e00" parameter.
From what i've gathered, possibly the only way to specify where ro data goes is with a linker script. Unfortunately, I cannot for the life of me get ld or link.ld scripts to work for some reason.
I've tried using a linker script with something like:
Code: Select all
g++ -march=i486 -m32 -nostartfiles -ffreestanding -nostdlib -nolibc -nodefaultlibs -Tlink.ld system.cpp -o system
nasm bootloader.asm -o bootloader.bin
cat system.raw >> bootloader.bin
with a link.ld of
Code: Select all
OUTPUT_FORMAT("elf32-i386")
ENTRY(begin)
SECTIONS
{
. = 0x7e00;
.text BLOCK(8K) : ALIGN(4K)
{
*(.text)
}
.rodata BLOCK(4K) : ALIGN(4K)
{
*(.rodata)
}
.data BLOCK(4K) : ALIGN(4K)
{
*(.data)
}
.bss BLOCK(4K) : ALIGN(4K)
{
*(.bss)
}
end = .;
}
but it never links correctly enough to even boot. I've tried fidgeting around, trying stuff some other projects on the internet and extensively trying all kinds of different command line parameters in the man pages but the best I can ever get is an error of
warning: cannot find entry symbol lf_i386; defaulting to 0000000000008000
. Copying this to memory location 0x8000 doesn't allow it to boot, naming a function "lf_i386" anywhere in my c++ code doesn't fix it, trying something like ".lf_i386 = 0x7e00" in the linker file doesn't fix it and that's about all the things there are to try.
What can I do to make a link.ld script actually work and potentially solve my rodata string problems?