I have been analyzing the code of bootmain.c code in xv6 kernel:
void
bootmain(void)
{
struct elfhdr *elf;
struct proghdr *ph, *eph;
void (*entry)(void);
uchar* pa;
elf = (struct elfhdr*)0x10000; // scratch space
// Read 1st page off disk
readseg((uchar*)elf, 4096, 0);
// Is this an ELF executable?
if(elf->magic != ELF_MAGIC)
return; // let bootasm.S handle error
// Load each program segment (ignores ph flags).
ph = (struct proghdr*)((uchar*)elf + elf->phoff);
eph = ph + elf->phnum;
for(; ph < eph; ph++){
pa = (uchar*)ph->paddr;
readseg(pa, ph->filesz, ph->off);
if(ph->memsz > ph->filesz)
stosb(pa + ph->filesz, 0, ph->memsz - ph->filesz);
}
// Call the entry point from the ELF header.
// Does not return!
entry = (void(*)(void))(elf->entry);
entry();
}
I understand that the following line
readseg((uchar*)elf, 4096, 0);
is trying to copy elf header from the disk to the memory at elf address, but I don't understand why is it copying 4kb where the size of the elf header itself is 52 bytes.
After running readelf -h kernel, I get the following info about elf headers:
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 3
which would mean (if my math serves me well) that elf header + program header table doesn't take more than 148 bytes.