I'm quite sure that the problem occurs because the ELF is loaded incorrectly. I checked the most common other issues, like paging and stack, with internal bochs debugger, but I was unable to find any issues with them. I used memory watch points and single-stepped and it looks like 0x69 keeps getting copied instead of the required 0x00.
The ELF loader is written in assembly. It (partially) verifies ELF file located at 0xA000 and loads it to the point specified in the ELF file, 0x100000 in my case. It loads the file according to the instructions in the ELF wiki page.
I loop through all the program headers, and do the following:
- Test that type is 1 - load: if not, jump to next header
- Clear p_memsz bytes at p_vaddr to 0
- Copy p_filesz bytes from p_offset to p_vaddr
- Next header
Output from readelf -l looks like this:
Code: Select all
vagrant@vagrant-ubuntu-trusty-64:/vagrant$ readelf -l build/kernel.bin
Elf file type is EXEC (Executable file)
Entry point 0x100000
There are 2 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x00000000000000b0 0x0000000000100000 0x0000000000100000
0x000000000000b000 0x000000000005b000 RWE 10
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RWE 10
Section to Segment mapping:
Segment Sections...
00 .entry .text .rodata .data .bss
01
Code: Select all
mov rdi, [rbx + 16] ; p_vaddr
mov rcx, [rbx + 40] ; p_memsz
; Clear p_memsz bytes at p_vaddr to 0
.loop_clear:
mov byte [rdi], 0
inc rdi
loop .loop_clear
mov rsi, [rbx + 8] ; p_offset
add rsi, img_loc ; ELF image location (0xA000)
mov rdi, [rbx + 16] ; p_vaddr
mov rcx, [rbx + 32] ; p_filesz
rep movsb ; copy p_filesz bytes from p_offset to p_vaddr