The First Process

Recall: in Lecture 3, after switched to the protected mode and enabled paging, the kernel code can finally enter the world of C again (the last time was in the boot loader).

Initialization on the first CPU:

Jump-start other CPUs

Preparing the first process

Memory allocation is available:

The main CPU will:

userinit() at proc.c

The first process' kernel stack layout (above KERNBASE)

low address                                          high address

----------------------------------------------------------------+

......| struct context     |  X  | struct trapframe             |stacktop

-----------------------^^^----^-----------------------^^^-------+

                        ^ context->rip == forkret      |

                              ^ X == syscall_trapret   |

                                                       ^ tf->rcx == 0x1000 (initcode.S:start at user space)

After switching to this kernel stack:

If "returning from a function" confuses you: the ret instruction is just a special jmp (jump) instruction.

pseudo code of what ret does:

By storing addresses of different functions on stack and execute ret with %rsp pointing to the left-most one, multiple functions will be called one after another, from left to right.

Some ABI uses stack to pass arguments to functions so on these systems arguments can also be prepared on the stack for the chained calling.

This feature can be used to facilitate buffer-overflow attack: Return-to-libc attack Return-oriented programming