By default ld
page-aligns input sections. Since your kernel enforces superpages (pages of 2MB = 0x200000 bytes) your .text
section gets aligned at offset 0x200000. It seems like a bug in ld
as it should use offset 0x0000000 instead (see EDIT below for a possible explanation)
To prevent this alignment which creates a bigger file, you can use the --nmagic
flag to ld to prevent it from page-aligning your .text section although it has side effects (it also disables linking against shared libraries). Be careful though to align other sections (.data
, .rodata
,...) to 2M pages because they can't live in the same page as .text since all these sections require different access bits.
EDIT: thinking about it, we all expect accesses to virtual address 0x00000000 to generate an exception (segfault). To do so, I see two possibilities: either the kernel maps a page with no access rights (r/w/x) or (more likely) it simply doesn't map anything (no page mapped => segfault) and the linker must know that somehow... that could explain why ld skips the first page which is at address zero. This is TBC.