OS Lab1 Code Review
wzk
文件树
 ├── boot
 │   ├── Makefile
 │   ├── start.o
 │   └── start.S
 ├── drivers
 │   ├── gxconsole
 │   │   ├── console.c
 │   │   ├── console.o
 │   │   ├── dev_cons.h
 │   │   └── Makefile
 │   └── Makefile
 ├── gxemul
 │   ├── elfinfo
 │   ├── r3000
 │   ├── r3000_test
 │   ├── test
 │   └── vmlinux
 ├── include
 │   ├── asm
 │   │   ├── asm.h
 │   │   ├── cp0regdef.h
 │   │   └── regdef.h
 │   ├── asm-mips3k
 │   │   ├── asm.h
 │   │   ├── cp0regdef.h
 │   │   └── regdef.h
 │   ├── env.h
 │   ├── error.h
 │   ├── kclock.h
 │   ├── mmu.h
 │   ├── pmap.h
 │   ├── printf.h
 │   ├── print.h
 │   ├── queue.h
 │   ├── sched.h
 │   ├── stackframe.h
 │   ├── trap.h
 │   └── types.h
 ├── include.mk
 ├── init
 │   ├── init.c
 │   ├── init.o
 │   ├── main.c
 │   ├── main.o
 │   └── Makefile
 ├── lib
 │   ├── Makefile
 │   ├── print.c
 │   ├── printf.c
 │   ├── printf.o
 │   └── print.o
 ├── Makefile
 ├── readelf
 │   ├── kerelf.h
 │   ├── main.c
 │   ├── main.o
 │   ├── Makefile
 │   ├── readelf
 │   ├── readelf.c
 │   ├── readelf.o
 │   ├── testELF
 │   └── types.h
 └── tools
     └── scse0_3.lds
MakeFile
文件开头定义了模块modules(boot、drivers、init、lib等目录)以及对应的.o文件objects
首先对每个子文件夹(模块)执行make,然后使用linker script将所有.o文件链接起来生成vmlinux内核。
Clean:进入每个子目录调用make clean,并删去所有.o文件以及vmlinux文件
include.mk
定义了交叉编译器gcc的路径和一些宏
readelf
types.h:定义了数据类型(u_int8_t等)和一些运算(最小值、rounding、offset、static_assert)
kerelf.h:首先定义了Elf32_word等数据类型,然后定义了Elf32_Ehdr(ELF头)、Elf32_Shdr(section header)、Elf32_Phdr(program header)的结构、segment type的宏定义(pt_null等)
readelf.c:首先判断是不是ELF文件(检查幻数),然后根据大小端(lab1-extra)输出各个segment的序号、文件大小、空间大小(作业)
main.c:接受文件名作为参数,读取文件调用readelf函数
Makefile:交叉编译main.c readelf.c生成main.o和readelf.o,最后生成可执行文件readelf;clean清除.o文件和readelf
tools
scse0_3.lds:即Linker Script,设定MIPS结构,设定程序入口为_start,设定.text、.data、.bss的地址(作业)
boot
start.S:引用regdef.h、cp0regdef.h、asm.h三个头文件,定义了内核栈空间的地址,调用Leaf(_start)函数,用.set设定汇编器,关闭中断,关闭监视异常,关闭内核态缓存,设定sp寄存器栈地址,跳转到main函数(作业),调用End(_start)
Makefile:交叉编译start.S,clean清除start.o
lib
printf.c:printf函数将接受的输出参数传递给print.c里的lp_Print函数,后者传递输出至myoutput;myoutput里调用printcharc(在gxconsole.c);va_list,va_start,va_end用于接受可变个数参数,panic用于测试
print.c:扫描字符串,识别%及标识符时按照需要打印(作业)。其中用到了PrintChar、PrintNum、PrintString函数确定输出个数和缓冲区内容。
Makefile:交叉编译print.c printf.c,clean清除.o文件
init
main.c:include pmap.h和printf.h。main函数调用printf函数输出,调用init.c中的mips_init(),出错时调用panic函数输出
init.c:include asm.h pmap.h env.h printf.h kclock.h trap.h。mips_init函数打印,调用FTEST、ENV_CREATE(PTEST),输出”^^^^^“
Makefile:交叉编译init.c main.c,clean清除.o文件
gxemul
gexmul硬件模拟器组件及生成的vmlinux内核文件
drivers
gxconsole/console.c:printcharc函数将待打印的字符放在PUTCHAR_ADDRESS,即可完成字符输出;printstr函数循环调用printcharc输出字符串;halt函数将HALT_ADDRESS地址的值设为0从而暂停
gxconsole/dec_cons.h:定义了gxemul模拟器的各个地址,用来计算PUTCHAR_ADDRESS等
gxconsole/Makefile:交叉编译console.o,clean清除.o文件
Makefile:进入gxconsole文件夹执行make或clean
include
asm/asm.h:汇编器宏,增加可读性,包括LEAF(定义了不调用其他函数的叶子函数)、NESTED(声明嵌套路径)、END(定义函数尾部)、EXPORT(标签)、FEXPORT(函数标签)
asm/regdef.h:定义了32个寄存器的宏,s0、t1、sp等
asm/cp0regdef.h:定义了cp0的30个寄存器的宏
env.h:定义了创造环境、环境状态有关的宏和环境结构,包括一些Lab4、Lab6需要的内容
error.h:定义了一些异常的宏
kclock.h:定义时钟端口
mmu.h:先定义了MIPS概念(一页的字节数、虚拟地址的虚页号部分、页表标识),注释中表明了MIPS内存空间,然后是一些宏(内核栈顶、内核栈大小等)、帮助函数(实地址到虚地址的转换、断言等)
pmap.h:定义了页的结构、页 页号 虚拟地址物理地址的转换,声明了很多页相关的函数(以后完成?)
printf.h:定义panic函数(就是把stdargs标准库中文件、行这些参数传入_panic函数)
print.h:定义了printf的最大长度,声明了lp_Print函数(实体在print.c)
queue.h:定义了列表、尾队列、循环队列三种数据结构
sched.h:声明了几个sched(时间表?)有关的函数
stackframe.h:定义了栈帧的一些宏,用来操作sp栈指针
trap.h:定义了trap(陷入)的相关宏,如除零错误、断点、溢出、非法opcode、pagefault、系统调用,以及Trapframe初始化、Trapframe寄存器等
types.h

                
            
        
浙公网安备 33010602011771号