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.
I'll assume that you have your virtual memory management & multitasking set up.
If you don't have virtual memory management, you should implement it before doing this.
Read the ELF header of the file & validate it. This header contains all the information you need for loading
Set up an empty process/task
Copy all "load segments" into memory: each of these segments has a virtual address (vaddr) where it should to be copied to, the amount of bytes that have to be copied (filesz) and the amount of memory that has to be zero'd (memsz), both based on the vaddr (read specification for more details)
Set the instruction pointer of the task to start at the entry point specified in the program header (e_entry)
Add the task to your scheduler
This should be appropriate for the start. In essence you load all "load" segments into memory and kick off the executable at it's entry point.
You want the System V ABI as the true standard of ELF. The trick is to parse the header and recognize it is an ELF. You then parse the program headers (not section headers!) and load each entry by allocating memory at the desired address and copying data from the file there, and zeroing the rest. Pretty simple. You locate the program entry point in the ELF header, and transfer execution there after setting up a stack.