網(wǎng)站建設(shè)實(shí)力滴滴友鏈
ucore的字符輸出有cga,lpt,和串口。qemu模擬出來顯示器連接到cga中。
cga
cga的介紹網(wǎng)站:https://en.wikipedia.org/wiki/Color_Graphics_Adapter
cga是顯示卡,內(nèi)部有個(gè)叫6845的芯片。cga卡把屏幕劃分成一個(gè)一個(gè)單元格,每個(gè)單元格顯示一個(gè)ascii碼編碼的字符。cga顯示卡關(guān)注內(nèi)存中某一段特定地址的數(shù)據(jù),并顯示這些數(shù)據(jù)。CPU只需要把要顯示的字符編碼放到顯示卡關(guān)注的內(nèi)存中。cga能顯示的數(shù)據(jù)有格式要求,另外,它能顯示的東西很少。如果CPU是以cga這種方式控制屏幕,是無法控制屏幕上的每一個(gè)像素的。cga的優(yōu)點(diǎn)在于方便地顯示字符。程序員唯一需要知道的知識(shí)就是字符編碼。
ucore的字符串輸出函數(shù)
cprintf和snprintf是操作系統(tǒng)使用者調(diào)用的函數(shù)。正常來說,是不會(huì)直接調(diào)用vcprintf和vsnprintf以及它右邊的函數(shù)的。
cprintf是向控制臺(tái)輸出字符串,snprintf是向內(nèi)存buffer輸出字符串。
cprintf
cprintf的用法和c標(biāo)準(zhǔn)庫printf的用法完全一致。
/* ** cprintf - formats a string and writes it to stdout** The return value is the number of characters which would be* written to stdout.* */
int cprintf(const char *fmt, ...) {va_list ap;int cnt;va_start(ap, fmt);cnt = vcprintf(fmt, ap);va_end(ap);return cnt;
}
cprintf的工作很簡單,它就是把可變參數(shù)變成va_list。就把剩下的工作交給vcprintf了。
vcprintf
vcprintf負(fù)責(zé)為vcprintfmt選擇一個(gè)輸出出口,選擇的輸出出口為控制臺(tái)。并把格式解析工作交給vcprintfmt。
下面的cputch就是控制臺(tái)輸出函數(shù)。這個(gè)函數(shù)將向控制臺(tái)輸出一個(gè)字符。
int vcprintf(const char *fmt, va_list ap) {int cnt = 0;vprintfmt((void*)cputch, &cnt, fmt, ap);return cnt;
}
vprintfmt
這個(gè)函數(shù)就是解析fmt,使得變成一個(gè)直接的字符串,然后調(diào)用上一個(gè)函數(shù)傳來的出口函數(shù),一個(gè)一個(gè)地將解析好的字符輸出。如果要了解是如何解析格式的,看的就是這個(gè)函數(shù)。
cputch
/* ** cputch - writes a single character @c to stdout, and it will* increace the value of counter pointed by @cnt.* */
static void
cputch(int c, int *cnt) {cons_putc(c);(*cnt) ++;
}
cons_putc
向lpt,cga,串口各輸出一個(gè)字符,調(diào)用的三個(gè)函數(shù)可以理解為外設(shè)的驅(qū)動(dòng)了。這三個(gè)函數(shù)是和硬件打交道的函數(shù)。
/* cons_putc - print a single character @c to console devices */
void
cons_putc(int c) {lpt_putc(c);cga_putc(c);serial_putc(c);
}