V0.0.2 Console Module Complete. 在这个版本中,实现了一个在保护模式下,VGA为Text Mode时,向屏幕输出字符的模块,位于/kernel/driver/console。内部有详细的注释。同时顺带着写了stdint.h和一些inline汇编。由于操作系统开发时是没有C语言标准库的,所以可以考虑该操作系统将会实现一个基本的标准库,是标准库的子集,位于/kernel/basecrt目录中。
目前版本可以从这里下载到源代码。目前版本截图如下:
可以看到,系统经由Grub或者其他multiboot引导扇区引导后,清屏,并向屏幕输出绿色的Hello world字符串。
下面记录一下,如何在保护模式中,向屏幕输出字符。
在保护模式中、Text Mode下,输出字符到屏幕是非常简单的事情。
在彩色模式下,屏幕中的每一个字符,与内存(实际上这段内存地址映射的应该是显存)中的0xB8000后的每一个16字节相对应。例如,屏幕最左上角的字符,和(shor*(0xB8000))[0]这个short对应。其中,这个short的高8位是颜色属性,低8位是ASCII码字符。颜色属性同dos api里的颜色属性是一致的,这里就不废话了。经由GRUB引导后,系统会进入80*25的字符模式中。
所以,向屏幕中输出字符,可以用下列示例代码表示。
void PutChar(char ch, int x, int y, char color){ volatile uint16_t* where; where=(uint16_t*)(0xB8000)+(y*80+x); *where=ch| (((uint16_t)color)<<8); }
在显示器为单色的情况下,显存地址为0xB0000,同时屏幕中每一个字符,与该地址后每一个8位内存相对应,并没有颜色属性。代码示例如下
void PutChar(char ch, int x, int y){ *(char*)(0xB0000)+(y*80+x) = ch; }
在BIOS的数据段中,有显示器属性的字段,从中可以查询显示器的颜色。更多资料请参考 (http://wiki.osdev.org/Detecting_Colour_and_Monochrome_Monitors) 和 (http://wiki.osdev.org/Memory_Map_(x86)#BIOS_Data_Area_.28BDA.29) 。示例代码如下
//! False is colorful boolean DRIVER_CONSOLE_IsVideoMono(){ char c = (*(volatile uint16_t*)0x410)&0x30; return (c==0x30); }
同样,在BOIS数据段中,也保存了VGA操作所需要的输出port,通常是0x3D4。详细资料参考自(http://wiki.osdev.org/Text_Mode_Cursor) 示例代码如下。不过值得注意的是,下面的代码为通常情况下的代码,有可能输出端口不是0x3D4,也有可能当前模式不是80*25。
/* void update_cursor(int row, int col) * by Dark Fiber */ void update_cursor(int row, int col) { unsigned short position=(row*80) + col; // cursor LOW port to vga INDEX register outb(0x3D4, 0x0F); outb(0x3D5, (unsigned char)(position&0xFF)); // cursor HIGH port to vga INDEX register outb(0x3D4, 0x0E); outb(0x3D5, (unsigned char )((position>>8)&0xFF)); }
下一步的目标,在键盘可以输出简单的字符串后,书写键盘的输入驱动,将最基本的输入输出搞定。