How to execute ELF executables?

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
zyp

How to execute ELF executables?

Post by zyp »

I have a little ELF-kernel which is booted by GRUB.
Now I'm wondering how I can execute an ELF executable (which grub loads into memory with module).
Is it as simple as just jmp-ing to the memory position which it's loaded at, or do I need to do some more work?
Kim

Re:How to execute ELF executables?

Post by Kim »

The easy way would be linking the ELF executable to a memory location that is not in use and then use memmove to move it to that location at runtime and read the entrypoint of it in the header and jump to it...

But i don't see the use of it :s you would then have a single task os without anything usefull...
ineo

Re:How to execute ELF executables?

Post by ineo »

Correct me if I am wrong, but grub doesn't interprete modules. Modules are considered plain binary, they are just loaded somewhere in memory. You have to do relocation & so on as needed.

I had the problem when starting my microkernel.

INeo
AR

Re:How to execute ELF executables?

Post by AR »

Modules are considered plain binary
Or more accurately, they are uninterpreted and are simply shoved in memory at the end of the "kernel" one after the other.

Loading a statically linked elf isn't difficult, just read the ELF header at the start, find the program header table (e_phoff), read through it and memcpy() the data (p_filesz bytes at p_offset from file start) to wherever it says to put it (p_paddr) then you can jmp to e_entry from the ELF header. You'll need to get a copy of the ELF Specification, note it can be a pretty difficult read, some of the stuff seems to be in a dialect of legalese, you should be able to understand everything you need without too much difficulty though.
zyp

Re:How to execute ELF executables?

Post by zyp »

Kim: Don't worry about the point, it's just for the theory of it. It will work the same way when I make multitasking or what?

ineo: I know that it's plain binary, that's the point, as I haven't done my own loader yet.

Instead of moving it in the memory, I can set up paging so that it's virtually another place, right?
durand
Member
Member
Posts: 193
Joined: Wed Dec 21, 2005 12:00 am
Location: South Africa
Contact:

Re:How to execute ELF executables?

Post by durand »

The alignments specified are far more fine-grained than just page boundaries in ELF - sometimes the differences are a few bytes in size.

You will have to memcpy the different sections to their correct virtual locations.
zyp

Re:How to execute ELF executables?

Post by zyp »

Do you know of any tutorials explaining how to do this kind of stuff?
durand
Member
Member
Posts: 193
Joined: Wed Dec 21, 2005 12:00 am
Location: South Africa
Contact:

Re:How to execute ELF executables?

Post by durand »

Well, it's always a lot easier than it sounds. :)

Here's some really bad pseudo-code I quickly slapped together:

Code: Select all


Assuming the complete ELF is loaded at *BUFFER by grub;

Locate the ELF header (first position in *BUFFER)

For ( i = 0; i < header->e_phnum; i++ ) do

   Set *Phdr to point to: (BUFFER + header->e_phoff + header->e_phentsize * i);

   if ( Phdr->p_type == 1 (aka LOAD)  ) then 
   
   Create a virtual memory region of Phdr->p_memsz at Phdr->p_vaddr
   Copy Phdr->p_filesz bytes from (*BUFFER + Phdr->p_offset) into new virtual location.
   
   end if;

end for;


Locate the program entry point in the header. (header->e_entry)

Set your new program to start running at virtual location header->e_entry.

Anyway, the ELF structures are defined in the link provided by AR. Just get your ELF structures correct, use the pseudo-code logic above and you'll be running your ELF binaries in no time.

If you want to use my ELF headers, you can download them from http://www.djm.co.za/spoon/snapshot.tar.gz and you can find them in /spoon/system/source/kernel/include/elf.h
zyp

Re:How to execute ELF executables?

Post by zyp »

Thanks, I'll try it tomorrow. Too tired now.

What about libraries then, that I just want to load, and call functions from?

I'll planning to make a modular kernel that contains as little as possible. Then I'll get GRUB to load the most important modules like VFS, filesystems and harddrive and then load less important drivers from the harddrive later.
I tought that each module could have an info structure which the kernel could read first, which told the kernel if it was an active (task) module or a passive (library) module.
Like, VFS could be active, but filesystem and harddrive could just be a library.

Does this make any sense? Anyway, I'm off to bed. ;)
AR (Away)

Re:How to execute ELF executables?

Post by AR (Away) »

I have just finished having the displeasure of writing an ELF Dynamic Linker for my Kernel in the bootloader (I'm implementing a Microsoft style HAL for the Kernel), the dynamic linker is the most difficult part to understand in the specification, loading a program that is standalone is very easy but when there are libraries involved, everything gets very complicated, very quickly (relocation table, dynamic linking table, symbol table, symbol hashes, GOT, etc).

Drivers and the filesystem would be standalone executables, you wouldn't want them in library format (they would go out of sync, you would effectively have infinite instances of the filesystem library, all conflicting with each others requests). If you mean metaphorically, they only respond to IPC from other processes, that would be an effective way to prevent wasting time in the service when it isn't needed.
zyp

Re:How to execute ELF executables?

Post by zyp »

AR (Away) wrote: Drivers and the filesystem would be standalone executables, you wouldn't want them in library format (they would go out of sync, you would effectively have infinite instances of the filesystem library, all conflicting with each others requests). If you mean metaphorically, they only respond to IPC from other processes, that would be an effective way to prevent wasting time in the service when it isn't needed.
FS-drivers won't respond to calls from processes, VFS-driver would.
Then I tought that each FS-driver could offer a class, and for each mount of that FS-type, one class is instanced by the VFS.
Post Reply