三十天自制操作系統(tǒng)(3)

第7天

PIC初始化之后寿弱,再寫中斷處理函數(shù)揍异,然后把中斷處理函數(shù)的入口地址注冊(cè)在IDT中⊙锇希現(xiàn)在重點(diǎn)是中斷處理函數(shù)如何編寫溺健。

PIC中還有一個(gè)寄存器OCW,如果鍵盤發(fā)生中斷阎抒,需要向PIC發(fā)送0X60+IRQ號(hào)碼憔狞,執(zhí)行這行代碼之后PIC才會(huì)繼續(xù)監(jiān)視IRQ1的中斷是否發(fā)生族淮。OCW設(shè)置完畢后凳干,CPU再?gòu)亩丝谥凶x入鍵盤數(shù)據(jù)晴裹,計(jì)算機(jī)的硬件規(guī)定被济,鍵盤數(shù)據(jù)總共8位救赐,從0x0060端口讀入。附上中斷處理程序

void inthandler21(int *esp)
{
  struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;
  unsigned char data, s[4];
  io_out8(PIC0_OCW2, 0x61); 
  data = io_in8(PORT_KEYDAT);
  sprintf(s, "%02X", data);
  boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 0, 16, 23, 31);
  putfonts8_asc(binfo->vram, binfo->scrnx, 0, 16, COL8_FFFFFF, s);
  return;
 }

像上面的程序那樣在中斷處理程序中既要讀取端口數(shù)據(jù)又要顯示到屏幕上只磷,作大量的圖像處理工作经磅,如果這個(gè)時(shí)候正好有一個(gè)中斷進(jìn)來(lái),計(jì)算機(jī)就不能處理钮追,只能不作任何反應(yīng)预厌。為了不影響中斷處理,把inthandle21中斷處理程序中的圖像處理部份拿出來(lái)元媚,inthandle21中斷處理程序只做一個(gè)工作:讀取端口數(shù)據(jù)轧叽,把數(shù)據(jù)放入緩存區(qū),把圖像處理工作放在主程序中處理刊棕。主程序一直查詢緩存區(qū)是否有數(shù)據(jù)炭晒,如果有數(shù)據(jù)就把數(shù)據(jù)顯示到屏幕上。接下來(lái)重點(diǎn)就是怎么寫緩存區(qū)的程序了甥角。

鍵盤的緩沖區(qū)程序其實(shí)就是大學(xué)學(xué)過(guò)的隊(duì)列网严,也就是能保證先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu)。當(dāng)然我們?cè)趯懖僮飨到y(tǒng)當(dāng)然無(wú)法用鏈表嗤无,只能用數(shù)組實(shí)現(xiàn)一個(gè)隊(duì)列震束。

先定義一個(gè)隊(duì)列的結(jié)構(gòu)體

struct FIFO8 
{
  unsigned char *buf;
  int p;//下一個(gè)數(shù)據(jù)定入地址
  int q;//下一個(gè)數(shù)據(jù)讀出地址
  int size;//隊(duì)列長(zhǎng)度
  int free;//表示隊(duì)列有沒(méi)有數(shù)據(jù)的字節(jié)數(shù)
  int flags;//標(biāo)記隊(duì)列有沒(méi)有溢出,最低位是1表示溢出
};

第一步:初始化

void fifo8_init(struct FIFO8 *fifo, int size, unsigned char *buf)
{
  fifo->size = size;
  fifo->buf = buf;
  fifo->free = size; 
  fifo->flags = 0;
  fifo->p = 0; 
  fifo->q = 0; 
  return;
}

第二步:存入數(shù)據(jù)

int fifo8_put(struct FIFO8 *fifo, unsigned char data)
{
  if (fifo->free == 0) 
  {
    fifo->flags |= FLAGS_OVERRUN;
    return -1;
  }
  fifo->buf[fifo->p] = data;
  fifo->p++;
  if (fifo->p == fifo->size) 
  {
    fifo->p = 0;
  }
  fifo->free--;
  return 0;
}

第三步:讀取數(shù)據(jù)

int fifo8_get(struct FIFO8 *fifo)
{
  int data;
  if (fifo->free == fifo->size) 
  {
    return -1;
  }
  data = fifo->buf[fifo->q];
  fifo->q++;
  if (fifo->q == fifo->size) 
  {
    fifo->q = 0;
   }
  fifo->free++;
  return data;
}

附:查詢數(shù)據(jù)量

int fifo8_status(struct FIFO8 *fifo)
{
  return fifo->size - fifo->free;
}

鍵盤的中斷碼是IRQ1当犯,而鼠標(biāo)則要晚得多垢村,是IRQ12。如果要讓鼠標(biāo)操作有效必須發(fā)行指令嚎卫,讓下面兩個(gè)裝置有效嘉栓,一個(gè)是鼠標(biāo)控制電路,一個(gè)是鼠標(biāo)本身。首先要激活鼠標(biāo)控制電路胸懈,鼠標(biāo)控制電路包含在鍵盤控制電路里担扑。然后發(fā)送激活鼠標(biāo)的指令,其實(shí)發(fā)送這個(gè)指令實(shí)際上就是CPU發(fā)送數(shù)據(jù)到鼠標(biāo)控制器趣钱,也就是鍵盤控制器涌献。

鼠標(biāo)的中斷處理程序和鼠標(biāo)差不多,也就是從端口中讀取數(shù)據(jù)放入隊(duì)列中首有,甚到CPU讀取數(shù)據(jù)的端口號(hào)都是一樣的燕垃。然后在主程序中從鼠標(biāo)隊(duì)列中取出數(shù)據(jù)進(jìn)行處理。鍵盤的處理非常簡(jiǎn)單井联,從端口讀進(jìn)來(lái)的數(shù)據(jù)就是鍵盤的掃描碼卜壕。那么從端口讀進(jìn)來(lái)的鼠標(biāo)數(shù)據(jù)表示什么意思呢?

第八天

鼠標(biāo)一開始設(shè)置完成會(huì)自動(dòng)發(fā)生一次中斷烙常,這次中斷發(fā)送到CPU的數(shù)據(jù)為0xfa轴捎,只是表示鼠標(biāo)已經(jīng)設(shè)置完成,將會(huì)向CPU發(fā)送數(shù)據(jù)蚕脏。我們每次對(duì)鼠標(biāo)操作都會(huì)引起鼠標(biāo)向CPU發(fā)送三次中斷侦副,每次中斷發(fā)送一個(gè)字節(jié),一共三個(gè)字節(jié)驼鞭,我們要把這三個(gè)字節(jié)湊到一起處理才是有意義的秦驯。

鼠標(biāo)一次性接收3字節(jié)數(shù)據(jù),其中第一個(gè)字節(jié)表示鼠標(biāo)的動(dòng)作挣棕,第一個(gè)字節(jié)的高4位取值范圍是03译隘,如果出現(xiàn)其它值,說(shuō)明鼠標(biāo)出現(xiàn)錯(cuò)誤洛心。第一個(gè)字節(jié)的低4位取值范圍8F固耘,如果出現(xiàn)其他值也說(shuō)明鼠標(biāo)發(fā)生錯(cuò)誤,如果第0位為1說(shuō)明鼠標(biāo)左鍵按下皂甘,如果第1位為1說(shuō)明右鍵被按下玻驻。第二個(gè)字節(jié)為鼠標(biāo)水平方向移動(dòng)的多少,正值為右偿枕,負(fù)值為左璧瞬。第三個(gè)字節(jié)為鼠標(biāo)豎直方向移動(dòng)多少,正值向上渐夸,負(fù)值向下嗤锉。

目前已經(jīng)能處理鼠標(biāo)操作傳入的3次中斷數(shù)據(jù),現(xiàn)在就是簡(jiǎn)單得在畫面上顯示出來(lái)墓塌。首先把原來(lái)鼠標(biāo)圖像所在的位置給畫成背景色瘟忱,然在計(jì)算新的鼠標(biāo)位置奥额,然后在新的鼠標(biāo)位置上畫一下鼠標(biāo)圖像,然后就感覺鼠標(biāo)移動(dòng)了访诱。

接下來(lái)插入講解一下如何從CPU實(shí)模式跳入保護(hù)模式垫挨。我們首先把顯卡模式設(shè)置好,然后把一些需要BIOS做的工作給做好触菜。將下來(lái)就開始跳入保護(hù)模式了九榔。關(guān)掉CPU級(jí)別中斷,往ox60號(hào)端口寫入0xdf涡相,可以讓CPU使用超過(guò)1M的內(nèi)存容量哲泊。然后設(shè)置CR0寄存器,把CR0寄存器讀出來(lái)催蝗,然后把最高位和最低位設(shè)置為0切威,再放入CR0,CPU就跳入保護(hù)模式了丙号,進(jìn)入保護(hù)模式后馬上要執(zhí)行JMP指令先朦,才能使接下來(lái)的指令正常執(zhí)行。接下來(lái)只要把特定的程序復(fù)制到內(nèi)存中就行了槽袄。也就是IDT,GDT,主程序烙无,棧及其他這個(gè)所放的位置在內(nèi)存中放好就行了锋谐。

保護(hù)模式和實(shí)模式的的區(qū)別就在于計(jì)算內(nèi)存地址時(shí)遍尺,是使用段寄存器的值直接指定地址值的一部份呢,還是通過(guò)GDT 使用段寄存器的值指定并非實(shí)際存在的地址號(hào)碼涮拗。

第九天

鼠標(biāo)處理告一段落乾戏,這一天主要做內(nèi)存管理,內(nèi)存管理的第一步是檢測(cè)計(jì)算機(jī)內(nèi)存容量有多大三热。

先檢測(cè)CPU有沒(méi)有緩存鼓择,如果CPU是486以上就有緩存,以下就沒(méi)有緩存也就不需要關(guān)閉緩存就漾。檢測(cè)方法就是看往CPU標(biāo)志寄存器第18位寫入是否有效呐能。然后對(duì)CR0寄存器的某些位設(shè)置為0,才能關(guān)閉掉緩存抑堡。關(guān)掉緩存之后摆出,開始檢測(cè)內(nèi)存容量,檢測(cè)的方法也很簡(jiǎn)單首妖,先把內(nèi)存地址從小到大偎漫,每次讀一個(gè)內(nèi)存內(nèi)容,然后把內(nèi)存內(nèi)容取否有缆,寫入內(nèi)存象踊,再讀一次這個(gè)內(nèi)存温亲,如果新的內(nèi)容跟預(yù)計(jì)取反的內(nèi)容一樣說(shuō)明這個(gè)內(nèi)存地址是有效的。為了提高效率我們沒(méi)有一個(gè)字節(jié)一個(gè)字節(jié)檢測(cè)杯矩,而是每次檢測(cè)4KB栈虚,所以這4KB內(nèi)存中最一4個(gè)字節(jié)是有效的,那就認(rèn)為這4KB都是有效內(nèi)存史隆。內(nèi)存大小知道了之后节芥,就可以進(jìn)行內(nèi)存管理了。

內(nèi)存管理的基礎(chǔ)是內(nèi)存分配和內(nèi)存釋放逆害。內(nèi)存是否使用可以在內(nèi)存中做一個(gè)位圖來(lái)表示头镊,比如內(nèi)存有16MB,我們以4KB為一個(gè)分配單位魄幕,那么一共需要4096位標(biāo)記相艇,也就是512字節(jié)。在這512字節(jié)中纯陨,如第1位是0坛芽,就表示0~0xfff這個(gè)內(nèi)存地址未使用。如果以這種方式管理內(nèi)存翼抠,從代碼上來(lái)講比較簡(jiǎn)單咙轩。但是也有不足,那就是分配最小內(nèi)存地址不靈活阴颖,上面的例子中以4KB為一個(gè)單位分配活喊,如果只需要1B,那么這樣分配就太浪費(fèi)了量愧。如果位圖以1字節(jié)為單位的話钾菊,那么位圖就需要16777216個(gè)標(biāo)記位,也就是2MB個(gè)標(biāo)記位偎肃,太浪費(fèi)了煞烫。

還有一種就是這本書使用的內(nèi)存管理方式,類似于從XXX號(hào)地址開始的YYY字節(jié)的空間是空著的累颂≈拖辏可以創(chuàng)建這樣一種數(shù)據(jù)結(jié)構(gòu)

struct FREEINFO
{
  unsigned int addr, size;
}

struct MEMMAN
{
  int frees;
  struct FREEINFO free[1000];
}
struct MEMMAN memman;
memman.frees = 1;
memman.free[0].addr = 0x400000;
memman.free[0].size = 0x07c00000;

如果需要100KB的空間,查看memman中free的情況紊馏,找出100MB以上的可用空間即可

for(int i = 0; i < memman.frees; i++)
{
  if(memman.free[i].size >= 100 * 1024)
  {
    "找到可用空間';
    "從地址memman.free[i].addr開始的100KB空間; 
  }
}

用這種方法可以實(shí)現(xiàn)內(nèi)存的管理料饥。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市瘦棋,隨后出現(xiàn)的幾起案子稀火,更是在濱河造成了極大的恐慌,老刑警劉巖赌朋,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凰狞,死亡現(xiàn)場(chǎng)離奇詭異篇裁,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)赡若,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門达布,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人逾冬,你說(shuō)我怎么就攤上這事黍聂。” “怎么了身腻?”我有些...
    開封第一講書人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵产还,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我嘀趟,道長(zhǎng)脐区,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任她按,我火速辦了婚禮牛隅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘酌泰。我一直安慰自己媒佣,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開白布陵刹。 她就那樣靜靜地躺著默伍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪授霸。 梳的紋絲不亂的頭發(fā)上巡验,一...
    開封第一講書人閱讀 49,829評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音碘耳,去河邊找鬼。 笑死框弛,一個(gè)胖子當(dāng)著我的面吹牛辛辨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瑟枫,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼斗搞,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了慷妙?” 一聲冷哼從身側(cè)響起僻焚,我...
    開封第一講書人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎膝擂,沒(méi)想到半個(gè)月后虑啤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體隙弛,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年狞山,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了全闷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡萍启,死狀恐怖总珠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情勘纯,我是刑警寧澤局服,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站驳遵,受9級(jí)特大地震影響腌逢,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜超埋,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一搏讶、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧霍殴,春花似錦媒惕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至月弛,卻和暖如春肴盏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背帽衙。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工菜皂, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人厉萝。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓恍飘,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親谴垫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子章母,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • 8086匯編 本筆記是筆者觀看小甲魚老師(魚C論壇)《零基礎(chǔ)入門學(xué)習(xí)匯編語(yǔ)言》系列視頻的筆記椿胯,在此感謝他和像他一樣...
    Gibbs基閱讀 37,139評(píng)論 8 114
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理筷登,服務(wù)發(fā)現(xiàn),斷路器哩盲,智...
    卡卡羅2017閱讀 134,633評(píng)論 18 139
  • 桃源口前方, 沙溪洲, 霜葉寒江不堪秋廉油。 夢(mèng)秦樓惠险, 秦樓明月照人愁。 燕去盼燕歸抒线, 人生幾回頭班巩。 望迢迢, 銷魂誰(shuí)人曉...
    思饗反動(dòng)閱讀 456評(píng)論 0 4
  • 金繕是漆藝中非常小的一塊嘶炭,簡(jiǎn)而言之就是把漆當(dāng)膠水用抱慌。但是前段時(shí)間金繕好像真的是火到不行,國(guó)內(nèi)網(wǎng)上關(guān)于金繕的“實(shí)在”...
    73e554e80a99閱讀 17,118評(píng)論 2 3
  • 6月7日 星期三 陰轉(zhuǎn)晴 今天早晨叫兒子起床眨猎,叫了好幾遍抑进,兒子才不情愿的起床,洗臉睡陪,刷牙寺渗,吃完飯一看...
    一年級(jí)八班崔皓媛閱讀 126評(píng)論 0 0