RetroBSD

2.11BSD operating system for microcontrollers
It is currently Tue Jan 16, 2018 7:25 pm

All times are UTC




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: Executable file format
PostPosted: Thu Sep 25, 2014 4:50 pm 

Joined: Tue Aug 19, 2014 2:27 pm
Posts: 10
I noticed that the default executable format for all of the built-in programs in the RetroBSD source tree are built in the a.out format, not ELF format. Is there a specific reason for this? There's clearly support in the kernel, although I haven't tested it.


Top
 Profile  
 
PostPosted: Thu Sep 25, 2014 5:29 pm 
Committer
User avatar

Joined: Wed Oct 10, 2012 11:01 pm
Posts: 1079
Location: Sunnyvale, CA
A.out format was the native for 2.11bsd. ELF has been added later. We could switch to ELF eventually, but assembler and linker still support only a.out variant. Enhancing all these utilities does not seem a trivial task, regarding the limitation of user space size. So for now it makes sense to use ELF for cross-compiled binaries, and a.out for native build.


Top
 Profile  
 
PostPosted: Fri Jul 31, 2015 7:29 pm 

Joined: Fri Jul 31, 2015 7:16 pm
Posts: 3
There's something I've always wanted to know about excusable in BSD, how are they loaded and start up?
By this, I mean, is the file (a.out, ELF, etc) just copied into memory, a little setup of ram, then the first opcode jumped to? (Like old DOS) or what?

On an ELF, I could see much more complicated (and efficient) ways of the OS preloading the variable ram and loading only the executable code from the ELF.

On a related note, where in the OS code can I see this happening? I've dug into this before but was not able to follow exactly what was going on.

TooMuchInfoMann


Top
 Profile  
 
PostPosted: Sat Aug 01, 2015 8:24 pm 

Joined: Fri Jul 31, 2015 7:16 pm
Posts: 3
This brings up a question I've had for years about Executables.... How exactly are they loaded and executed in a modern OS, like BSD?

In the old DOS days, the EXE file was copied into ram, then there was a jump to the first opcode. I know in Unix/Linux/BSD there is a lot more going on, like the application environment, ram space, etc. must be created.

A.out appears to be similar to DOS EXE files, but ELF is more complex and the OS could be optimized to only load what is needed. This could be loading only a few sections, the ones needed into application ram, including loading initiation variables into the starting variable space rather than the application do so.


Also, on a related note, where in the RetroBSD source does this happen? I've dung though the source of it, Linux kernel, and others without luck. I'm just overwhelmed at the abstraction layers, because of not understanding what is what in the variable and function naming.

- - TooMuchInfoMann
(This is try 2 at this post. I hope it works!)


Top
 Profile  
 
PostPosted: Sun Aug 02, 2015 1:33 am 
Committer
User avatar

Joined: Wed Oct 10, 2012 11:01 pm
Posts: 1079
Location: Sunnyvale, CA
Loading executables is a quite interesting topic. In 1992 William Jolitz, a guy who first ported 4.3BSD to i386 architecture, publishes a series of articles in Dr.Dobb's Journal describing a few aspects. One of them was execve() system call, i.e. loading of a.out executable in a memory of a process.

It does worth mentioning that AT&T treated this stuff as it's intellectual property and forced Berkeley university to remove the sources of execve() call from the public BSD package. All opensource systems based on 4.4BSD-Lite (FreeBSD, NetBSD, OpenBSD and others) had to reimplement it from scratch. You can find the RetroBSD version of execve() here: https://github.com/RetroBSD/retrobsd/blob/master/sys/kernel/kern_exec.c

Basically the sequence of actions is not much complicated. See function exec_check(). First step is to read the file header and detect a format: a.out, ELF or shell script. Then a format-specific function is called:
In RetroBSD we have not demand paging, so the following actions for a.out and ELF are pretty straightforward.
  1. Read text and data sections into memory
  2. Fill bss section with zeroes
  3. Create a frame on user stack
  4. Extend the user stack with command line arguments and environment variables
  5. Finish the system call as usual, restoring the user context from this new stack frame
You can find the details in file: https://github.com/RetroBSD/retrobsd/blob/master/sys/kernel/exec_subr.c

Best wishes,
--Serge


Top
 Profile  
 
PostPosted: Mon Aug 03, 2015 3:52 am 

Joined: Fri Jul 31, 2015 7:16 pm
Posts: 3
Thank you Vax.

Fantastic reply with loads an loads of great info.

Now warming up Code::Blocks to start digging to understand all this.

_________________
-- TooMuchInfoMann


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
cron




Powered by phpBB® Forum Software © phpBB Group

BSD Daemon used with permission