Operating System | Ucore-Lab4
Presupposition
In this lab, we will not differ (process, thread) and (pcb, tcb). Because based on the presupposition, we can just create kernel thread.
Practices & Conclusion
Practice 1
The process control block in ucore is designed like this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16struct proc_struct {
enum proc_state state; // Process state
int pid; // Process ID
int runs; // the running times of Proces
uintptr_t kstack; // Process kernel stack
volatile bool need_resched; // bool value: need to be rescheduled to release CPU?
struct proc_struct *parent; // the parent process
struct mm_struct *mm; // Process's memory management field
struct context context; // Switch here to run process
struct trapframe *tf; // Trap frame for current interrupt
uintptr_t cr3; // CR3 register: the base addr of Page Directroy Table(PDT)
uint32_t flags; // Process flag
char name[PROC_NAME_LEN + 1]; // Process name
list_entry_t list_link; // Process link list
list_entry_t hash_link; // Process hash list
};The context struct is used for saving or restoring registers when switching the running process, it records the context of one process. We save the fork return address as
context.eip, so the newly process will start at fork return in this lab.1
2
3
4
5
6
7
8
9
10struct context {
uint32_t eip;
uint32_t esp;
uint32_t ebx;
uint32_t ecx;
uint32_t edx;
uint32_t esi;
uint32_t edi;
uint32_t ebp;
};The trapframe struct can be writen when interrupt occurred, cpu will reset to run the ISR and find the corresponding handler. Then the trapframe would be used to parse and handle the interrupt. In this lab, we use trapframe as the first stack frame to initialize the process stack, so that when newly process starting at fork return address and jumping to trapret func, trapret will reset the current esp to trapframe.tf_esp, when iret done, cpu will be set up totally to run the
kernel_thread_entrywhich is a wrapped function to redirect the function what we request before.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22struct trapframe {
struct pushregs tf_regs;
uint16_t tf_gs;
uint16_t tf_padding0;
uint16_t tf_fs;
uint16_t tf_padding1;
uint16_t tf_es;
uint16_t tf_padding2;
uint16_t tf_ds;
uint16_t tf_padding3;
uint32_t tf_trapno;
/* below here defined by x86 hardware */
uint32_t tf_err;
uintptr_t tf_eip;
uint16_t tf_cs;
uint16_t tf_padding4;
uint32_t tf_eflags;
/* below here only when crossing rings, such as from user to kernel */
uintptr_t tf_esp;
uint16_t tf_ss;
uint16_t tf_padding5;
} __attribute__((packed));
Practice 2
Problem 1
The following codes had shown the processing of do_fork().
1 | // 1. call alloc_proc to allocate a proc_struct |
Notice:
- Step 3 has decided the way to operating the memory, duplicate or share with its parent.
Problem 2
Ucore can assign an unique process id for each process control block. First, Step 5 in Prob.1 has shown us that it will do the assigning opertion with interrupt disabled by command local_intr_save(intr_flag), because of that, cpu will not be rescheduled to other threads or processes until local_intr_restore(intr_flag) called. Secondly, the logic of get_pid(), which use two parameters last_pid and next_safe to ensure a safe interval can be used, ensures an unique pid assigned with an acceptable time complexity.
1 | // get_pid - alloc a unique pid for process |
Practice 3
Problem 1
In lab4, ucore created 2 processes: idle and init.
Ucore created a pcb named idle in the final stages then it set current process to idle. Idle process is used to run in idle status or switch the running processes. Init process is just used to print string in this lab, it will change to be more functional in the following labs. When the ucore running to cpu idle, the control will be handed to idle or another processes which is can be scheduled.
Problem 2
Codes of proc_run:
1 | // proc_run - make process "proc" running on cpu |
In these codes, local_intr_save(intr_flag) and local_intr_restore(intr_flag) disabled the interrupt to ensure cpu executing commands in an atomic status which means it can not be interrputted. Because of that, registers of cpu can be restore and reset with security.