任務:閱讀實驗一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