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