22 Matching Annotations
  1. Last 7 days
    1. PTE also contains an access bit, a dirty bit, a present bit• Present bit: whether this page is in physical memory or on disk• Dirty bit: whether the page has been modified since it was broughtinto memory• Access bit: whether a page has been accessed 18

      | 位 | 含义 | OS 用途 | | ------- | ------- | ------ | | Present | 是否在 RAM | 缺页异常 | | Dirty | 是否被修改 | 是否写回磁盘 | | Access | 最近是否使用 | 页面置换 |

    2. Don’t you need tocompare offsetwith bounds?

      为什么分页不用?

      分页地址结构:

      虚拟地址 = VPN + offset

      例如页大小 4KB:

      offset 范围天然固定: 0 ~ 4095

      因为 offset 的位数固定。

      若页大小4KB:

      2^12 = 4096

      所以 offset 就是低12位。

      它天然不可能超过页大小。

    1. A segment may grow, which may or may not be possible

      heap 想扩展,但:

      👉 中间空间不够 👉 或被别的 segment 挡住

      那怎么办?

      可能结果: ❌ 扩展失败 ❌ 必须搬整个段(非常昂贵)

    2. Base/bounds registers organized as a table

      一个 CPU 拥有多个 segment 的 base/bounds 寄存器对(每个 segment 一对),执行时根据访问类型选择对应的那一对使用

    3. <?

      👉 bounds 表示的是“大小(size)”,不是位置(position)

      👉 检查的时候:

      检查的是:虚拟地址 VA < bounds

      👉 计算物理地址才用:

      PA = base + VA

    4. 1. #include <stdio.h>2 #include <stdlib.h>3 int main(int argc, char *argv[]) {4 printf("code : %p\n", main);5 printf("heap : %p\n", malloc(100e6));6 int x = 3;7 printf("stack: %p\n", &x);8 return x;9 }

      打印的是虚拟地址 main 函数地址 code(代码段) malloc(...) 返回值 堆内存地址 heap 参数是申请的大小(byte) &x 变量地址 stack

    5. Big endian or little endian• 32-bit int at 0x8c• big endian: 0x d1 4a f5 83• little endian: 0x 83 f5 4a d1

      ✔ Big Endian(大端) 高位字节(Most Significant Byte)放在低地址 看起来和我们写数字顺序一样 ✔ Little Endian(小端) 低位字节(Least Significant Byte)放在低地址 “反着放”

    1. One-to-one mapping

      在 one-to-one 模型中,user thread 作为编程抽象仍然存在,每个 user thread 对应一个 kernel thread;创建线程时,通过线程库调用系统调用(如 clone)在内核中创建对应的 kernel thread。

    2. Thread Models109One-to-OneMany-to-One Many-to-Many• Many-to-one mapping• Many user threads to onekernel thread• One-to-one mapping• One user thread to onekernel thread• Many-to-many mapping• Many user threads tomany kernel threads

      user thread 和 kernel thread 的区别在于调度和实现层次;mapping 表示用户线程与内核线程之间的对应关系,用于将用户线程映射到可被操作系统调度的内核线程上执行。只有kernel thread能在CPU上运行,所以user thread必须挂载在kernel thread上

    3. It’s possible:real > user + sysreal < user + sys“>”: when CPU not schedule to you“<“: when multi-threadingWhy?• real>user+sysI/O intensive• real<user+sysmulti-core

      对于 I/O 密集型程序,进程在等待设备时不会占用 CPU,因此这些等待时间不计入 user 或 sys 时间,从而导致 real > user + sys; 对于多线程或多核并行程序,多个 CPU 同时执行任务,CPU 时间会累加,因此 user + sys 可能大于 real。

    4. How does uCorecreate the firstprocess?

      uCore 在启动过程中通过内核函数(如 kernel_thread)手动创建第一个进程,直接分配并初始化进程控制块(PCB),设置执行入口并加入调度队列,而不是通过 fork 创建。

    5. =0 ) {printf("Look at the status of the child process %d\n", pid);while( getchar() != '\n' );wait(NULL);printf("Look again!\n");while( getchar() != '\n' );}return 0;} This program requires you to type “enter” twicebefore the process terminates.You are expected to see the status of the childprocess changes (ps aux [PID]) between the 1st andthe 2nd “enter”.“enter” here“enter” here123456789101112

      fork() 后父子进程都会继续执行;子进程因 pid == 0 不进入 if,直接返回并通过 exit() 终止,此时由于父进程尚未调用 wait(),子进程变为 zombie;在第一次按 Enter 前可观察到该 zombie 进程,而在父进程调用 wait(NULL) 后,该 zombie 被回收并消失。

    6. On Parent’s wait(), kernel:- sets the signal handling routine- once set, found SIGCHLD isalready there- takes action immediatelyThis guy invokedwait().ChildParentSignal handlersSIGCHLDfrom1235

      当子进程调用 exit() 时,内核会释放其大部分资源,但保留其进程表项并将其标记为 zombie,同时记录退出状态并向父进程发送 SIGCHLD 信号;父进程调用 wait() 时,如果已有 zombie 子进程,则会立即回收其中一个、返回其 PID 并通过 status 提供退出信息,否则父进程会阻塞等待直到子进程结束。

    7. Clean up most of the allocated kernel-space memory(e.g., process’s running time info).Step (2) Clean up the exit process’s user-space memory.Step (3) Notify the parent with SIGCHLD.exit() iscalled.(1) (2) (3)exit()returns.ChildKernel

      子进程调用 exit() 后,内核不会立即删除其 process table entry(PCB的一部分),而是将其标记为 zombie,并保留退出状态(exit code)等信息; 同时内核向父进程发送 SIGCHLD 信号,通知其子进程已终止; 父进程随后通过 wait() 或 waitpid() 获取子进程的 PID 和退出状态,并最终回收该进程资源。

    8. How do the twoprocessescommunicate?

      子进程返回给内核,内核唤醒父进程 父进程wait()的返回值是子进程的pid 子进程通过 exit(code) 将退出状态交给内核; 内核将该状态编码到 status 中; 父进程调用 wait(&status) 后,可通过 WEXITSTATUS(status) 获取子进程的退出码。