?? setup.s
字號:
!! setup.s (C) 1991 Linus Torvalds!! setup.s is responsible for getting the system data from the BIOS,! and putting them into the appropriate places in system memory.! both setup.s and system has been loaded by the bootblock.!! This code asks the bios for memory/disk/other parameters, and! puts them in a "safe" place: 0x90000-0x901FF, ie where the! boot-block used to be. It is then up to the protected mode! system to read them from there before the area is overwritten! for buffer-blocks.!! setup.s 負責從BIOS 中獲取系統(tǒng)數(shù)據(jù),并將這些數(shù)據(jù)放到系統(tǒng)內存的適當?shù)胤健?/span>! 此時setup.s 和system 已經(jīng)由bootsect 引導塊加載到內存中。!! 這段代碼詢問bios 有關內存/磁盤/其它參數(shù),并將這些參數(shù)放到一個! “安全的”地方:0x90000-0x901FF,也即原來bootsect 代碼塊曾經(jīng)在! 的地方,然后在被緩沖塊覆蓋掉之前由保護模式的system 讀取。!! NOTE! These had better be the same as in bootsect.s!! 以下這些參數(shù)最好和bootsect.s 中的相同!INITSEG = 0x9000 ! we move boot here - out of the way ! 原來bootsect 所處的段。SYSSEG = 0x1000 ! system loaded at 0x10000 (65536). ! system 在0x10000(64k)處。SETUPSEG = 0x9020 ! this is the current segment ! 本程序所在的段地址。.globl begtext, begdata, begbss, endtext, enddata, endbss.textbegtext:.databegdata:.bssbegbss:.textentry startstart:! ok, the read went well so we get current cursor position and save it for! posterity.! ok,整個讀磁盤過程都正常,現(xiàn)在將光標位置保存以備今后使用。mov ax,#INITSEG ! this is done in bootsect already, but...! 將ds 置成#INITSEG(0x9000)。這已經(jīng)在bootsect 程序中! 設置過,但是現(xiàn)在是setup 程序,Linus 覺得需要再重新! 設置一下。mov ds,axmov ah,#0x03 ! read cursor pos! BIOS 中斷0x10 的讀光標功能號 ah = 0x03! 輸入:bh = 頁號! 返回:ch = 掃描開始線,cl = 掃描結束線,! dh = 行號(0x00 是頂端),dl = 列號(0x00 是左邊)。xor bh,bhint 0x10 ! save it in known place, con_init fetchesmov [0],dx ! it from 0x90000.! 上兩句是說將光標位置信息存放在0x90000 處,控制臺! 初始化時會來取。! Get memory size (extended mem, kB) ! 下面3 句取擴展內存的大小值(KB)。! 是調用中斷0x15,功能號ah = 0x88! 返回:ax = 從0x100000(1M)處開始的擴展內存大小(KB)。! 若出錯則CF 置位,ax = 出錯碼。mov ah,#0x88int 0x15mov [2],ax ! 將擴展內存數(shù)值存在0x90002 處(1 個字)。! Get video-card data: ! 下面這段用于取顯示卡當前顯示模式。! 調用BIOS 中斷0x10,功能號 ah = 0x0f! 返回:ah = 字符列數(shù),al = 顯示模式,bh = 當前顯示頁。! 0x90004(1 字)存放當前頁,0x90006 顯示模式,0x90007 字符列數(shù)。mov ah,#0x0fint 0x10mov [4],bx ! bh = display pagemov [6],ax ! al = video mode, ah = window width! check for EGA/VGA and some config parameters ! 檢查顯示方式(EGA/VGA)并取參數(shù)。! 調用BIOS 中斷0x10,附加功能選擇 -取方式信息! 功能號:ah = 0x12,bl = 0x10! 返回:bh = 顯示狀態(tài)! (0x00 - 彩色模式,I/O 端口=0x3dX)! (0x01 - 單色模式,I/O 端口=0x3bX)! bl = 安裝的顯示內存! (0x00 - 64k, 0x01 - 128k, 0x02 - 192k, 0x03 = 256k)! cx = 顯示卡特性參數(shù)(參見程序后的說明)。mov ah,#0x12mov bl,#0x10int 0x10mov [8],ax ! 0x90008 = ??mov [10],bx ! 0x9000A = 安裝的顯示內存,0x9000B = 顯示狀態(tài)(彩色/單色)mov [12],cx ! 0x9000C = 顯示卡特性參數(shù)。! Get hd0 data ! 取第一個硬盤的信息(復制硬盤參數(shù)表)。! 第1 個硬盤參數(shù)表的首地址竟然是中斷向量0x41 的向量值!而第2 個硬盤! 參數(shù)表緊接第1 個表的后面,中斷向量0x46 的向量值也指向這第2 個硬盤! 的參數(shù)表首址。表的長度是16 個字節(jié)(0x10)。! 下面兩段程序分別復制BIOS 有關兩個硬盤的參數(shù)表,0x90080 處存放第1 個! 硬盤的表,0x90090 處存放第2 個硬盤的表。mov ax,#0x0000mov ds,axlds si,[4*0x41] ! 取中斷向量0x41 的值,也即hd0 參數(shù)表的地址??ds:simov ax,#INITSEGmov es,axmov di,#0x0080 ! 傳輸?shù)哪康牡刂? 0x9000:0x0080 ?? es:dimov cx,#0x10 ! 共傳輸0x10 字節(jié)。repmovsb! Get hd1 datamov ax,#0x0000mov ds,axlds si,[4*0x46] ! 取中斷向量0x46 的值,也即hd1 參數(shù)表的地址??ds:simov ax,#INITSEGmov es,axmov di,#0x0090 ! 傳輸?shù)哪康牡刂? 0x9000:0x0090 ?? es:dimov cx,#0x10repmovsb! Check that there IS a hd1 :-) ! 檢查系統(tǒng)是否存在第2 個硬盤,如果不存在則第2 個表清零。! 利用BIOS 中斷調用0x13 的取盤類型功能。! 功能號 ah = 0x15;! 輸入:dl = 驅動器號(0x8X 是硬盤:0x80 指第1 個硬盤,0x81 第2 個硬盤)! 輸出:ah = 類型碼;00 --沒有這個盤,CF 置位; 01 --是軟驅,沒有change-line 支持;! 02 --是軟驅(或其它可移動設備),有change-line 支持; 03 --是硬盤。mov ax,#0x01500mov dl,#0x81int 0x13jc no_disk1cmp ah,#3 ! 是硬盤嗎?(類型 = 3 ?)。je is_disk1no_disk1:mov ax,#INITSEG ! 第2 個硬盤不存在,則對第2 個硬盤表清零。mov es,axmov di,#0x0090mov cx,#0x10mov ax,#0x00repstosbis_disk1:! now we want to move to protected mode ... ! 從這里開始我們要保護模式方面的工作了。cli ! no interrupts allowed ! ! 此時不允許中斷。! first we move the system to it's rightful place! 首先我們將system 模塊移到正確的位置。! bootsect 引導程序是將system 模塊讀入到從0x10000(64k)開始的位置。由于當時假設! system 模塊最大長度不會超過0x80000(512k),也即其末端不會超過內存地址0x90000,! 所以bootsect 會將自己移動到0x90000 開始的地方,并把setup 加載到它的后面。! 下面這段程序的用途是再把整個system 模塊移動到0x00000 位置,即把從0x10000 到0x8ffff! 的內存數(shù)據(jù)塊(512k),整塊地向內存低端移動了0x10000(64k)的位置。mov ax,#0x0000cld ! 'direction'=0, movs moves forwarddo_move:mov es,ax ! destination segment ! es:di??目的地址(初始為0x0000:0x0)add ax,#0x1000cmp ax,#0x9000 ! 已經(jīng)把從0x8000 段開始的64k 代碼移動完?jz end_move
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -