任务:阅读实验一makefile 搞清楚ucore.img是如何构建的html
$@ $< $^ 这三个变量分别是什么意思 https://blog.csdn.net/YEYUANGEN/article/details/36898505linux
=和:=的区别 https://stackoverflow.com/questions/448910/what-is-the-difference-between-the-gnu-makefile-variable-assignments-agit
dd命令 http://www.runoob.com/linux/linux-comm-dd.htmlgithub
call命令web
通配符apache
$(call create_target,ucore.img)不懂,create_target是内置函数?segmentfault
makefile教程:https://blog.csdn.net/special00/article/details/51084619 包含call 函数调用的说明数组
找到一个TsingHua大佬在github的实验:https://github.com/dongyp13/os_lab/blob/master/labcodes/lab1/lab1-%E8%91%A3%E8%83%A4%E8%93%AC.md数据结构
GCC的-fno-builtin选项 https://blog.csdn.net/baiyu9821179/article/details/73007124函数
-gstabs
此选项以stabs格式声称调试信息,可是不包括gdb调试信息.
-gstabs+
此选项以stabs格式声称调试信息,而且包含仅供gdb使用的额外调试信息.
-ggdb
此选项将尽量的生成gdb的可使用的调试信息.
GCC选项-g和-ggdb的区别 https://my.oschina.net/moooofly/blog/493859
Linux 中的 cc 命令 https://blog.csdn.net/candy060403/article/details/7519370
-nostdinc不要在标准系统目录中寻找头文件.只搜索`-I'选项指定的目录(以及当前目录,若是合适).
结合使用`-nostdinc'和`-I-'选项,你能够把包含文件搜索限制在显式指定的目录.
-fstack-protector:
启用堆栈保护,不过只为局部变量中含有 char 数组的函数插入保护代码。
-fstack-protector-all:
启用堆栈保护,为全部函数插入保护代码。
-fno-stack-protector:
禁用堆栈保护。
有关堆栈保护内容 https://www.ibm.com/developerworks/cn/linux/l-cn-gccstack/index.html
-Idir在头文件的搜索路径列表中添加dir 目录.
-I-任何在`-I-'前面用`-I'选项指定的搜索路径只适用于`#include "file"'这种状况;他们不能用来搜索`#include <file>'包含的头文件.
若是用`-I'选项指定的搜索路径位于`-I-'选项后面,就能够在这些路径中搜索全部的 `#include'指令. (通常说来-I选项就是这么用的.)
还有, `-I-'选项可以阻止当前目录(存放当前输入文件的地方)成为搜索`#include "file"'的第一选择.没有办法克服`-I-'选项的这个效应.你能够指定 `-I.'搜索那个目录,它在调用编译器时是当前目录.这和预处理器的默认行为不彻底同样,可是结果一般 使人满意.
`-I-'不影响使用系统标准目录,所以, `-I-'和`-nostdinc'是不一样的选项.
-Ldir在`-l'选项的搜索路径列表中添加dir目录.
关于fno-builtin和fno-builtin-function编译选项
https://blog.csdn.net/SstudentT/article/details/52910696
CLI https://en.wikipedia.org/wiki/Interrupt_flag
CLD https://en.wikipedia.org/wiki/Direction_flag#cite_note-1
A20地址线 https://blog.csdn.net/ruyanhai/article/details/7181842
gdb 跳过当前断点进入下一个断点时别忘了输入 c
fwrite和fread函数的用法小结 https://blog.csdn.net/sky_qing/article/details/12783045
100个gdb小技巧 https://wizardforcel.gitbooks.io/100-gdb-tips/print-registers.html
(伪,不肯定)代码说明指令行为:x86 Instruction Set Reference https://c9x.me/x86/
Makefile 中命令的@,-@,+@符号 做用 https://blog.csdn.net/elfprincexu/article/details/51886620
实模式切换到保护模式,为何要开启A20地址线(系统升级产生的兼容性问题)https://blog.csdn.net/PacosonSWJTU/article/details/48005813
某位大佬ucore实验1-3 https://blog.csdn.net/winkar/article/details/40017573
(硬件信息比较详细)ucore操做系统实验笔记 - Lab1-3 https://segmentfault.com/a/1190000009386091
某位大佬ucore实验1-8 https://blog.csdn.net/qq_19876131/article/details/51706973
ucore实验之操做系统启动流程 http://blog.xiaohansong.com/2015/10/02/ucore%E5%AE%9E%E9%AA%8C%E4%B9%8B%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%90%AF%E5%8A%A8%E6%B5%81%E7%A8%8B/
ucore实验结构和ex实验?http://os.cs.tsinghua.edu.cn/oscourse/ucore/2016
某位大佬ucore实验1-8 https://blog.csdn.net/ni9htmar3/article/category/6793322
ucore的makefile部分解释 https://blog.csdn.net/u013484370/article/details/50638353
ucore 1-8 https://blog.csdn.net/tangyuanzong/article/category/7110079
ucore2,3,4,6 https://blog.csdn.net/th_num/article/category/6148598
ucore1-8 https://blog.csdn.net/cs_assult/article/category/3273629
操做系统:ucore的部分Bug&挑战练习 https://blog.csdn.net/He11o_Liu/article/details/54028501
全局描述符表格式:https://blog.csdn.net/yuzhihui_no1/article/details/42386915
分段模式:https://www.csie.ntu.edu.tw/~wcchen/asm98/asm/proj/b85506061/chap2/segment.html
asm.h中 .word是什么意思:.word就是在这个地方放一个值。至关于在这里定义一个数据变量。用.word定义了一个16bit的数据。http://sdnydubing.blog.163.com/blog/static/13747057020112904958830/
.byte应该就是8bit的数据变量吧?http://qvb3d.iteye.com/blog/1172510
段描述符:https://blog.csdn.net/longintchar/article/details/50489889
段描述符:http://guojing.me/linux-kernel-architecture/posts/segment-descriptor/
初始化各类段描述符:https://www.cnblogs.com/pacoson/p/4893177.html
关于asm.h 中的汇编宏
#define SEG_ASM(type,base,lim) \
.word (((lim) >> 12) & 0xffff), ((base) & 0xffff); \
.byte (((base) >> 16) & 0xff), (0x90 | (type)), \
(0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff)
这个是声明了两个16bit的数据变量和4个8bit的数据变量
段描述符是上下两条 一共64bit
关于上面这个汇编宏是考虑了大小端的,此处考虑x86是小端模式,即高位高地址,低位低地址,而后存的时候咱们默认先从内存的低地址开始存
ljmp的含义:
0xffff0: ljmp $0xf000,$0xe05b
也就是说,BIOS开始的地址应该是 $cs << 4 | 0xe05b = 0xfe05b
# ljmp <imm1>, <imm2> # %cs ← imm1 # %ip ← imm2
关于ljmp:
(7) |
远程的转移指令和子程序调用指令的操做码名称,在AT&T格式中为“ljmp”和“lcall气而 在Intel格式中,则为"JMP FAR"和"CALL FAR"。当转移和调用的目标为直接操做数时, 两种不一样的表示以下: CALL FAR SECTION:OFFSET (Intel格式) JMP FAR SECTIOM:OFFSET (Intel格式) lcall $section, $offset (AT&T格式) ljmp $section,$offset (AT&T格式) 与之相应的远程返回指令,则为: RET FAR STACK_ADJUST(Intel格式) lret $stack_adjust (AT&T格式) |
因为咱们要将实模式切换为保护模式,因此要关掉A20地址线,A20地址线的关闭要经过与Intel 8042控制器进行通讯来实现
主要用到8042的两个端口
PS/2 compatibles.
IO Port | Access Type | Purpose |
---|---|---|
0x60 | Read/Write | Data Port |
0x64 | Read | Status Register |
0x64 | Write | Command Register |
而后0x64是命令端口,0x60是数据端口
进行操做时要首先考虑该设备的状态信息,即缓冲区是否为空
Bit | Meaning |
---|---|
0 | Output buffer status (0 = empty, 1 = full) (must be set before attempting to read data from IO port 0x60) |
1 | Input buffer status (0 = empty, 1 = full) (must be clear before attempting to write data to IO port 0x60 or IO port 0x64) |
2 | System Flag Meant to be cleared on reset and set by firmware (via. PS/2 Controller Configuration Byte) if the system passes self tests (POST) |
3 | Command/data (0 = data written to input buffer is data for PS/2 device, 1 = data written to input buffer is data for PS/2 controller command) |
4 | Unknown (chipset specific) May be "keyboard lock" (more likely unused on modern systems) |
5 | Unknown (chipset specific) May be "receive time-out" or "second PS/2 port output buffer full" |
6 | Time-out error (0 = no error, 1 = time-out error) |
7 | Parity error (0 = no error, 1 = parity error) |
流程是,检查状态,缓冲区为空就写入命令端口,再次检查状态,缓冲区为空就写入数据端口将A20地址线标志位置位关闭
BIOS是系统本身的固件,不用管,当BIOS启动后的某一个阶段会将ucore.img?load 到0x7c00,而后将控制权交给0x7c00
而0x7c00后面就是咱们的bootasm.S以及后面调用的bootmain.c合并以后的汇编代码
bootasm.S将A20关闭,定义了代码段和数据段的GDT表项,而后将栈空间定义为0x0000到0x7c00而且在这里呼叫了bootmain.c中的bootmain函数
bootmain在干什么尚不清楚,稍后研究。更新:bootmain是用来将文件kernel(elf格式)加载到内存中去,也就是解析elf格式的内核文件,elf:executable linkable file
bootmain连续加载了磁盘扇区(位于bootloader后面的连续的四个扇区),而后进行elf的解析
系统启动流程
1.系统加电 BIOS初始化硬件
2.BIOS读取主引导扇区代码
3.主引导扇区的代码读取活动分区的引导扇区代码
4.引导扇区的代码读取文件系统中的加载程序
加载程序bootloader
1.从文件系统中读取启动配置信息(加载程序)
2.启动菜单:可选的操做系统内核列表和加载参数
3.依据配置加载指定内核并跳转到内核执行
IRQ Numbers:https://www.webopedia.com/quick_ref/IRQnumbers.asp
中断向量符表:http://guojing.me/linux-kernel-architecture/posts/interrupt-descriptor-table/
又一位大佬(UESTC)的ucore实验1:http://xr1s.me/2018/05/15/ucore-lab1-report/
貌似gdb target连接qemu以后只能si调试了???https://github.com/chyyuu/ucore_os_lab/issues/39
calltree 查看函数调用 http://blog.51cto.com/chenqin/977113
各类段寄存器:https://wiki.osdev.org/CPU_Registers_x86#EFLAGS_Register
pusha指令:https://blog.csdn.net/ross1206/article/details/72831209 https://c9x.me/x86/html/file_module_x86_id_270.html
trapframe数据结构:http://www.cnblogs.com/fanzi2009/archive/2011/04/07/2008144.html
IBM内联汇编教程:https://www.ibm.com/developerworks/cn/linux/sdk/assemble/inline/index.html
中断指令以及中断和异常控制在x86手册的位置:https://c9x.me/x86/html/file_module_x86_id_142.html