天天看點

Foxdisk03-如何安裝2

(請保留 -> 作者:羅冰 )

整個Foxdisk3.01的代碼,是将安裝程式和主程式混在一起編譯的。安裝程式負責将代碼拷貝到指定的硬碟區域,包括MBR代碼、Foxdisk的啟動代碼、Foxdisk的資源、Foxdisk的code段和資料段。在“如何安裝1”中叙述的foxdisk在硬碟中的映像,都是由它來實作的。

混編的好處是,安裝程式能夠很容易的定位主程式各種段(code、data、stack等等)的位置,友善安裝。另外,很多函數可以共用。壞處是,安裝程式也要占據不少的空間。我之前為了友善C和彙編混合,設定了編譯模式為small,也即Code段必須在64K内,Stack和Data段加起來在64K之内。我在設計初期沒有考慮好,代碼寫到後半段就感到很痛苦—許多想實作的功能因為代碼的限制,沒法去實作。

現在的編譯器早就取消了這樣的限制,以技術而言,BorlandC++3.1已經是石器時代的産品。以我現在常用的Vs2015,從來不用去考慮類似這樣的問題,可以專注在程式本身的實作。計算機軟體的發展非常快,一不小心我也變成了老古董了。

回到正題。與安裝相關的檔案有Setup.c、Setup.h、iSetup.c和iSetup.h,與主程式共用了磁盤通路、圖像顯示等函數。外設的通路,在後面專門寫幾個章節進行介紹,用彙編去通路外設,我估計現在除了開發驅動或者OS的程式員,很少會有人去關注它們了。

從Setup.c的main()函數開始跟蹤,了解安裝過程。

main函數做了兩件事情: 解除安裝和軟體安裝。解除安裝的過程故意設計得複雜,通過判斷指令行以及熱鍵,确定使用者需要完全解除安裝,然後再将相應的扇區覆寫。這幾天我重讀代碼,覺得這裡的設計很有問題,有可能導緻解除安裝後無法進入作業系統了。

軟體安裝通過兩個函數實作,firstSetup()和updateSetup()。前一個函數是首次安裝,後一個是針對已經安裝的軟體進行參數更改或者代碼更新。main()最後的彙編代碼:

asm mov ax,3

asm int 0x10

其作用為回到文本模式。程式是在DOS環境下,并使用圖形模式安裝的,如果沒有回到文本模式,DOS的指令行無法執行。

通篇代碼中,有大量嵌入彙編的地方。這種寫法不是很好,程式可讀性比較差,我主要是習慣了彙編來實作一些小功能,不自覺的就用上了。後續出現内嵌彙編的地方,都會給出解釋。

firSetup()中,将安裝主程式的步驟分為了四個,代碼中給出了很詳細的說明,很容易讀懂。此函數中所調用的圖形函數和磁盤通路函數,其功能都比較單一,通過函數說明可以了解其作用。

我盡量不去調用C的庫函數,以防止代碼量的增加。是以,很多經典的函數,比如memset、memcpy等,隻能重新自己實作。另外一個原因,Foxdisk的主程式中,是沒有作業系統的,那些庫函數也沒法運作。我參考的代碼來自于linux2.6,不愧是千錘百煉的代碼,非常精簡高效。

firSetup()中頻繁使用的彙編代碼:

asm xor ax,ax

asm int 0x16

這段代碼的功能是等待按鍵,類似于C語言中的getchar()或者pause()。

updateSetup()的實作代碼在iSetup.c中,其實作方式類似于firSetup(),就不一一解釋了。

這兩個函數都打開了時鐘中斷,實作一些需要定時的功能。篇幅所限,不再詳細說明,在後續章節中針對時鐘中斷做一個詳細說明。