# 练习

## 练习1：分配并初始化一个进程控制块

`alloc_proc` 函数（位于 `kern/process/proc.c` 中）负责分配并返回一个新的`struct proc_struct`结构，用于存储新建立的内核线程的管理信息。ucore 需要对这个结构进行最基本的初始化，你需要完成这个初始化过程。

{% hint style="success" %}
在`alloc_proc`函数的实现中，需要初始化的 `proc_struct` 结构中的成员变量至少包括：state/pid/runs/kstack/need\_resched/parent/mm/context/tf/cr3/flags/name。
{% endhint %}

请在实验报告中简要说明你的设计实现过程。并回答如下问题：

* 请说明 `proc_struct` 中`struct context context`和`struct trapframe *tf`成员变量含义和在本实验中的作用是啥？（提示：通过看代码和编程调试可以判断出来）

## 练习2：为新创建的内核线程分配资源

创建一个内核线程需要分配和设置好很多资源。`kernel_thread` 函数通过调用`do_fork`函数完成具体内核线程的创建工作。`do_kernel` 函数会调用 `alloc_proc` 函数来分配并初始化一个进程控制块，但 `alloc_proc`只是找到了一小块内存用以记录进程的必要信息，并没有实际分配这些资源。ucore 一般通过 `do_fork`实际创建新的内核线程。`do_fork` 的作用是，创建当前内核线程的一个副本，它们的执行上下文、代码、数据都一样，但是存储位置不同。在这个过程中，需要给新内核线程分配资源，并且复制原进程的状态。你需要完成在 `kern/process/proc.c`中的 `do_fork`函数中的处理过程。它的大致执行步骤包括：

* 调用`alloc_proc`，首先获得一块用户信息块。
* 为进程分配一个内核栈。
* 复制原进程的内存管理信息到新进程（但内核线程不必做此事）
* 复制原进程上下文到新进程
* 将新进程添加到进程列表
* 唤醒新进程
* 返回新进程号

请在实验报告中简要说明你的设计实现过程。请回答如下问题：

* 请说明 ucore 是否做到给每个新 fork 的线程一个唯一的 id？请说明你的分析和理由。

## 练习3：理解proc\_run函数和调用的函数如何完成进程切换的

请在实验报告中简要说明你对 proc\_run 函数的分析。并回答如下问题：

* 在本实验的执行过程中，创建且运行了几个内核线程？
* 语句`local_intr_save(intr_flag);....local_intr_restore(intr_flag);`在这里有何作用?请说明理由


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://nankai.gitbook.io/ucore-os-on-risc-v64/lab4/lian-xi.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
