?? linux.txt
字號(hào):
代碼重定位部分:含供連接程序使用的記錄數(shù)據(jù),在連接時(shí)用于定位代碼段中的指針和地址。
數(shù)據(jù)重定位部分:同上。
符號(hào)表部分:含供連接程序使用的記錄數(shù)據(jù),用于在各模塊文件間對(duì)變量和函數(shù)(符號(hào))進(jìn)行交叉引用。
字符串表部分:含有與符號(hào)名相對(duì)應(yīng)的字符串(描述信息)。用于調(diào)試。
可重定位項(xiàng)為一條記錄,其中記錄著代碼中某條尋址指令的目的地址值所在的地址,連接時(shí)只需直接修改該可重定位項(xiàng)所指向的位置處的地址即可。
符號(hào)表中的符號(hào)值是該符號(hào)所表示的變量的值在代碼中的地址。
連接程序:首先將各模塊中相同的段組合在一起,并將所有具有非0值的未解析的外部符號(hào)作為公共塊來(lái)看待。隨后進(jìn)行符號(hào)的綁定和代碼修改并進(jìn)行存儲(chǔ)空間分配。
make命令:編譯內(nèi)核(以makefile文件為編譯過(guò)程中的批處理文件),只要在含有makefile文件的目錄下運(yùn)行make命令內(nèi)核就會(huì)進(jìn)行編譯。具體而言,將bootsect.s和setup.s使用8086匯編器進(jìn)行編譯,將其它程序使用GNU的gcc/gas編譯器進(jìn)行編譯,最后將各部分合并成一個(gè)內(nèi)核映象文件image。build.c是一個(gè)輔助內(nèi)核編譯的工具不包含在內(nèi)核中。
system.map中存放了符號(hào)表:符號(hào)地址 類(lèi)型 符號(hào)名
8.內(nèi)存管理(頁(yè)表項(xiàng)結(jié)構(gòu)p553)
linux0.11中,頁(yè)目錄表是系統(tǒng)所有進(jìn)程公用的,而內(nèi)核中的4頁(yè)頁(yè)表(即緊跟在頁(yè)目錄后)則是內(nèi)核專(zhuān)用,對(duì)于新建的進(jìn)程,系統(tǒng)會(huì)在主內(nèi)存區(qū)為其申請(qǐng)頁(yè)面來(lái)存放頁(yè)表。
引起頁(yè)出錯(cuò)中斷(int 14)的幾個(gè)原因:
1.地址變換過(guò)程中用到的頁(yè)目錄項(xiàng)或頁(yè)表項(xiàng)中存在位(p)等于0(需時(shí)加載do_no_pape);
2.當(dāng)前執(zhí)行程序沒(méi)有足夠的特權(quán)訪(fǎng)問(wèn)指定的頁(yè)面(寫(xiě)時(shí)復(fù)制do_wp_page)。
當(dāng)訪(fǎng)問(wèn)某一頁(yè)時(shí),cpu會(huì)“自動(dòng)(非程序,而是CPU體系結(jié)構(gòu)自動(dòng)執(zhí)行的)”置位該頁(yè)所對(duì)應(yīng)頁(yè)表項(xiàng)的“已修改位”和“已訪(fǎng)問(wèn)位”;但是這些位不會(huì)自動(dòng)復(fù)位,需要程序來(lái)手動(dòng)操作(注:頁(yè)目錄項(xiàng)的“已修改位”無(wú)用)。
當(dāng)發(fā)生頁(yè)出錯(cuò)中斷時(shí)cpu會(huì)“自動(dòng)(非程序,而是CPU體系結(jié)構(gòu)自動(dòng)執(zhí)行的)”向頁(yè)出錯(cuò)異常處理程序提供以下兩方面信息:
1.棧中的一個(gè)出錯(cuò)碼(有32位,但只有最低3個(gè)比特有效,具體含義見(jiàn)p555);
2.cr2中存放的引起出錯(cuò)的地址。
頁(yè)出錯(cuò)中斷處理程序根據(jù)上述信息決定調(diào)用的具體操作:
1.do_no_pape卻頁(yè)異常:首先判斷卻頁(yè)原因是否是由于申請(qǐng)新堆棧頁(yè)引起的(即缺頁(yè)地址在進(jìn)程代碼數(shù)據(jù)段范圍之外),若是,則直接分配新頁(yè)并映射該頁(yè)。若不是則說(shuō)明缺頁(yè)發(fā)生在執(zhí)行文件范圍內(nèi)(代碼數(shù)據(jù)段范圍內(nèi),即欲執(zhí)行的代碼數(shù)據(jù)還在文件中尚未加載進(jìn)內(nèi)存)此時(shí),先嘗試頁(yè)面共享(即若有其它進(jìn)程執(zhí)行相同的文件,則嘗試同其它進(jìn)程共享該文件代碼),若失敗則申請(qǐng)一頁(yè)并從設(shè)備上讀入相應(yīng)的數(shù)據(jù)且復(fù)制到新頁(yè)中,然后將新頁(yè)映射到進(jìn)程線(xiàn)性地址中。
2.do_wp_page寫(xiě)保護(hù)函數(shù):首先若欲寫(xiě)入地址在進(jìn)程的代碼段中,則中止進(jìn)程,否則調(diào)用un_wp_page(若欲寫(xiě)入的頁(yè)面非共享,則直接將對(duì)應(yīng)該頁(yè)的頁(yè)表項(xiàng)設(shè)為可寫(xiě);若欲寫(xiě)入的頁(yè)面為共享,則新申請(qǐng)一頁(yè)面,并將原頁(yè)內(nèi)容復(fù)制進(jìn)來(lái),然后使頁(yè)表項(xiàng)指向該新頁(yè)即可)。
mem_map[]字節(jié)數(shù)組,每個(gè)字節(jié)描述一個(gè)"物理內(nèi)存頁(yè)"的占用狀況,其中的數(shù)值表示引用次數(shù),0表示空閑。該數(shù)組從1mb開(kāi)始。初始時(shí)該數(shù)組中對(duì)應(yīng)于主內(nèi)存區(qū)的項(xiàng)被清0,對(duì)應(yīng)于緩沖區(qū)的項(xiàng)被置為100(已占用)p558
重新加載頁(yè)目錄表地址(cr3)即可起到刷新頁(yè)變換高速緩沖器的作用。變換高速緩沖器會(huì)將最近使用的頁(yè)表項(xiàng)保存下來(lái)以提高速度,但若程序?qū)⒛骋辉诰彌_器中有拷貝的頁(yè)表項(xiàng)更改了之后,需手動(dòng)的重刷緩沖器。
創(chuàng)建新進(jìn)程時(shí)會(huì)執(zhí)行copy_page_tables:將父進(jìn)程的頁(yè)表復(fù)制給子進(jìn)程,具體如下:
頁(yè)表的復(fù)制:在主內(nèi)存中申請(qǐng)一新頁(yè),然后將原頁(yè)表內(nèi)容復(fù)制過(guò)來(lái);
頁(yè)目錄項(xiàng)的復(fù)制:在頁(yè)目錄表中新建一項(xiàng),使其指向上面分配的頁(yè)表;
設(shè)置:將原頁(yè)表項(xiàng)和目的頁(yè)表項(xiàng)都設(shè)為只讀;
mem_map:將相應(yīng)的物理頁(yè)引用計(jì)數(shù)加1(mem_map中相應(yīng)項(xiàng)的值加1)。
(注:對(duì)于進(jìn)程0而言只完成上述的1,2步。原因是一方面進(jìn)程0和進(jìn)程1雖然共享同一代碼,但它們執(zhí)行該代碼的不同區(qū)域所以不會(huì)出現(xiàn)沖突;另一方面,mem_map管是low_mem以上的內(nèi)存,而進(jìn)程0和進(jìn)程1的代碼數(shù)據(jù)在low_mem以下。)
頁(yè)表不存在于一般進(jìn)程的空間中,而存在于進(jìn)程0的空間中(0-64mb),即頁(yè)表是獨(dú)立于進(jìn)程的。
給出一個(gè)線(xiàn)性地址,CPU通過(guò)頁(yè)機(jī)制將其轉(zhuǎn)換為物理地的這一過(guò)程中,查詢(xún)頁(yè)表的尋址操作將不使用頁(yè)機(jī)制。
9。c語(yǔ)言函數(shù)調(diào)用機(jī)制(p129--p133)
函數(shù)調(diào)用返回時(shí)由調(diào)用者自動(dòng)丟棄堆棧上的參數(shù)。
int abc(int a)以此為例,abc本身也是一個(gè)地址和一般的變量類(lèi)似。故函數(shù)指針和一般的變量指針也類(lèi)似。
10.中斷;異常;系統(tǒng)調(diào)用
異常:打印出一些信息并中止程序
系統(tǒng)調(diào)用:相應(yīng)的功能調(diào)用
中斷:相應(yīng)的功能調(diào)用
在某一用戶(hù)態(tài)中發(fā)生上述情況中的一種時(shí):首先CPU“自動(dòng)”將SS:ESP堆棧寄存器,SFLAGS,CS:EIP指令寄存器壓入堆棧,然后在中斷向量表中找到相應(yīng)的處理程序的入口地址,然后“自動(dòng)”加載內(nèi)核的CS及SS(CS寄存器在發(fā)生任何遠(yuǎn)跳轉(zhuǎn)時(shí)會(huì)自動(dòng)重加載)。然后手動(dòng)加載內(nèi)核的DS,ES。
內(nèi)核態(tài)中的進(jìn)程能接受中斷,但不能接受進(jìn)程調(diào)度。
**p:當(dāng)一個(gè)程序調(diào)用另一個(gè)程序時(shí),若參數(shù)為int i則被調(diào)用函數(shù)不能修改i的值;若參數(shù)為int *i則被調(diào)用函數(shù)可修改i的值(但不能修改i指針的值);若參數(shù)為int **i則被調(diào)用函數(shù)可些改i的值且可修改i指針的值。
11.信號(hào)處理
在進(jìn)程每次調(diào)用系統(tǒng)調(diào)用或發(fā)生時(shí)鐘中斷時(shí),若進(jìn)程已收到信號(hào),則信號(hào)預(yù)處理程序會(huì)將用戶(hù)自定義的信號(hào)處理程序置為iret的返回地址(即進(jìn)程處理完系統(tǒng)調(diào)用或時(shí)鐘中斷后,返回到用戶(hù)態(tài)時(shí),將直接返回到自定義的信號(hào)處理程序處),隨后通過(guò)一個(gè)函數(shù)指針(參數(shù)restorer)跳轉(zhuǎn)到善后程序(在編譯連接時(shí)由libc函數(shù)庫(kù)提供,非內(nèi)核程序,用于將信號(hào)處理程序;的返回地址及
返回的上下文設(shè)為用戶(hù)進(jìn)程剛執(zhí)行系統(tǒng)調(diào)時(shí)的上下文)。
在將字符從用戶(hù)緩沖區(qū)寫(xiě)入字符設(shè)備輔助緩沖隊(duì)列(或反之)時(shí),如遇到有待處理信號(hào)則直接退出讀寫(xiě)函數(shù),返回讀寫(xiě)出錯(cuò)標(biāo)志。
12.硬盤(pán)(p280圖)
hd_infor結(jié)構(gòu):存放硬盤(pán)信息,該信息來(lái)源于cmos供16季節(jié),包括(柱面數(shù),磁頭數(shù),寫(xiě)前預(yù)補(bǔ)償柱面號(hào),控制字節(jié),磁頭著陸區(qū)柱面號(hào),每磁道扇區(qū)數(shù))
hd結(jié)構(gòu):存放硬盤(pán)分區(qū)表信息,該信息來(lái)原于硬盤(pán)引導(dǎo)扇區(qū)446字節(jié)處的硬盤(pán)分區(qū)表(見(jiàn)p278),包括:(起始扇區(qū),長(zhǎng)度)
do_hd_request:第一次運(yùn)行時(shí),直接向硬盤(pán)控制器發(fā)出相應(yīng)的命令,隨后返回。過(guò)一會(huì)當(dāng)硬盤(pán)控制器執(zhí)行完命令后會(huì)發(fā)出一個(gè)中斷(向硬盤(pán)控制器發(fā)命令時(shí)將會(huì)設(shè)置與該命令對(duì)應(yīng)的中斷處理程序),中斷處理程序會(huì)出現(xiàn)3個(gè)分支:分支1出錯(cuò)(此時(shí)進(jìn)一步判斷出錯(cuò)的次數(shù),較少則調(diào)用do_hd_request重發(fā)命令,較多則調(diào)用do_hd_request發(fā)送復(fù)位硬盤(pán)。命令(硬盤(pán)執(zhí)行該命令后也會(huì)產(chǎn)生中斷,并執(zhí)行相應(yīng)的處理程序),太多則廢棄該請(qǐng)求項(xiàng)并退出;分支2正確但未完(緩沖區(qū)指針后移,并退出中斷處理程序,等待下一個(gè)中斷的到來(lái));分支3正確且完成(喚醒等待進(jìn)程,并開(kāi)始執(zhí)行下一個(gè)請(qǐng)求項(xiàng))。
引導(dǎo)扇區(qū)結(jié)構(gòu):p278
緩沖區(qū):緩沖區(qū)中的一塊與硬盤(pán)中的一塊向?qū)?yīng),當(dāng)進(jìn)行硬盤(pán)讀寫(xiě)操作時(shí)若預(yù)讀寫(xiě)的硬盤(pán)塊在緩沖區(qū)中有對(duì)應(yīng)的塊,則直接對(duì)緩沖區(qū)讀寫(xiě)。
一次成功的讀寫(xiě)硬盤(pán)操作后該緩沖塊的uptodate標(biāo)志將置1,此時(shí)再對(duì)該緩沖塊所對(duì)應(yīng)的硬盤(pán)塊進(jìn)行讀操作時(shí),將直接從緩沖塊中去讀取。
13.鍵盤(pán)
8042鍵盤(pán)控制芯片(p345)
每當(dāng)鍵盤(pán)按下時(shí)會(huì)發(fā)送一個(gè)掃描碼(1<<7+按鍵的碼);釋放時(shí)也會(huì)發(fā)送一個(gè)掃描碼(0<<7+按鍵的碼)
當(dāng)用戶(hù)按下一個(gè)按鍵時(shí):首先鍵盤(pán)向鍵盤(pán)控制器發(fā)送該鍵的掃描碼,然后當(dāng)鍵盤(pán)控制器收到掃描碼后向8259A發(fā)鍵盤(pán)中斷,然后調(diào)有鍵盤(pán)處理程序,然后當(dāng)鍵盤(pán)處理程序處理完畢后重置鍵盤(pán)(先關(guān)再開(kāi)),并向8259A發(fā)EOI結(jié)束本次中斷。
鍵盤(pán)處理程序:根據(jù)掃描碼直接調(diào)用相應(yīng)的子程序(對(duì)于一般按鍵則直接將其轉(zhuǎn)換為字符并存入緩沖隊(duì)列;對(duì)于像ctrl,shift,alt這種控制鍵則僅僅將標(biāo)志字段中的相應(yīng)位置位;對(duì)于像F1,F2這種功能鍵則將其轉(zhuǎn)化為相應(yīng)的字符序列并存入緩沖隊(duì)列中),然后將讀緩沖隊(duì)列中的數(shù)據(jù)進(jìn)行格式轉(zhuǎn)換,并存放到輔助隊(duì)列中。
14.顯示
控制臺(tái)方式下欲在屏幕上顯示字符:首先將欲顯示的字符存入設(shè)備的寫(xiě)緩沖隊(duì)列write_q中,然后將寫(xiě)緩沖隊(duì)列中的字符經(jīng)過(guò)轉(zhuǎn)換后(如回車(chē)字符轉(zhuǎn)換為一行空格)寫(xiě)入顯存。對(duì)于控制臺(tái)而言顯示的實(shí)質(zhì)其實(shí)就是將欲顯示的字符放入顯存中(顯存可看成是一個(gè)邏輯上的屏幕),然后顯示控制器會(huì)自動(dòng)的從顯存中讀出數(shù)據(jù)并顯示到屏幕上,欲修改屏幕上的內(nèi)容只需直接修改相應(yīng)顯存中的內(nèi)容即可
15.終端(p327)
字符設(shè)備文件的i_zone[0]中存放著該設(shè)備的設(shè)備號(hào),其對(duì)應(yīng)于tty_table[]數(shù)組中的索引號(hào)(tty_table[]中的每一項(xiàng)為一個(gè)tty_struct),即一個(gè)設(shè)備字符文件對(duì)應(yīng)于一個(gè)tty_struct對(duì)應(yīng)一個(gè)設(shè)備。
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -