Why first user process loads another program?
What happen?
The first user process from userinit()
loads initcode.S
program, which internally calls exec
to run init
program.
The flow:
userinit
prepares the first process. It sets the program counter to instructions in initcode.S
. When scheduler runs it, it will begin execution. initcode.S
has a system call exec
to run init
, and starts from there.
Why the process cannot call init
directly?
init
directly?My original Thought
I think userinit
can definitely call init.c
. We can get the hex dump of init.c
binary, then make our array initcode[]
to contain it. The reason MIT implementers did not do it because there are a lot of hex to copy! But, I might be wrong…
The Truth
The instruction of the loaded program must be fitted into one page.
initcode.S
is built to a binary file.
The obj dump of the binary shows the first instruction is auipc a0,0x0
:
The program is mapped to the process at virtual address(VA) 0. The program counter is set to VA 0 as well, which is the 1st instruction.
When CPU scheduler runs this process, the PC points to first instruction at VA 0. Then PC moves to the next instruction (PC + 4).
Understand initcode
section in Makefile
initcode
section in MakefileUse linker for ELF executable
In Makefile: $(LD) $(LDFLAGS) -N -e start -Ttext 0 -o $U/initcode.out $U/initcode.o
ld(1): GNU linker - Linux man page
ld -o /lib/crt0.o hello.o -lc
This tells ld
to produce a file called output as the result of linking the file “/lib/crt0.o” with “hello.o” and the library “libc.a”, which will come from the standard search directories. (See the discussion of the -l option below.)
The linker cmd generates initcode.out
from object file. The output file is:
Use objcopy
to generate stripped binary
objcopy
to generate stripped binaryIn Makefile: $(OBJCOPY) -S -O binary $U/initcode.out $U/initcode
Research
objcopy (GNU Binary Utilities) objcopy
can be used to generate a raw binary file by using an output target of ‘binary’ (e.g., use -O binary).
When objcopy
generates a raw binary file, it will essentially produce a memory dump of the contents of the input object file. All symbols and relocation information will be discarded. The memory dump will start at the load address of the lowest section copied into the output file.
Use -S to remove sections containing debugging information.
Explain
The result data file (initcode
) is a stripped version of initcode.out
(binary). It is a memory dump of the contents.
Look at this assembly
Then look at the hex dump:
Now tell me, what do you observe? The hex dump is the assembly instructions in little endian format! (00000517
becomes 17 05 00 00
…)
Now, we understand why there is a hex dump array loaded to xv6 first user process!!!
Ref
objcopy(1): copy/translate object files - Linux man page
Makefile prints tool prefix.
Last updated