i've posted both files (.gba rom and .elf binary) in a zip archiveberkus wrote:Why not parse all ELF file headers, there are some fields that pretty much can tell you if this is a real ELF file, what format it is in and if it actually contains information you're looking for. If it's not too big you can attach it here so that we can have a look instead.
ELF questions
-
- Posts: 17
- Joined: Tue Jan 20, 2009 7:03 pm
Re: ELF questions
- Attachments
-
- pong.zip
- (7.06 KiB) Downloaded 108 times
Re: ELF questions
I remember doing GBA development with devkitarm. If I remember correctly. one usually links everything into an ELF file, and then converts it to a flat binary using objcopy.
Marionette the flexible kernel
-
- Posts: 17
- Joined: Tue Jan 20, 2009 7:03 pm
Re: ELF questions
ok i've gone a bit further with this after putting it off for a while. i'm able to read the elf file and get the information from the elf header and program headers. here's the info given by reading the file information:
elf header:
phdr1:
phdr2:
phdr3:
so what i'd like to do next is get the program running. i'm not worried about switching back to the caller, just in switching context. i'll need to use physical addressing as i'm not actually building an OS from this yet, just trying to get binaries loaded and running.
first, given the above program header information, do i really need to move the data into the above locations in physical memory? it doesn't seem like it should really matter where in memory the program sits so long as the interrupt send program execution to the place in memory where the beginning of the program exists, no? if it is actually necessary to move things into the physical addresses listed by the p_paddr member of the program headers, could someone explain why this is necessary?
second, if it is necessary to place the program in a specific place in memory, i'll need to ensure that those addresses aren't in use. so since i'll be loading up about 40KB of space (39KB in EWRAM and 1KB in IWRAM on the GBA), i'll need to ensure that the code i'm executing exists somewhere outside this boundary. since really the only code i need to be careful with on placement is the memcpy that places the code in it's appropriate location, how can i use C syntax to block the memcpys together and place them in a particular location in memory, at say, 0x02020000, so it isn't affected by the memcpy copying over the running code?
elf header:
Code: Select all
e_type: 2
e_machine: 40
e_version: 1
e_entry: 0x02000000
e_phoff: 52
e_shoff: 102832
e_flags: 67108866
e_ehsize: 52
e_phentsize: 32
e_phnum: 3
e_shentsize: 40
e_shnum: 25
e_shstrndx: 22
Code: Select all
p_type: 1
p_vaddr: 0x02000000
p_paddr: 0x02000000
p_filesz: 40820
p_memsz: 40820
p_flags: 7
p_align: 32768
Code: Select all
p_type: 1
p_vaddr: 0x03000424 //exactly 1060 bytes, size of phdr3 (memsz)
p_paddr: 0x02009F74 //exactly 40820 bytes, size of phdr1
p_filesz: 4
p_memsz: 4
p_flags: 6
p_align: 32768
Code: Select all
p_type: 1
p_vaddr: 0x03000000
p_paddr: 0x03000000
p_filesz: 0
p_memsz: 1060
p_flags: 6
p_align: 32768
first, given the above program header information, do i really need to move the data into the above locations in physical memory? it doesn't seem like it should really matter where in memory the program sits so long as the interrupt send program execution to the place in memory where the beginning of the program exists, no? if it is actually necessary to move things into the physical addresses listed by the p_paddr member of the program headers, could someone explain why this is necessary?
second, if it is necessary to place the program in a specific place in memory, i'll need to ensure that those addresses aren't in use. so since i'll be loading up about 40KB of space (39KB in EWRAM and 1KB in IWRAM on the GBA), i'll need to ensure that the code i'm executing exists somewhere outside this boundary. since really the only code i need to be careful with on placement is the memcpy that places the code in it's appropriate location, how can i use C syntax to block the memcpys together and place them in a particular location in memory, at say, 0x02020000, so it isn't affected by the memcpy copying over the running code?
-
- Member
- Posts: 524
- Joined: Sun Nov 09, 2008 2:55 am
- Location: Pennsylvania, USA
Re: ELF questions
Unless the code is position independent, you need to run it at the location specified in p_vaddr.
-
- Posts: 17
- Joined: Tue Jan 20, 2009 7:03 pm
Re: ELF questions
but doesn't that assume that you're using virtual addressing? as i said, this isn't for an OS, but just to load the file and run it. and how can i tell if the code is "position independent" or not? there is an objdump in one of the above posts; can you tell from that?JohnnyTheDon wrote:Unless the code is position independent, you need to run it at the location specified in p_vaddr.
my understanding, from the ARM ELF reference, is that p_vaddr is used on most modern operating systems with virtual addressing
i'm assuming that the operating system specific information has to do with simply how the OS would avoid issues with memory overwrite...p_vaddr - this member gives the virtual address at which the first byte of the segment resides in memory.
p_paddr - on systems for which physical addressing is relevant, this member is reserved for the segment's physical address. this member requires operating system specific information.
i think i'm correct in my assumptions, and since you say the code must be PIC and i don't know how to verify if it is or not (should i post the Makefile i'm using? it came with the gcc 4.3 ARM eabi and some gba libraries...) but i'm not sure how to write C syntax to place blocks of code at specific addresses. i thought about defining a pointer to a function at a specified address in a preprocessor directive, but this would just place the pointer in that address and not the actual code...
i realize a lot of you guys have written full blown operating systems where virtual addressing is relevant but this is merely a simple ELF loader that i'm writing for the GBA. basically, the flash cartridge will load a .gba rom that i'm building that will do the following:
- load ELF from disk to main memory according to p_paddr(?) variable (using stdio)
- send a hardware interrupt that will perform re-entrant capable interrupts (i already have the code for this and have gone through many guides for writing interrupt handlers for ARM)
- switch execution to address of loaded ELF binary
- Firestryke31
- Member
- Posts: 550
- Joined: Sat Nov 29, 2008 1:07 pm
- Location: Throw a dart at central Texas
- Contact:
Re: ELF questions
Isn't the 'p_vaddr' field (for all intents and purposes) just the place the ELF expects to be loaded? There's a similar field in EXE that I just load my old OS's EXE to physically instead of dealing with virtual memory and all of that. It still works because the addresses that the program sees are all the same. "Virtual" address is just used because it's assumed that people are running on a multi-tasking OS (I think).
Owner of Fawkes Software.
Wierd Al wrote: You think your Commodore 64 is really neato,
What kind of chip you got in there, a Dorito?
-
- Posts: 17
- Joined: Tue Jan 20, 2009 7:03 pm
Re: ELF questions
if that's the case then i'll just have to write two functions for building the process image; one that uses the p_paddr member and one that uses the p_vaddr member. but before i can do that, i still need to know how i can use C syntax to place the .gba rom code away from the addresses that will be used by the program being loaded.Firestryke31 wrote:Isn't the 'p_vaddr' field (for all intents and purposes) just the place the ELF expects to be loaded? There's a similar field in EXE that I just load my old OS's EXE to physically instead of dealing with virtual memory and all of that. It still works because the addresses that the program sees are all the same. "Virtual" address is just used because it's assumed that people are running on a multi-tasking OS (I think).
so if i wanted to place code at 0x02020000 (EWRAM, well away from the addresses specified in the ELF binary), how can i do that? the gba will expect the first bit of code to be at 0x02000000 when the rom is first loaded but any code after that can be elsewhere.
- Firestryke31
- Member
- Posts: 550
- Joined: Sat Nov 29, 2008 1:07 pm
- Location: Throw a dart at central Texas
- Contact:
Re: ELF questions
You could compile as if loaded to 0x02020000, but have the first thing you do be copy the code there, then jump (does the ARM have IP-relative jumps?). That's what my second stage does, since the copy loop can use a relative jump on the x86, and I'm sure something similar can be done on the ARM.moonlightcheese wrote: so if i wanted to place code at 0x02020000 (EWRAM, well away from the addresses specified in the ELF binary), how can i do that? the gba will expect the first bit of code to be at 0x02000000 when the rom is first loaded but any code after that can be elsewhere.
Owner of Fawkes Software.
Wierd Al wrote: You think your Commodore 64 is really neato,
What kind of chip you got in there, a Dorito?
Re: ELF questions
If you are using GCC and LD you should look into using a linker script. With a linker script you can tell LD to make the code think that its running at any address you tell it to.