external ELF programs (loading and linker script)

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
User avatar
AndrewAPrice
Member
Member
Posts: 2309
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

external ELF programs (loading and linker script)

Post by AndrewAPrice »

1) Can I have an example of a linker script for an i586-elf program which will load be loaded at virtual 0x400000? (The kernel is loaded and mapped from 0 to 0x3FFFFF).

2) To load an ELF image, the steps I have so far are:
- Check to make sure the ELF header is valid (located at offset 0 in the image).
- Loop through the section headers, if the SHF_ALLOC flag is set copy from sh_offset to (sh_offset+sh_size) in the image to sh_addr in memory.

I don't understand what to do with the program headers. Does each one represent a different section of the program? (Isn't that what section headers are for?)
My OS is Perception.
User avatar
AndrewAPrice
Member
Member
Posts: 2309
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Post by AndrewAPrice »

This is what I have so far:

Code: Select all

OUTPUT_FORMAT("elf32-i386")
ENTRY(start)
SECTIONS
{
    .= 0x400000;
    .text:
    {
        *(.text)
    }
    .data:
    {
        *(.data)
    }
    .bss:
    {
        *(.bss)
    }
}
Is anything else required? (I'm going to use this linker script for all programs compiled with my OS) If I place a STARTUP command that points to my crt0.o do I still have to pass crt0.o to ld, or will the linker script do it automatically?
My OS is Perception.
User avatar
AndrewAPrice
Member
Member
Posts: 2309
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Post by AndrewAPrice »

I've made an ELF parser which scans through the elf, section, and program headers. Using the above linker script my parser displays the following: (the start address for module 0 is where in memory grub loaded the file)

Code: Select all

Module 0: Start: 1077248 Size: 4664 String: /system/SampleProgram.prog
Found ELF header at 1077248.
Contains 1 program headers and 6 section headers.
Prog header 0: Start: 4194304 Offset: 4096
Sect header 0: Addr: 0 Offset: 0 Size: 0
Sect header 1: Addr: 4194304 Offset: 4096 Size: 43
Sect header 2: Addr: 0 Offset: 4139 Size: 49
Sect header 3: Addr: 0 Offset: 4188 Size: 42
Sect header 4: Addr: 0 Offset: 4472 Size: 160
Sect header 5: Addr: 0 Offset: 4632 Size: 32
My parser doesn't check for the SHF_ALLOC flag yet, which could change my question. I understand the program header, it seems like there is only one which covers the entire contents of the file. Are there any scenarios where an ELF file contains more than 1 program header?

I understand section header 0 (I read in the ELF documentation I don't have to do anything with this section because it has a size of 0). I understand section header 1 (the .text section I presume) - I copy from offset 4096 to 4096+32 into memory location 4194304 when I load the it. I don't understand section headers 2, 3, 4, and 5? I'm certainly not going to copy their contents to location 0 in memory since my kernel uses this address for memory management.

EDIT: After looking through the Wiki and being re-directed to the GeekOS header, I see they completely ignore the section header, and instead loop through all the program headers and copy the offset, location, and size of each header. Then loop through and copy this into memory. Is that all I have to do before I can jump to Elf32_Ehdr->e_entry? What are the point of the section headers then?
My OS is Perception.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

Section headers are used in the object files (which are also executable), while the program header is for a final linked executable. You'll probably find more than one in position-independent code that expects to be relinked later.

For the section headers, their type and attributes are a unique combination. Based on this you can find executable segments, data segments, and other random segments that GCC likes to throw into the mix :D

Hope this helps!
User avatar
AndrewAPrice
Member
Member
Posts: 2309
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Post by AndrewAPrice »

I'm getting the proudness everyone else feels the first time they see their OS call a printing function from inside a user program. :)
My OS is Perception.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

MessiahAndrw wrote:I'm getting the proudness everyone else feels the first time they see their OS call a printing function from inside a user program. :)
It's a very good feeling. Even better is when you see it as a product of linking a ported library :D
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

It is a good feeling - the problem with my version is that I'm still using the kernel debug-mode screen print functions at the moment (writing direct to 0xB8000 -->). Just need to get that driver interface sorted out :?

Cheers,
Adam
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

Mine is using the kernel's print function as well.

I haven't yet figured out how to let multiple processes use the console at once. Perhaps I'll make my shell act like DOS in that it'll only run one process at a time (while allowing you to create background services), and ensure that services don't print anything.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Yes - if you are using a text user interface, I think the only sensible way to avoid garbage is ensure that only one task has the console's 'focus' for input and output at any one time.

Of course, you could always have a virtual console associated with each program and allow the user to switch between them - I'm waiting until I get to GUI stage for that, though.

Adam
User avatar
AndrewAPrice
Member
Member
Posts: 2309
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Post by AndrewAPrice »

AJ wrote:Yes - if you are using a text user interface, I think the only sensible way to avoid garbage is ensure that only one task has the console's 'focus' for input and output at any one time.
That's how I do it. I have a m_currentProcess - the process currently running on the processor, and a m_activeProcess - the process in 'focus' and the process the keyboard events are sent to.
My OS is Perception.
User avatar
Dex
Member
Member
Posts: 1444
Joined: Fri Jan 27, 2006 12:00 am
Contact:

Post by Dex »

I would go the way "AJ" pointed out eg:
Of course, you could always have a virtual console associated with each program and allow the user to switch between them
Post Reply