彭民德:《電子計算60年》(18)UNIX原始碼的一些運用
手頭有了UNIX原始碼,就有運用的天地。曾經看到中科院計算(軟體)所、成都電訊工程學院、合肥工大等單位有過應用報導。我們也在閱讀分析的同時,首先把它用於教學。UNIX中的程式可以作為作業系統、資料結構、C語言、軟體工程等課程的用例。在北京大學第二分校劉日昇、孫玉芳1982年3月編寫的《UNIX作業系統分析報告》的附錄中,就實際地選擇羅列了UNIX原始碼中的16個C函式,提供學習C語言使用。我們也從UNIX原始碼中選擇陣列、結構、指標等資料型別和諸如線性表、連結串列操作程式作為相應的教學用例。
對於UNIX原始碼的又一項運用是,1987年我們開發了一個基於UNIX環境的用於作業系統輔助教學的OSCAI系統(以caios命名)。鑑於作業系統核心工作從計算機外面看不見摸不著,很難理解,而閱讀原始碼雖然有較大收穫,但面對一本靜態的程式程式碼,要理解作業系統的動態性還是很難的。我們想通過跟蹤應用程式的執行過程,儘可能展示作業系統核心,在加工該應用程式某些特定語句時的實際狀況。如果能夠做到這一點,那麼第一,應用程式和作業系統都是實際的,應用程式可以獲得預期結果。第二,看不見的核心加工應用程式的過程,可以適當展示出來,提供外界對計算機內部工作過程,一種較直觀的瞭解。要實現上述功能,顯而易見的難度是核心程式碼和資料區無法訪問,核心程式碼在管理態執行,神聖不可侵犯。
我們的做法是,在應用程式和作業系統之間,增加一層OSCAI軟體,它截獲應用程式請求作業系統所做的系統呼叫,模擬核心對該系統呼叫進行加工,讀取通過系統呼叫可以得到的,核心與執行該應用程式相關的資料結構,並受控地顯示給應用者。這個OSCAI就是模擬UNIX的一個在使用者態執行的作業系統,因為借鑑了UNIX V6原始碼和第七版的技術,這種模擬可以接近真實。
OSCAI模擬核心設定了一套同名的資料結構,又用與核心相同的演算法編寫了在其上的一套操作程式。這些程式凡是能夠引用UNIX系統呼叫實現自己功能的,都用系統呼叫實現,讓實際UNIX去加工,以保持真實性。從UNIX來看,OSCAI只是一個實用程式,但從使用者來看,它是一個看得見摸得著的作業系統。
這樣做的代價是,記憶體中除了已有的UNIX,還有一套相似的OSCAI,增加了程式碼的冗餘,減慢了使用者程式的執行速度。但使用者可以選擇是否呼叫OSCAI,如果不用,那就保持原先的作業系統環境,不會增加程式碼冗餘。
本系統在UNIX環境下工作。使用本系統與使用UNIX的基本命令和其它實用程式的方法完全一樣。下面用例子加以說明。假定有一個C語言程式,檔名為prog.c,其中包含若干條系統呼叫。一方面可以用通常的方法編譯執行,顯示結果,也可以呼叫我們的caios,只要執行命令“caios prog.c”即可。
caios 是一個shell程式,包括下列依序的4步動作:
addcai $1
cc –o caios$$ caiosinit.c $1 –lcai
caios$$
rmcai $1
其中:
1. 命令“addcai $1”對prog.c進行加工,將程式中各條系統呼叫的名字,悄悄地在前面加上cai。比如,將
fd=open(“name”,0);
改成
fd=caiopen(“name”,0);
以便程式執行時不是直接由UNIX截獲,而是先經由我們的OSCAI系統加工。同時將使用者程式中的主函式main改為mmain,使它變成一個一般函式名,以便能夠與我們的caiosinit.c一起編譯成一個目標程式。
2. 命令“cc –o caios$$ caiosinit.c $1 –lcai ”的功能是將$1所代表的prog.c與caiosinit.c一起編譯成目標碼檔案caios$$。檔名中包含當前程式號$$,可以保證目標檔名的唯一性。後面的任選項告訴編譯程式cc,編譯時引用我們寫的OSCAI庫函式。命令列中的caiosinit.c對使用者程式做些預處理,執行經改造了的使用者程式mmain,最後做些善後處理。其程式碼為:
main(){
caiinit();
mmain();
endinit();
}
3. 命令“caios$$”是執行目標檔案。
4. 執行命令“rmcai $1”,還原上面被加工了的使用者程式。
考慮核心資料結構太多,對於OSCAI追蹤系統呼叫執行過程中,要顯示的系統資料進行了精選。僅顯示核心3類重要資料結構,即有關程式管理方面的proc結構、user結構;有關儲存管理方面的u.u_uisa和u.u_uisd頁表結構;有關檔案管理方面的filesys、inode、 u.u_file和file結構。這批資料讓使用者對於核心的瞬時情況有了基本瞭解。這些資訊無法從核心獲得的,來自我們的OSCAI,凡是能夠經系統呼叫從核心取得的,便直接取自核心,以儘量保持資料的真實性。
系統以醒目的表格形式顯示各個資料結構。要顯示的資料結構,有的往往又含有指向其它資料結構的指標成員,在這種情況下,就像對一顆樹進行搜尋一樣,不用退出顯示程式,就可以逐枝地任意搜尋整棵樹。顯示模組還利用了VDU-140圖形終端具有4屏顯示緩衝的特點,可以對4屏內容同時、輪流查閱。
下面引用一個例項。現有一個C語言的父子程式通訊程式:
char buf[]={“A:How do you do?\n”};
main()
{
int fpd[2];
char buf[20] ;
pipe(fdp);
if(fork()==0) {
close(fdp[0]);
write(fdp[1],buf,20);
close(fdp[1]);
exit(0);
}
read(fdp[0],buf,20);
printf(“%s\n”,buf);
}
上面程式的功能是父程式用系統呼叫pipe() 建立一個通訊管道,並用系統調fork()建立一個子程式,子程式經管道向父程式發信“A:How do you do?”,父程式接收後把信件顯示到螢幕上。該程式被OSCAI按照上述辦法做第一步處理後,將被改造成下述樣子:
char buf[]={“A:How do you do?\n”};
mmain()
{
int fpd[2];
char buf[20];
caipipe(fdp);
if(caifork()==0) {
caiclose(fdp[0]) ;
write(fdp[1],buf,20);
caiclose(fdp[1]);
caiexit(0);
}
read(fdp[0],buf,20);
printf(“%s\n”,buf);
}
其中有幾條系統呼叫pipe、fork、close、exit被修改成由我們控制的caipipe、caifork、caiclose、caiexit,而系統呼叫read、write當時尚未把它們寫到OSCAI中,那就直接交給UNIX處理。程式執行中可以顯示一些資料結構的變化,以反映作業系統核心加工該程式的情況。
作為第一階段工作,我們在OSCAI子程式庫中,包含了25條以cai打頭的系統呼叫。
系統開發完成後,我們寫了一篇文章,參加了1988年10月在上海召開的亞太你地區國際計算機教育會議。同一組4篇論文中,另有清華大學、復旦大學各一篇,還有一篇是美國人的。
在掌握了UNIX和C語言後,又一項運用是,對於我的同事們正在進行的“UNIX漢化”專案進行支援。當時執行最新的UNIX第七版的Dual 68000的多使用者微機,是純英文環境。馬友申老師等正在做漢化工作,將國標的常用漢字以點陣字型檔的方式存到硬碟上,提供輸入/輸出介面,必要時能夠從硬碟上取出漢字點陣,送到顯示緩衝器把漢字顯示到螢幕上,或者送到印表機列印。當時還沒有帶硬字型檔的漢字印表機,用這種方式列印速度比較慢,但是解決了從無到有的問題也是一個飛躍。我參與用C語言編寫了電話號碼查詢程式。基本實現是將一組常用電話,用“單位或姓名 電話號碼”記錄形式,存於正文檔案中,查詢程式每次從檔案讀入一塊512位元組資訊到記憶體快取。提供查詢介面接收查詢輸入,用C語言提供的字串操作函式,逐條記錄進行匹配,將匹配的記錄顯示到螢幕上。在專案的鑑定會上,專家們隨意用他單位或者本人的中文名,都可以執行程式phone查出所要的電話號碼,或者反過來,也可以用電話號碼查出名稱。程式經編譯讓phone獲得執行權後,就可以查詢了。例如執行
$ phone 湖南大學
將報告
湖南大學 82711
執行
$ phone 26356
將報告
國防科大 26356
當時還是用5位電話號碼。由此表明我們得到了最初的UNIX系統的漢化成果,時間是1984年。
用C語言寫的電話號碼查詢程式不到50行,很小巧。我們還用UNIX的shell語言寫了同樣功能的程式,那就更簡單了。比如先把電話號碼存到當前目錄下檔案phone_num中,再用下列方法生成一個執行grep查詢功能的程式檔案phone。
$ echo ‘grep $1 ./ phone_num’ > phone
這個shell程式phone中只有一個語句,比C語言程式簡單多了。用
$chomd +x phone
賦予它執行權,就可以像上述C程式一樣進行查詢了。
(與本文相關的更多內容,可參看 彭民德《電子計算60年》第4章 三代計算併發共享 電子工業出版社)
相關文章
- 彭民德:《電子計算60年》 (16) UNIX強勢走來
- 彭民德:《電子計算60年》(17)分析UNIX原始碼揭去作業系統神祕感原始碼作業系統
- 電子計算60年 (彭民德著)
- 彭民德:《電子計算60年》 (19) UNIX核心反彙編程式碼有啃頭
- 彭民德:《電子計算60年》(28 )輸入裝置的發展與運用
- 彭民德:《電子計算60年》 (37)跨入雲端計算時代
- 彭民德:《電子計算60年》 (20) UNIX一本經典著作的生命力
- 彭民德:《電子計算60年》(34) 863城市供水排程計算
- 彭民德:《電子計算60年》 (25)可愛又可恨的BASICA
- 彭民德(42) 電子計算大眾化,人人都有計算祕書如影隨形
- 彭民德:《電子計算60年》 (33)網路計算極大地提升了計算能力
- 彭民德:《電子計算60年》 (27) 多種媒體形式擴充套件電子計算內涵套件
- 彭民德:《電子計算60年》(4) 從學習蘇聯電子管計算機開始計算機
- 彭民德:《電子計算60年》(32) 網路數字資訊的特點
- 彭民德:《電子計算60年》 (26) Windows 主導圖形化PCWindows
- 彭民德:《電子計算60年》(12)ALGOL 60與程式自動化Go
- 彭民德:《電子計算60年》(6)我國首臺電子數字計算機104機計算機
- 彭民德:《電子計算60年》(15) 作業系統造就計算機活的靈魂作業系統計算機
- 彭民德:《電子計算60年》(7)DJS 21機的結構和用機環境JS
- 彭民德:《電子計算60年》(9)空空導彈彈道和脫靶量計算
- 彭民德:《電子計算60年》 (3)學習計算數學跟未來結緣
- 彭民德:《電子計算60年》 (2)數學的嚴密推理和美的薰陶
- 彭民德:《電子計算60年》(29)電腦漢化、文件編輯與鐳射照排
- 彭民德:《電子計算60年》 (31)計算機網路與第四代計算機計算機網路
- 彭民德(43)智慧計算成果斐然
- 彭民德:《電子計算60年》(35)網際網路時代的製造型企業
- 彭民德:《電子計算60年》(8)DJS 21機的資料、指令和程式JS
- 彭民德:《電子計算60年》 (23)駕馭PC,應用開發百花齊放
- 彭民德:《電子計算60年》 (22) IBM PC如潮水般湧來IBM
- 彭民德:《電子計算60年》(21) 全國第一屆C語言交流會C語言
- 彭民德:《電子計算60年》 (13) 程式語言曾被人無端稱作計算機語言計算機
- 彭民德:《電子計算60年》(5)用手搖計算機做三峽大壩下不穩定流計算計算機
- 彭民德:《電子計算60年》 (14) 以IBM 360為代表的多使用者計算機系統IBM計算機
- 彭民德:《電子計算60年》 (36) 從面向硬體的控制檯操作到瀏覽器人機介面瀏覽器
- 彭民德:《電子計算60年》(10)對付U-2偵察機的15號及317任務
- 彭民德:《電子計算60年》(30) 在列印技術發展長河中,16針印表機未能曇花一現
- 彭民德:(40)基於移動計算的物聯網共享單車
- 彭民德:《電子計算60年》(24)PC與微控制器聯合控制的水文流速儀實時檢定系統