30天自製作業系統 命令列

2021-08-03 04:00:28 字數 4439 閱讀 4023

實現乙個命令列任務,首先需要乙個命令列視窗,然後需要乙個命令列任務,在命令列任務中實現命令列的相關功能。 一、

建立乙個命令列視窗

建立命令列視窗就是在螢幕上畫個視窗出來,實際就是操作視訊記憶體,這一部分利用前面已經實現的makewindow8函式即可實現。 二、

建立乙個命令列任務

有了命令列視窗,我們再來實現命令列的功能。

(1)游標閃爍功能

在剛開始做命令行時,命令列的功能就是游標閃爍即可,也就是說命令列任務中需要乙個定時器來控制游標色塊的顏色,使之產生閃爍的效果。在harimain函式中已經實現過游標的閃爍功能,該功能還需要使用乙個

fifo

佇列,通過在佇列中存放不同的數值,可以使得游標的顏色進行變換,實現方法與

harimain

中游標閃爍的實現方法相同。

(2)切換輸入視窗

目前使用者使用鍵盤輸入資料時,所有的資料都被task_a給接收了,新建的命令列視窗完全就是個擺設,為了使得命令列視窗可以接收資料,在

harimain

中設定整型變數

key_to

,key_to=0時,

task_a

接收鍵盤資料;

key_to=1

時,命令列任務接收鍵盤資料。鍵盤資料都儲存在各任務的

fifo

中。而key_to

值的切換則是由主程式

harimain

負責監聽

tab鍵來進行切換的,同時在切換視窗的同時,視窗標題欄的顏色發生改變。

(3)實現字元輸入

只要各個任務可以接收到字元編碼,那麼該任務就可以實現字元輸入的功能,各個任務接收到的字元編碼都儲存在其fifo中,在《

30天自製作業系統》中,作者將

fifo

與task

繫結,結構體

fifo

中還有個

task

的指標成員,作者的**執行起來沒有問題,但是我根據作者的步驟編寫出來的作業系統就執行不起來,在

vmware

上就會出現導致虛擬

cpu關閉的錯誤。

所以我直接將命令列任務的fifo在

bookpack.c

定義為全域性變數來避免此問題。

(4)符號的輸入

鍵盤上的有些按鍵與shift鍵結合就可以產生其他字元,為了使得編寫的作業系統可以顯示這些字元,我們需要監測

shift

鍵的狀態,

shift

鍵的按下與抬起都有相應的編碼,只需要監測是否有這些編碼產生即可。 按下

抬起左shift

0x2a

0xaa

右shift

0x36

0xb6

不同字元的編碼不同,為了實現乙個按鍵可以產生兩個字元,我們需要兩套keytable與之對應,大概是因為日本的鍵盤與中國鍵盤有所不同,作者的

keytable

並不能與我的鍵盤完全對應,所以我對

keytable

做了些許修改,修改之後的

keytable

如下:static char keytable0[0x80]=;

static char keytable1[0x80]=',  0,  0,'a','s',

'd','f','g','h','j','k','l',':',0x22,  0,  0,'|','z','x','c','v',

'b','n','m','<','>','?',  0,'*',  0,' ',  0,  0,  0,  0,  0,  0,

0,  0,  0,  0,  0,  0,  0,'7','8','9','-','4','5','6','+','1',

'2','3','0','.',  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,

0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,

0,  0,  0,0x5c, 0,  0,  0,  0,  0,  0,  0,  0,  0,0x5c, 0,  0 };

(5)大小寫字母轉換

為了盡可能保證鍵盤輸入的正確性,字母的大小寫轉換也是非常必要的。在我們使用電腦的過程中,控制大小寫的就只有兩個鍵:shift鍵和

capslock

鍵。我們可以根據

shift

鍵以及capslock

鍵的狀態來區分輸入的是大寫字母還是小寫字母。

capslock狀態

shift狀態

大寫/小寫

off

off 小寫

off on

大寫 on

off 大寫

on on

小寫

shift鍵狀態的監測只需要根據其按鍵編碼來監測即可,

capslock

鍵的狀態也可以根據其按鍵編碼來監測,但是因為

bios

中儲存有

capslock

鍵的狀態,所以我們採用的方式是通過

binfo

中的leds

來查詢其狀態。

至於大小寫字母的轉換,因為大寫字母的ascii編碼比小寫字母的

ascii

編碼要小

0x20

,所以是很好轉換的。

(6)控制游標閃爍

目前我們的作業系統有兩個視窗:task_a和

console

。當我們選中task_a任務時,希望只有

task_a

視窗的游標閃爍;當選中

console

任務是,希望只有

console

視窗的游標閃爍。

實現該功能的思路是每個視窗都有個變數cursor_c來記錄其游標的顏色,根據定義其正常的取值範圍為

0~15

,那麼我們可以在對其游標顏色作修改之前,先判斷其

cursor_c

的取值是否在正常範圍內,若在正常範圍內,則對其作修改,若不在,則不對其作修改。也就是說當某個視窗的

cursor_c

取值異常時,那麼該視窗的游標就不再閃爍。

之前我們使用tab鍵實現任務的切換,在

harimain

中使用tab

鍵進行任務切換時順便可以對

task_a

的cursor_c

賦值,當任務要切換到

task_a

時,對cursor_c

正常賦值,當任務要切換到

console

是,給cursor_c

賦個非正常值,這樣就實現了

task_a

的游標閃爍的控制。

同時為了控制命令列任務中的游標閃爍,還需要通過命令列的fifo來給命令列傳送游標的控制資訊,在實現過程中定義

2表示命令行視窗游標on,

3表示命令行視窗游標

off。

(7)對回車鍵的支援

命令列任務對回車鍵的支援僅僅通過監聽回車鍵的按鍵編碼即可,監聽到回車鍵之後,游標閃爍位置變為下一行的起始位置,當然下一行要首先顯示提示符。

(8)對視窗滾動的支援

命令列對視窗滾動的支援,實際上就是將命令列視窗中的畫素全都上移一行,最後一行全部塗黑即可。

(9)對相關命令的支援

用命令列執行相關指令一般都是在按下回車鍵之後,在這之前對於任何字元輸入我們都需要將其儲存在cmdline字元陣列中,當按下回車鍵之後,判斷

cmdline

中儲存的內容是啥,然後再作出相關處理。

(10)

dir命令 :顯示檔名等資訊

顯示檔名等資訊需要讀取磁碟,但是當前系統處於32位模式,無法使用

bios

,但是在前面的實現過程中,我們已經讀取了很多內容到記憶體

0x00100000~0x00267fff

(1440kb

)中去。又因為一般像乙個空軟盤儲存檔案時,檔名會寫在

0x002600

以後的地方,檔案的內容會寫在

0x004200

以後的地方,所以我們可以從位址

0x00100000+0x002600

開始的地方開始查詢相關檔案資訊。根據

根據作者實驗可得,每個檔案資訊使用32個位元組來儲存,所以檔案資訊最多存放

(0x004200-0x002600)/32=244

個。檔案資訊的結構如下:

struct fileinfo ;

說明:檔名第乙個位元組為0x00,代表這一段不包含任何檔名資訊;

檔名第乙個位元組為0xe5,代表這一段這個檔案已經刪除。

type值的說明:

0x01  -----

唯讀檔案(不可寫入)

0x02  -----隱藏檔案

0x04  -----系統檔案(比如磁碟名稱等)

0x10  -----目錄

30天自製作業系統

第一天的內容很少,是一些簡單的基礎知識,在這裡我就沒有必要寫出來了,只說出大概的輪廓了,然後我會對其中的幾點進行詳細的解釋。文章的第一天的輪廓大概是這樣的,作者首先用二進位制編輯器做了乙個顯示二進位制的程式,然後用彙編完全db的形式,後又進行改善,最後以比較標準的組合語言編寫,但程式主體部分還沒有翻...

30天自製作業系統 導讀

說明 這是8月15日即將上市的一本新書,本文的摘選也可以命名為 30天自製作業系統 上市之前必讀。本書幽默,有趣,可以說是技術書裡的幽默書,讓您讀起來絕對不會感到乏味。在本書上市之前,您一定先要讀下此篇文章,可以避免在學習中走更多的閱讀彎路,因為更多的讀者會問,七百多頁,30天?是的,看完此篇內容,...

30天自製作業系統 startHaribote

haribote os tab 4 org 0x8400 mov si,msg call putloop mov al,0x13 mov ah,0x00 int 0x10 fin hltjmp fin msg db 0x0a db test db 0 putloop mov al,si add si...