# ucore **Repository Path**: os_study/ucore ## Basic Information - **Project Name**: ucore - **Description**: ucore 笔记与源码 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-04-05 - **Last Updated**: 2022-04-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README - [清华大学 ucore 操作系统文档](https://chyyuu.gitbooks.io/ucore_os_docs/content/) # UCore 流程 ## boot - CPU上电 ``` 第一条指令:0xfffffff0 JMP F000:E05B # 从最高64K 跳回 1M空间的最高64K CS.Base->0x000f0000 第二条指令:0x000fe05b BIOS 指令 ``` - BIOS - 硬件自检和初始化 - 选择一个启动设备(例如软盘、硬盘、光盘等),读取该设备的第一扇区\(即主引导扇区或启动扇区\)到0x7c00处 - 跳转至0x7c00处,执行bootloader **bootasm.S::start** - 通过键盘控制器8042,使能A20控制线,以便切换到保模式 - A20控制线(0时)是为了在实模式下模仿早期8086寻址的回绕特征,为访问全部内存需使其为1。 - [探测物理地址](detail.md#probe_memory)-> [struct e820map](struct.md#struct%20e820map)(0x8000); - 切换到保护模式,启用分段机制 **bootmain.c::bootmain** - 加载 gdtr(0x7db4),将CR0第0位置1,更新CS - 更新CS使用长跳转指令 - gdtr:(size:0x17,add:0x7c9c ) - gdt: 三个段,第一个段全 0,data,text 段:(0x0 - 0xffffffff) - 读磁盘中ELF执行文件格式的kernel到内存指定的内存起始地址(0xc010000),kernel的起始地址是在硬盘第1扇区。 - 把控制权交给ucore操作系统 ## kern ### init **entry.S::kern_entry** - [启动页机制](detail.md#启动页机制) - movl 加载 `_boot_pgdir` 到 [cr3](struct.md#cr3%20pde%20pte)中,使能cr0的bit31。 - 跳转到高虚拟地址空间(0xc0000000以上),取消低地址对等映射,调用 `kern_init`。 **init.c::kern_init** - 初始化终端,显示字符串,显示堆栈中的多层函数调用关系; - 调用`pmm_init` ### mm **pmm.c::pmm_init** - [默认物理内存管理器](struct.md#default_pmm_manager)初始化(初始化[free_area](struct.md#free_area_t)) - 调用 [page_init](detail.md#page_init) - 建立[自映射机制](detail.md#自映射机制),便于按虚拟地址的地址顺序显示整个页目录表和页表的内容 - 调用[boot_map_segment](detail.md#boot_map_segment),将 `KERNBASE ~ KERNBASE + KMEMSIZE` 映射到 `0 ~ KMEMSIZE` - 调用 [gdt_init](detail.md#gdt_init) - 返回 `kern_init` ### init **init.c::kern_init** - 调用 `pic_init`,初始化中断控制器 - 调用 [idt_init](detail.md#idt_init),初始化中断描述符表 - 通过 `vmm_init`,调用 [check_vmm](detail.md#check_vmm),模拟缺页,检测页替换算法 ### mm **vmm.c::check_vmm** - 调用 `check_vma_struct`,检测 [mm_struct](struct.md#mm_struct) 相应操作的正确性,其中内存分配为 `kmalloc` ,使用 slub 算法 - 调用 `check_pgfault`,初始化 `check_mm_struct`,其页目录地址为 `boot_pgdir`,向里面插入一个 0 ~ 4M 的合法虚拟地址空间,由于 `boot_map_segment` 未对 0 ~ 4M 的虚拟地址映射,所以访问 `addr = 0x100`时,将产生缺页异常,中断号为 0xE (中断向量 vector14),通过 `trap_dispatch` 进入 [pgfault_handler](detail.md#pgfault_handler) ,缺页异常处理完成后,对 0 ~ 4M 空间进行读写,检测正确性。 - 返回 `kern_init` ### init **init.c::kern_init** - `sched_init`:初始化调度器 - `proc_init` :初始化[PCB 全局变量](struct.md#PCB%20全局变量)(`proc_list`和`hash_list`),[创建初始的内核线程](detail.md#创建内核线程)(第 0 个内核线程 `idleproc`,第 1 个内核线程 `initproc`),并加入进程列表 - `ide_init`:初始化 ide 设备 - `swap_init`:初始化 文件系统 - `clock_init`:初始化时钟中断,`intr_enable`:中断使能 - `cpu_idle`:运行 0 号内核线程 ### process **proc.c::cpu_idle** - 死循环,如果当前线程需要重新调度,调用[schedule](detail.md#schedule)执行 cpu 调度算法