1 !
2 ! SYS_SIZE is the number of clicks (16 bytes) to be loaded.
3 ! 0x3000 is 0x30000 bytes = 196kB, more than enough for current
4 ! versions of linux ! SYS_SIZE 是要載入的節數(16 位元組為1 節)。0x3000 共為
! 0x30000 位元組=192 kB(上面Linus 估算錯了),對於當前的版本空間已足夠了。
5 !
6 SYSSIZE = 0x3000 ! 指編譯串連後system 模組的大小。參見列表1.2 中第92 的說明。
! 這裡給出了一個最大預設值。
7 !
8 ! bootsect.s (C) 1991 Linus Torvalds
9 !
10 ! bootsect.s is loaded at 0x7c00 by the bios-startup routines, and moves
11 ! iself out of the way to address 0x90000, and jumps there.
12 !
13 ! It then loads 'setup' directly after itself (0x90200), and the system
14 ! at 0x10000, using BIOS interrupts.
15 !
16 ! NOTE! currently system is at most 8*65536 bytes long. This should be no
17 ! problem, even in the future. I want to keep it simple. This 512 kB
18 ! kernel size should be enough, especially as this doesn't contain the
19 ! buffer cache as in minix
20 !
21 ! The loader has been made as simple as possible, and continuos
22 ! read errors will result in a unbreakable loop. Reboot by hand. It
23 ! loads pretty fast by getting whole sectors at a time whenever possible.
!
! 以下是前面這些文字的翻譯:
! bootsect.s (C) 1991 Linus Torvalds 著作權
!
! bootsect.s 被bios-啟動子程式載入至0x7c00 (31k)處,並將自己
! 移到了地址0x90000 (576k)處,並跳轉至那裡。
!
! 它然後使用BIOS 中斷將'setup'直接載入到自己的後面(0x90200)(576.5k),
! 並將system 載入到地址0x10000 處。
!
! 注意! 目前的核心系統最大長度限制為(8*65536)(512k)位元組,即使是在
! 將來這也應該沒有問題的。我想讓它保持簡單明了。這樣512k 的最大核心長度應該
! 足夠了,尤其是這裡沒有象minix 中一樣包含緩衝區高速緩衝。
!
! 載入程式已經做的夠簡單了,所以持續的讀出錯將導致死迴圈。只能手工重啟。
! 只要可能,通過一次取取所有的扇區,載入過程可以做的很快的。
24
25 .globl begtext, begdata, begbss, endtext, enddata, endbss ! 定義了6 個全域識別碼;
26 .text ! 文本段;
27 begtext:
28 .data ! 資料區段;
29 begdata:
30 .bss ! 堆棧段;
31 begbss:
32 .text ! 文本段;
33
34 SETUPLEN = 4 ! nr of setup-sectors
! setup 程式的扇區數(setup-sectors)值;
35 BOOTSEG = 0x07c0 ! original address of boot-sector
! bootsect 的原始地址(是段地址,以下同);
36 INITSEG = 0x9000 ! we move boot here - out of the way
! 將bootsect 移到這裡 -- 避開;
37 SETUPSEG = 0x9020 ! setup starts here
! setup 程式從這裡開始;
38 SYSSEG = 0x1000 ! system loaded at 0x10000 (65536).
! system 模組載入到0x10000(64 kB)處;
39 ENDSEG = SYSSEG + SYSSIZE ! where to stop loading
! 停止載入的段地址;
40
41 ! ROOT_DEV: 0x000 - same type of floppy as boot.
! 根檔案系統裝置使用與引導時同樣的軟碟機裝置;
42 ! 0x301 - first partition on first drive etc
! 根檔案系統裝置在第一個硬碟的第一個分區上,等等;
43 ROOT_DEV = 0x306 ! 指定根檔案系統裝置是第2 個硬碟的第1 個分區。這是Linux 老式的硬碟命名
! 方式,具體值的含義如下:
! 裝置號=主裝置號*256 + 次裝置號(也即dev_no = (major<<8) + minor )
! (主裝置號:1-記憶體,2-磁碟,3-硬碟,4-ttyx,5-tty,6-並行口,7-非具名管道)
! 0x300 - /dev/hd0 - 代表整個第1 個硬碟;
! 0x301 - /dev/hd1 - 第1 個盤的第1 個分區;
! …
! 0x304 - /dev/hd4 - 第1 個盤的第4 個分區;
! 0x305 - /dev/hd5 - 代表整個第2 個硬碟盤;
! 0x306 - /dev/hd6 - 第2 個盤的第1 個分區;
! …
! 0x309 - /dev/hd9 - 第2 個盤的第4 個分區;
! 從linux 核心0.95 版後已經使用與現在相同的命名方法了。
44
45 entry start ! 告知串連程式,程式從start 標號開始執行。
46 start: ! 47--56 行作用是將自身(bootsect)從目前段位置0x07c0(31k)
! 移動到0x9000(576k)處,共256 字(512 位元組),然後跳轉到
! 移動後代碼的go 標號處,也即本程式的下一語句處。
47 mov ax,#BOOTSEG ! 將ds 段寄存器置為0x7C0;
48 mov ds,ax
49 mov ax,#INITSEG ! 將es 段寄存器置為0x9000;
50 mov es,ax
51 mov cx,#256 ! 移動計數值=256 字;
52 sub si,si ! 源地址 ds:si = 0x07C0:0x0000
53 sub di,di ! 目的地址 es:di = 0x9000:0x0000
54 rep ! 重複執行,直到cx = 0
55 movw ! 移動1 個字;
56 jmpi go,INITSEG ! 間接跳轉。這裡INITSEG 指出跳轉到的段地址。
57 go: mov ax,cs ! 將ds、es 和ss 都置成移動後代碼所在的段處(0x9000)。
58 mov ds,ax !由於程式中有堆棧操作(push,pop,call),因此必須設定堆棧。
59 mov es,ax
60 ! put stack at 0x9ff00. ! 將堆棧指標sp 指向0x9ff00(即0x9000:0xff00)處
61 mov ss,ax
62 mov sp,#0xFF00 ! arbitrary value >>512
! 由於程式碼片段移動過了,所以要重新設定堆棧段的位置。
! sp 只要指向遠大於512 位移(即地址0x90200)處
! 都可以。因為從0x90200 地址開始處還要放置setup 程式,
! 而此時setup 程式大約為4 個扇區,因此sp 要指向大
! 於(0x200 + 0x200 * 4 + 堆棧大小)處。
63
64 ! load the setup-sectors directly after the bootblock.
65 ! Note that 'es' is already set up.
! 在bootsect 程式塊後緊根著載入setup 模組的代碼資料。
! 注意es 已經設定好了。(在行動程式碼時es 已經指向目的段地址處0x9000)。
66
67 load_setup:
! 68--77 行的用途是利用BIOS 中斷INT 0x13 將setup 模組從磁碟第2 個扇區
! 開始讀到0x90200 開始處,共讀4 個扇區。如果讀出錯,則複位磁碟機,並
! 重試,沒有退路。INT 0x13 的使用方法如下:
! 讀扇區:
! ah = 0x02 - 讀磁碟扇區到記憶體;al = 需要讀出的扇區數量;
! ch = 磁軌(柱面)號的低8 位; cl = 開始扇區(0-5 位),磁軌號高2 位(6-7);
! dh = 磁頭號; dl = 磁碟機代號(如果是硬碟則要置位7);
! es:bx