Linker script confuses physical and virtual addresses

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
restingwitchface
Posts: 18
Joined: Sat Nov 02, 2024 2:58 pm
GitHub: https://github.com/NyxNeptune

Linker script confuses physical and virtual addresses

Post by restingwitchface »

In my continuing of implementing paging for my kernel, I've decided to load .text at 0xc0000000, .rodata at 0xc0040000, .data at 0xc0080000 and .bss at 0xc00c0000. I have the following section in my linker script:

Code: Select all

.multiboot.text : ALIGN(4K)
{
	*(.multiboot.text)
	_mbtext_end = .;
	ASSERT(_mbtext_end < 0x202000, "Paging setup code exceeds page boundary!");
}

. = 0xC0000000;
_kernel_base = .;

.text ALIGN(4K) : AT (_mbtext_end)
{
	*(.text)
	*(.text.*)
	_text_end_virt = .;
	_text_end = _text_end_virt - 0xC0000000 + _mbtext_end;
}
[...]
When I test the linker script, QEMU significantly lags my computer. When I pass the image through

Code: Select all

nm
, I notice _text_end is 0xc020514b, which means QEMU was probably trying to allocate 3 GiB memory. How can this be? The values of _text_end_virt and _mbtext_end are 0xc000412e and 0x0020101d, so _text_end should be 0x20514b. Does LD somehow not respect operator precedence when calculating values?
she/her, please.

Don't flirt with me.
Oderint dum metuant.
GPG fingerprints:

Code: Select all

b16598566a5124946d87279fbc2d2dd299af811e (encryption)
b504ba54c5c164257156f53a32409b59258453e0 (signing)
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: Linker script confuses physical and virtual addresses

Post by Octocontrabass »

restingwitchface wrote: Mon Dec 09, 2024 11:52 amwhich means QEMU was probably trying to allocate 3 GiB memory.
QEMU uses the program headers to decide how to load your binary. Try "objdump -h" or "readelf -l" or "readelf -aW" to see the program headers.
restingwitchface wrote: Mon Dec 09, 2024 11:52 amDoes LD somehow not respect operator precedence when calculating values?
You're running into something funky with relative symbols. I'm not sure exactly what, but moving the definition of _text_end outside the .text section turns it into an absolute symbol that has the value you're expecting:

Code: Select all

    _text_end_virt = .;
}
_text_end = _text_end_virt - 0xC0000000 + _mbtext_end;
It seems like this behavior is for backwards-compatibility. The manual tries to explain it here.
Post Reply