How exec() works
Split the flow into 2 phases.
Overview
Split the flow into 4 phases:
1. Read args.
2. Load program from disk to memory.
3. Allocate stacks.
4. Prepare the new images.
Flow
Find
inodeby pathCheck ELF header
Load program by memory.
uvmallocto allocate new size.loadsegload file to memory address atph.vaddr. Note: Exec loads bytes from the ELF file into memory at addresses specified by the ELF file.Allocate 2 pages. 2nd one is user stack.
Push args to stack. Prepare
ustackto save each argument with its address.Push the array of argv[] pointers (
ustack) to stack.Set
sptoa1.Commit to user image. Free old process’ page table.
Set
epc,sp,sz.return argcwhich setargcin rega0. Now we havemain(args, args)fromentry, a0, a1
Read User Args
The argv is a pointer to list of arguments from user space.

Each pointer in RISC-V is 64 bits.
argaddr(1, &uargv) is to get the base pointer. Then, do fetchaddr(uargv+sizeof(uint64)*I, (uint64*)&uarg) in a loop to find each argument’s address.
fetchstr(uarg, argv[i], PGSIZE) is to load the string in argv[I].
Fetch address and string
copyinstr Copy a null-terminated string from user to kernel.
Load program and Allocate pages
Check ELF header
Load program into memory
Allocate 2 pages, one for user stack. Another for guard page.

Note: this graph has a bug. The following 3 items should not exist: argv, argc, 0xFFFFFF
Prepare the new image
Push argument strings to stack. Prepare rest of stack.
Push the array of argv[] pointers to stack.
Set argv in a1 register.
Set process info, including pagetable, sz
Set epc = elf.entry, initial program counter to main initial stack pointer.
Return argc, in RSIC-V, this sets argc in register a0. So arguments main(argc, argv) is set.
The jump preparation is done. Program will go to main, and get args set properly.
How stack look after pushing args?

Core exec code for reference
exec code for referenceTODO
understand ELF.
Last updated
Was this helpful?