RayCommand操作系统的实现笔记2--完成在保护模式Text Mode下,输出字符

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));
 }


Future Work

下一步的目标,在键盘可以输出简单的字符串后,书写键盘的输入驱动,将最基本的输入输出搞定。

你可能感兴趣的:(command)