如果跟著我學(xué)到現(xiàn)在吕嘀,一定知道到哪里去下載代碼违寞,算了,地址在這https://github.com/cfenollosa/os-tutorial/tree/master/15-video-ports偶房,這個(gè)地址里有這節(jié)課要用到的代碼趁曼,如果之前你只是看看就算了,這節(jié)課就是不上手就再也跟不上的關(guān)鍵節(jié)點(diǎn)棕洋。代碼中有一點(diǎn)點(diǎn)問題挡闰,Makefile中在qemu 調(diào)用-s時(shí)加一個(gè)-S(比如這樣 -sS),這樣gdb才能夠真正控制qemu的運(yùn)行掰盘。
看到代碼了嗎摄悯?如果還沒打開代碼,本課程將不再歡迎你愧捕。
drive
文件夾中有兩個(gè)c程序奢驯,用到了Inline Assembly的寫法,這是一個(gè)難點(diǎn)晃财,這段代碼這么寫就顯得更加難理解叨橱。
原本的Inline Assembly的用法是這樣:
int a=10, b;
asm ("movl %1, %%eax;
movl %%eax, %0;"
:"=r"(b) /* 輸出 */
:"r"(a) /* 輸入 */
:"%eax" /* 用到的寄存器 */
);
我們的代碼是這樣
__asm__("in %%dx, %%al"
: "=a" (result)
: "d" (port));
"in %%dx, %%al"就是匯編指令
"=a" (result) 是指將eax寄存器的值寫入c語言中的變量result
中。
"d" (port)) 是指將port變量的值寫到edx中断盛。
繞不繞罗洗?感覺繞就正常了,因?yàn)槟悴恢?code>in %%dx, %%al是在干什么钢猛,讓我們看看kernel/kernel.c中如何調(diào)用這段代碼的伙菜。
port_byte_out(0x3d4, 14); /* 14是請(qǐng)求高位字節(jié),0x3d4是一個(gè)地址命迈,用于與顯卡交互 */
/* 索取的數(shù)據(jù)將出現(xiàn)在 (0x3d5)中 */
int position = port_byte_in(0x3d5);
position = position << 8; /* high byte */
port_byte_out(0x3d4, 15); /* 請(qǐng)求低位字節(jié) */
position += port_byte_in(0x3d5);
其實(shí)它是在請(qǐng)求顯卡告訴咱們贩绕,現(xiàn)在光標(biāo)在什么位置火的,光標(biāo)的位置是一個(gè)16位的數(shù)據(jù),分兩個(gè)字節(jié)提取淑倾,提取流程是:
1.在0x3d4位置寫入14馏鹤,光標(biāo)位置高字節(jié)信息出現(xiàn)在0x3d5中
2.在0x3d4位置寫入15,光標(biāo)位置低字節(jié)信息結(jié)果出現(xiàn)在0x3d5中娇哆。
由此湃累,實(shí)現(xiàn)了一個(gè)顯示數(shù)據(jù)的接口,以后再要打印什么ASCII碼就方便多了碍讨。