2011-10-02 43 views
1

最近我在看linux 01的源代碼,因爲2.6.11和更高版本的bootsect.S是無用的,因此它是開始學習linux代碼的好地方,因此我選擇跟蹤Linux的第一個版本。 :P關於linux v0.01 bootsect.S

我在bootsect.S中有一些問題。以下是bootsect.S linux v 0.01中的一些代碼。

P.S第一個版本的彙編代碼使用的是intel語法,而不是在& t。

mov ax,#0x0001 | protected mode (PE) bit 
lmsw ax   | This is it! 
jmpi 0,8 | jmp offset 0 of segment 8 (cs) which is the second entry of the gdt. 

GDT:

.word 0,0,0,0  | dummy 
.word 0x07FF  | 8Mb - limit=2047 (2048*4096=8Mb) 
.word 0x0000  | base address=0 
.word 0x9A00  | code read/exec 
.word 0x00C0  | granularity=4096, 386 

.word 0x07FF  | 8Mb - limit=2047 (2048*4096=8Mb) 
.word 0x0000  | base address=0 
.word 0x9200  | data read/write 
.word 0x00C0  | granularity=4096, 386 

引導過程似乎是這樣的:

  • 移動的引導程序從0x7c00到0×9000

  • 代碼跳轉到0×9000

  • 設置段寄存器。

  • 負載系統代碼爲0x10000 (系統代碼包含啓動/ head.S中和init/main.c中根據生成文件)

  • 負載臨時GDT和IDT與LGDT和LIDT

  • 使A20能夠訪問16MB物理內存。

  • 組CR0的PE位去保護模式

  • 跳轉到0x000000處

下面是Makefile文件系統:

tools/system: 
boot/head.o init/main.o \ 
$(ARCHIVES) $(LIBS) 
$(LD) $(LDFLAGS) boot/head.o init/main.o \ 
$(ARCHIVES) \ 
$(LIBS) \ 

-o tools/system > System.map 

好像頭部.S和main.c作爲bootsect加載到內存中的系統二進制文件鏈接在一起。

我的問題是如果系統代碼(哪個條目是head.S/startup_32)加載在0x10000比爲什麼不跳轉到0x10000而是跳轉到0x000000? 跳到0x0是不是很奇怪,因爲裏面沒有加載代碼?

以下是下載源代碼的鏈接: https://docs.google.com/viewer?a=v&pid=explorer&chrome=true&srcid=0B1F0m2rUn8BYMjQ4ZDQxZTUtODI5My00MGZiLTgwZDQtM2ZiZWQ2ZWQxYzIx

+0

一個鏈接到源將本來不錯:) – sehe

+0

我添加一個下載鏈接到帖子。 tks的回覆:) – mike820324

回答

1

這裏的答案:

| It then loads the system at 0x10000, using BIOS interrupts. Thereafter 
| it disables all interrupts, moves the system down to 0x0000, ... 

,這裏是連同它的代碼:

 cli      | no interrupts allowed ! 

| first we move the system to it's rightful place 

     mov  ax,#0x0000 
     cld      | 'direction'=0, movs moves forward 
do_move: 
     mov  es,ax   | destination segment 
     add  ax,#0x1000 
     cmp  ax,#0x9000 
     jz  end_move 
     mov  ds,ax   | source segment 
     sub  di,di 
     sub  si,si 
     mov  cx,#0x8000 
     rep 
     movsw 
     j  do_move 

如果您仔細看代碼,你會注意到它確實開始做ES = 0,DI = 0(目標)和DS = 0x1000,SI = 0(源)的REP MOVSW,也就是說,從0x10000(= DS * 0x10 + SI)到0(= ES * 0x10 + DI)的容量。

+0

tks,它解決了我的問題。 :d – mike820324