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

  1. Find inode by path

  2. Check ELF header

  3. Load program by memory. uvmalloc to allocate new size.

  4. loadseg load file to memory address at ph.vaddr. Note: Exec loads bytes from the ELF file into memory at addresses specified by the ELF file.

  5. Allocate 2 pages. 2nd one is user stack.

  6. Push args to stack. Prepare ustack to save each argument with its address.

  7. Push the array of argv[] pointers (ustack) to stack.

  8. Set sp to a1.

  9. Commit to user image. Free old process’ page table.

  10. Set epc, sp, sz.

  11. return argc which set argc in reg a0. Now we have main(args, args) from entry, 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

  1. Check ELF header

  2. Load program into memory

  3. 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

TODO

understand ELF.

Last updated

Was this helpful?