The entry point point appears to be wrong and i have to minus 0x120 from it to get the thing to run. This i found out after hours with a hex editor and searching through the binary in memory finding out where the first opcode is. However this doesn't seem to be due to me loading the program segment to the wrong location, if I load the program segment 0x120 bytes earlier, the entry point is in the right place now but the code seems to be written to be in the former location so no longer works. So essentially the symbols seem to be 0x120 out and may have nothing to do with the loading of elf file at all but rather the linker.
Elf-loader (i'm aware that it might not work with multiple program section atm, but there's only one in my test kernel so that case hasn't been tested yet):
Code: Select all
uint32_t _loader_parse_elf() {
//Header information
Elf32_Ehdr *elf_header = (Elf32_Ehdr*) KERNEL_ELF;
//Loop through each program segment
Elf32_Phdr *program_header = (Elf32_Phdr*) (KERNEL_ELF + (elf_header->e_phoff/4));
for(uint_fast16_t i = 0; i < elf_header->e_phnum; i++) {
//Only parse loadable ones
if(program_header->p_type == 1) {
//Get info
uint8_t *src = (uint8_t*) (KERNEL_ELF + program_header->p_offset);
static uint8_t *dst = (uint8_t*) KERNEL_BUILT;
for(uint32_t i = 0; i < program_header->p_filesz; i++) *dst++ = *src++;
//TODO zero out BSS
//Page in the memory
_loader_page_memory((uint32_t*) KERNEL_BUILT, program_header->p_vaddr, program_header->p_memsz);
}
//Jump to next entry
program_header += elf_header->e_phentsize;
}
//Return entry point
return elf_header->e_entry;
}
Linker:
Code: Select all
/* link-arm-eabi.ld - linker script for arm eabi */
ENTRY(main)
SECTIONS
{
. = 0x80000000;
/* text */
.text : {*(.text)}
/* Read only data */
.rodata : {*(.rodata)}
/* Data */
.data : {*(.data)}
/* BSS */
.bss : {*(.bss)}
}
Code: Select all
void main() {
//light LED
*LED_SELECT = 1 << 18;
*LED_ON = 1 << 16;
while(1);
}
I think i'm missing obvious but i have some theories to test when i get back home.
1. See if all symbols are 0x120 out or just the entrypoint. Have main call another method to turn on the LED and see if variables can be accessed.
2. (EDIT: Nope) I think i might need to map my kernel entrypoint into the .text.startup section that the elf file creates before the .text. I think the e_entrypoint simply points to the start of the that code section and i was supposed to put my main in there.
3. I'll see if the elf file is actually bootable by U-boot bootelf to see if that is the problem (it only works with identity paging though so i'll have to move the load address lower). Then i'll know for sure it's my elf loader code or the symbols being wrong.