linux核心學習筆記(一)

來源:互聯網
上載者:User
 

liunx網友學習文章(1)     2007-04-02 18:59:06 大 中 小

目錄:
1.學習bootsect.s中經常會問到的問題 轉自oldlinux論壇
2.系統調用及參數傳遞過程 
3. 調度器工作時機:office"
4.虛擬機器VMWARE與其網路設定(包你玩轉虛擬機器)


1.學習bootsect.s中經常會問到的問題 轉自oldlinux論壇

這個是我學習bootsect.s檔案時,看完了本版關於bootsect檔案後彙集了一下。
有些問題實在是書上很明顯的地方,我就沒有摘錄上去
有些問題實在和bootsect這個代碼沒有關係,我也沒有摘錄上去

都是大家問的問題,也是自己最想問的問題。我看了幾遍依然還是有很多問題。
其實很多問題,以前大家都問過了,確實是這樣的。

查閱很方便,都是按照行號來的!
----------------------------------------

關於bootsect.s中出現的移位指令
-------------------------------------------------------
運算元的長度用加在指令後的符號表示b(byte, 8-bit), w(word, 16-bits), l(long, 32-bits),如“movb %al, %bl”,“movw %ax, %bx”,“movl %eax, %ebx ”。

如果沒有指定運算元長度的話,編譯器將按照目標運算元的長度來設定。
比如指令“mov %ax, %bx”,由於目標運算元bx的長度為word,那麼編譯器將把此指令等同於“movw %ax, %bx”,指令“mov $4, %ebx”等同於指令“movl $4, %ebx”,“push %al”等同於“pushb %al”。

對於沒有指定運算元長度,但編譯器又無法猜測的指令,編譯器將會報錯,比如指令“push $4”。
======================================

L25 .globl begtext,begdata,begbbs,endtext,enddata,endbbs
L26 .text
L27 begintext:
L28 .data
L29 begdata:
L30 .bss
L31 begbbs:
L32 .text
...
.....
.......
L255 .text
L256 endtext:
L257 .data
L258 enddata:
L259 .bss
L260 endbbs:

Q:
可以看出.text .data .bss重疊的,我的疑問是在模組串連時,.text 和其他模組的.text合并,.data和其他模組的.data合并,那不會出現問題?
還有就是文法問題,為什麼.text會出現3次?
-------------------------------------------------------------------------------
A:
重疊段的用法通常只用於單個檔案。
前後兩個.text開始text段並起定義段“標號”的用途,這樣在帶符號調試時可以分清。bootsect和setup都單獨編譯連結,不與其他目標檔案合并。在組建核心Image檔案時,tools/build.c檔案會直接把他們去除各自的頭結構後順序組合在一起。.text就定義其後面的代碼在. text段中。若後面又出現其他.XXXX,則表示.XXXX後面開始是XXXXX段中的代碼或資料。
###########################################################################

最近我在學習as彙編,瞭解了分段方面的知識。但在閱讀bootsect.s檔案時產生了疑問
整個檔案的結構是這樣的
.globl begtext,begdata,begbbs,endtext,enddata,endbbs
.text
begintext:
.data
begdata:
.bss
begbbs:
.text
...
.....
.......
.text
endtext:
.data
enddata:
.bss
endbbs:
Q:我不理解這種分段的方法,難道linus為了把程式碼片段和資料區段編譯在一個段內?
即便如此,為什麼最後還要有endtext等標示符?
-----------------------------------------------------------
A: bootsect程式都統統放在512位元組之內。在這麼小的地方沒有必要分離各個sections。
標號begtext和endtext可分別用來指明text段的開始和結束。

##########################################################################
25 .globl begtext, begdata, begbss, endtext, enddata, endbss
26 .text
27 begtext:
28 .data
29 begdata:
30 .bss
31 begbss:
32 .text

Q: 我看了一下MASM的文法,然後又看了一下as86的協助,但是不知道上面幾句話到底起什麼作用,在MASM中有定義段的語句,正好對應段寄存器, as86的協助上說.text,.data是置當前段(set current segment)我想跟MASM中的某些語句相當,但是.text和.bss對應什麼段寄存器呢?另外as86中好像沒有看到像MASM那樣在原始碼中分段,是不是as86在彙編的時候自動根據原始碼來劃分相應段?

A:這些偽指令是供編譯器使用的。這些標號供ld86使用。
.text指明程式中的程式碼片段;.data是資料區段;.bss是未初始化的資料區。
注意,上面的“段”的含義並不是段寄存器的意思,它只是指明目標檔案或執行檔案中的代碼或資料區(塊)。其中對於硬碟上的執行檔案來講不含bss,只有到了執行檔案被載入到記憶體中時才會為其分配bss段(區),並且位於data段的後面。
連結程式(例如ld)會使用這些偽指令把所有連結模組中的這些段都分別組合在一起,從而在輸出檔案中形成已經組合過的代碼和資料部分。這方面的內容可以參考:
http://www.oldlinux.org/cgi-bin/LB5000XP/topic.cgi?forum=1&topic=1139&show=25

########################################################################
Q: 在啟動的檔案中定義的幾個globl變數沒有使用是不是可以不要啊
我在閱讀過程中看不出這幾個globl變數有什麼用啊
----------------------------------------------------------------------
A: 一般情況下或者需要使用你自己指定的全域變數時不能不要.global。但是我你的所有段都是重疊的並且不使用除了連結器使用的幾個全域變數時,就可以省略它們。例如,你可以把bootsect.s和setup.s中的.global定義都去掉。
#######################################################################

Q:下面代碼和上面代碼的效果等價嗎?
.globl begtext,begdata,begbbs,endtext,enddata,endbbs
.text
begintext:
begdata:
begbbs:
...
.....
.......
endtext:
enddata:
endbbs:

A: 你還需要在.text後給出.data、.bss

==============================================================================
3.
L43  ROOT_DEV=0X306 !指定檔案系統裝置是第2個硬碟的第一個分區。
Q:
如果核心程式和檔案系統安裝在同一個硬碟裡時,是否需要把ROOT_DEV=0X301 /dev/hda1?換成第一個硬碟的第一個分區.
還有程式中load setup、取每個磁軌扇區數等時,也需要把磁碟機代號改成讀硬碟標識?
A:
1. 如果要安裝在同一個分區中,那麼就需要使用專用獨立的能從檔案系統中取得核心Image檔案並載入的引導軟體。例如,shoelace,grub,lilo等。本站有人已經自己做了一個專門的。請參考第2個分論壇中(精華區)。
2. 你說的沒錯。很多(基本上全部:)都沒用,可刪除。不過從這點可以看出Linus當時也在不斷學習其他人的東東
L43  ROOT_DEV = 0x306   ! 0x306-/dev/hd6-第2個硬碟的第1個分區
Q:
為什麼ROOT_DEV要指向第2個硬碟的第1個分區,而不是第一個硬碟或者其他分區?有什麼特別的道理嗎?
A:
因為當時Linus的機器上有兩個硬碟,而他使用第2個硬碟來開發Linux系統,第1個硬碟上安裝的是MINIX系統。

==============================================================================

L51   mov cx #256
       sub si si
       sub di di
       rep
       movw
Q:
將bootsect.s的模組移到0x90200處,請問怎麼知道bootsect.s彙編好後是256個字?
A:
在bootsect.s最後有:
249L  .org 508
表示249行後面的代碼從508個位元組處開始,再往下:
.word ROOT_DEV
.word 0xAA55
共4個位元組,所以整個檔案大小就是508+4=512個位元組。
Linus在這裡用了.org也可以採用填充0的方法,不論怎樣,總要使512位元組的最後兩個位元組是55 AA(用word表是就是AA55了)

==============================================================================
L56 jmpi go,INITSEG
L57 go: mov ax,cs
jmpi的文法是jmpi 段值,段內位移
Q:
在彙編裡好象標號指的是段內位移,所以此處的標號go應該是一個段內位移,感覺是不是有點問題啊??
A:
“jmpi的文法是jmpi 段值,段內位移”--沒錯,這是as86的文法。

==============================================================================
L77  j   load_setup
Q:
是否應為:  jmp load_Setup?
A:
不是印刷錯誤,LD86中就有j這條指令,等價於JMP

==============================================================================
L81 <注釋> 利用INT 0x13的第8號子功能讀取磁碟機參數,入口參數ah=0x08,dl=磁碟機代號(如果是硬碟則要置位7為1)
Q:
磁碟機代號是誰分配的,又是怎麼分配的,為啥硬碟要置位7為1?
A:
是IBM PC機BIOS就這樣規定設計的。

==============================================================================
L87 seg cs  !表示下一條語句的運算元在cs段寄存器所指的段中
Q:
在bootsect.s 中定義了sectors, root_dev, sread,head,track等標誌符,但是在運算元中含有sectors, root_dev時,需要seg cs, 而運算元含有sread,head,track時,之前卻不用加seg cs,why?
A:
你仔細看一下會發現,其實所有"seg cs"指令都無用。因為這個程式被串連在一個段中,即代碼、資料區段都在一起。Linus當時開發時所用的讀盤程式可能是單獨編寫的,或者是從網上下載後修改的。

L87  seg cs
L88  mov sectors,cx
Q:
語句的意思很好理解,但是這時DS與CS段是一樣的,是否這裡不加87行語句也是可以的呢?
A:
seg cs可以不用。

==============================================================================
L94 mov ah,0x03
L95xor bh,bh
L96int ox10
A:
第94到96行的語句,是否是顯示串前必須做的呢?我以前在核心的代碼裡加調試語句時是沒有先讀游標位置的。是否是第一次顯示時讀一次就可以了
Q:
94-96是必須的。用於設定int 0x10調用功能0x13使用的行列值(dx中,串開始位置)。
若調用串顯示函數時al的最低位元位=1(al=1或3),則游標會在顯示串後被設定在串的結尾處。否則若al=0或2,則在顯示後游標位置不動

==============================================================================
L99 mov bx,#0x0007  !page 0,attribute 7 (normal)
Q:bl=0x07,有什麼作用?
A:這是顯示參數,請參考VGA顯示卡資料。

==============================================================================
L153  test ax,#0x0fff
Q:
(1)#0x0fff為啥不是#0x1000呢?
(2)這一步是不是多餘呀,因為ax肯定是0x1000,為什麼還要測試?出了什麼錯才會導致ax和es不等於0x1000?
A:
(1)TEST指令:兩運算元相與不儲存結果,只儲存特徵條件碼(影響Flag標誌)。
這句測試所有三個0xf代表的12個位元位應該都為零。若都為0則段值肯定是0xN000,對應段的地址肯定是0xN0000,也即位於64KB邊界上。
(2)因為這是個子程式,它有自己的介面要求。加上這種判斷是良好的編程習慣

==============================================================================
L170xor ax,ax 
L171sub ax,bx
L172shr ax,#9

Q:
170 行的代碼有疑問,程式跳轉到read_it 子程式裡時,要完成把磁碟裡的資料讀入到記憶體中0x10000地址開始的地區中,整個讀的過程是先檢測本磁軌中剩下的扇區所包含的位元組總數是不是可以完全放到當前的64K記憶體段裡,如果當前的64K記憶體段裡放不下,就會執行到170行這個地方,170行來了句
xor ax,ax 
sub ax,bx
shr ax,#9
這幾行代碼是想獲得可以讀到當前的64K記憶體段的扇區個數,存放在al裡
對這個地方,我有一點不解,如果是第一次讀,bx就應該是0了,那ax也是0,結果最後al裡面也是0了,那下面緊接著就調用INT 13號中斷讀磁碟,al 在13號中斷裡的含義是從磁碟讀出的扇區的個數,當al=0時,不知道這個中斷是怎麼執行的??
我查了手冊,手冊上也沒講INT 13號中斷的2號子功能調用,在當al=0時調用的結果是什麼,手冊上只是說了,al的值在1-128之間是有效,我就不知道上面講的那種情況INT 13號中斷是怎麼處理的了?
A:
第1 次讀時bx確實是0,但ax不是0。因為sread最初是1+SETUPLEN,即5。因此(80 - 5)*512 = 38400 = 37.5KB 沒有超過64KB,所以第1次不會執行170行開始的代碼。由於16位寄存器最大隻能表示64KB -1,因此這裡0表示最大值64KB(已進位)。
磁碟片上一個磁軌上有80個扇區,硬碟上一個磁軌上最多有63個扇區,
這樣的話,一個磁軌上的位元組總數是肯定小於64K的,也就是說不會出現,第一次讀磁碟就執行到 170行處的:
xor ax,ax
sub ax,bx
shr ax,#9

==============================================================================

L180mov ax,#1
L181sub ax,head
L182jne ok4_read
L183inc track
Q:
當0磁頭的當前道沒有資料可讀後則去讀1磁頭上的資料,想問這種情況是適用於哪種軟碟機的?我想過去是個雙面軟碟機。如果不是雙面軟碟機,則在read_track裡則會死迴圈吧。
A:
PC機使用的軟碟機都是雙頭(雙面)的。沒有見過哪種PC機用的的是單面的

==============================================================================
read_track:
199         push ax
200         push bx
201         push cx
202         push dx
203         mov dx,track
204         mov cx,sread
205         inc cx
206         mov ch,dl
207         mov dx,head
208         mov dh,dl
209         mov dl,#0
210         and dx,#0x0100
211         mov ah,#2
212         int 0x13
213         jc bad_rt <--我用Bochs返彙編出來的是jb... 這個是不是代碼錯了?
214         pop dx
215         pop cx
216         pop bx
217         pop ax
218         ret

Q:
(1)是不是因為Linux0.11每個段就給了64KB得長度限制?
(2)還有就是bootsect.c裡面read_it這部分,jc bad_rt <--我用Bochs返彙編出來的是jb... 這個是不是代碼錯了?
A:
沒有限制在64KB,而是每次讀時最多64KB。
另外,查一下手冊看看jb 是否就是 jc 。
 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.