lab1的代码量在1.5K左右,想要一天看完还要熟悉工具链了解相关姿势做完练习果然还是不太科学orz
Lab1相关笔记:
- ucore用页机制实现分段
- 练习一中sign为签名工具,编译时带标准库,在开发环境下,对生成的bootblock进行签名处理。
- 在lab1就已经提供了一定程度【就是自己写的意思】的库函数了,,,,,可怕!lab1其实已经提供了太多硬件接口了,实际代码做的事远比视频描述的bootloader和ucore要多,毕竟已经做了好多好多中断和库函数了,,
- understand key: 09E58CD1FB79【滴滴学生卡】
- kern_init/init.c/console_init()/cga_init():CGA是显卡模式,估计是字符型
- 前人的blog
http://spartan1.iteye.com/blog/1267858 实际上把bootloader和ucore单步调试走一遍基本可以有一定深度地了解整个启动过程了,毕竟启动的模块就一个一个函数写好在那里,但是不展开又怎么知道具体实现呢。我在这里粗略写一下启动的调用顺序吧:
- 【bootasm.S】:关中断,初始化段寄存器,激活1MB以外的内存(enable A20),实模式到保护模式的切换,实模式下初始化段寄存器,t跳转到bootmain()
- 【bootmain.c】:读第一扇区,判断扇区内容是否符合ELF文件格式,把所有程序段读进来(这里我的细节没有详细弄明白),用
((void (*)(void))(ELFHDR->e_entry & 0xFFFFFF))();
来实现访问指定地址的代码【而不是数据!】,这种技巧还真的第一次见,因为ucore的kernel入口在e_entry里嘛, - 【kernel/init.c】:设定kern用的内存范围,初始化控制台(包括CGA初始化,即上面说到的显卡模式,串口初始化,键盘),物理内存管理的初始化(现在只是设置了一下GDT,估计后面讲内存管理再进一步详细设置),PIC初始化,中断向量表初始化,时钟设置,恢复中断,这里期间还进行了一些测试性输出,比如输出寄存器的值,打印栈帧,进行用户态-系统态的切换。建议每一个函数都去展开来看,看到比较底层的地方大概很清楚做了什么了,配套提供的understand生成函数调用图食用疗效更佳。
今天【2016年7月30日 22:48:51】就先到这里吧,我还是尽量以lab为单位去分配日记吧,不然看起来不方便,一天的内容也不够多。
- 今天【2016年7月31日 20:23:05】继续往后看lab_book,结果发现其实很多地方还是讲了很详细的,我昨天写的【这一条上面的】内容很多lab_book其实有很详细的介绍了,尤其是中断机制,系统态-用户态切换的细节,以及很多硬件的细节都有讲,配套练习的问题也有很多拓展的资料可以看(然而看不过来),真是不得不感叹羡慕人家资源好,还开放给大众用。但是笔记我还是要写一下的,不扯了继续主题。
- mmu.h里结构体的定义使用到了位域这一语法,规定了成员的长度:
struct{int a:2;} 表示变量a的位长为2,不论其声明类型
- UCORE的GDT设定如下(kern/mm/pmm.c):
-
- 0x0 : unused (always faults – for trapping NULL far pointers)
- 0x8 : kernel code segment
- 0x10: kernel data segment
- 0x18: user code segment
- 0x20: user data segment
- 0x28: defined for tss, initialized in gdt_init
定义了【暂时性的?】各个功能段的范围
- 没啥好写就把项目目录下没有怎么提及过的文件的相关功能写一下吧= =
├── boot
│ ├── asm.h
│ ├── bootasm.S
│ └── bootmain.c
├── kern
│ ├── debug【这个文件的功能我还没有完全搞太懂,可能有错】
│ │ ├── assert.h 断言assert的宏实现
│ │ ├── kdebug.c 能打印debug用的相关信息
│ │ ├── kdebug.h
│ │ ├── kmonitor.c 内核的简单控制台
│ │ ├── kmonitor.h
│ │ ├── panic.c 处理致命性错误
│ │ └── stab.h stab相关,【下有stab的描述】
│ ├── driver
│ │ ├── clock.c 时钟芯片相关.h同理
│ │ ├── clock.h
│ │ ├── console.c 处理串口和键盘的中断 .h同理
│ │ ├── console.h
│ │ ├── intr.c 中断使能相关,.h同理
│ │ ├── intr.h
│ │ ├── kbdreg.h 键盘相关
│ │ ├── picirq.c 对PIC初始化,.h同理
│ │ └── picirq.h
│ ├── init
│ │ └── init.c
│ ├── libs
│ │ ├── readline.c 就只实现了从stdin(标准输入流)readline这个函数
│ │ └── stdio.c
│ ├── mm
│ │ ├── memlayout.hcore 操作系统有关段管理(段描述符编号、段号等)的一些宏定义
│ │ ├── mmu.h ucore操作系统有关X86 MMU等硬件相关的定义
│ │ ├── pmm.c 设定段机制相关,.h同理
│ │ └── pmm.h
│ └── trap
│ ├── trap.c 实际中断例程存在的地方
│ ├── trapentry.S 包装好的处理中断例程入口的上下文
│ ├── trap.h 中断号的宏定义,各种trap相关结构体
│ └── vectors.S 中断向量表
├── libs
│ ├── defs.h 宏库,关于数据类型和二进制取整
│ ├── elf.h ELF文件结构声明
│ ├── error.h 宏定义错误类型
│ ├── printfmt.c 格式化print,估计就是作为库文件使用一般的存在了
│ ├── stdarg.h 关于va_list的宏定义【处理变长参数,比如scanf一类的函数】
│ ├── stdio.h IO相关函数的声明
│ ├── string.c 不用说了吧= =
│ ├── string.h
│ └── x86.h 基于X86架构的汇编指令的C语言封装,汇编级别的库函数实现
├── Makefile
└── tools
├── function.mk makefile里的函数
├── gdbinit gdb启动时输入的参数
├── grade.sh 貌似是qemu相关的脚本文件
├── kernel.ld 一个link的脚本,具体作用不祥
├── sign.c elf的格式sign工具
└── vector.c
最后为了方便查询专业词汇,在这边也做个整理吧:
- Stabs: refers to a format for information that describes a program to a debugger. This format was apparently invented by Peter Kessler at the University of California at Berkeley, for the pdx Pascal debugger; the format has spread widely since then.大致就是调试器用的一个符号表?我没有学过编译原理相关,但是估计是那边用到的吧,见识有限,日后补充。
- PIC:Programmable Interrupt Controller可编程中断控制器
- GDT:Global Descriptor Table全局描述符表
- CPL:当前特权级(Current Privilege Level) 保存在CS段寄存器(选择子)的最低两位,CPL就是当前活动代码段的特权级,并且它定义了当前所执行程序的特权级别)
- DPL:描述符特权(Descriptor Privilege Level) 存储在段描述符中的权限位,用于描述对应段所属的特权等级,也就是段本身真正的特权级。
- RPL:请求特权级RPL(Request Privilege Level) RPL保存在选择子的最低两位。RPL说明的是进程对段访问的请求权限,意思是当前进程想要的请求权限。RPL的值由程序员自己来自由的设置,并不一定RPL>=CPL,但是当RPL