30天自制操作系统 杂谈1
写在前面
《30天自制操作系统》书名乍一看让人反感。但笔者翻开第一页就意识到这本书不简单(大概是臭味相投),书是2005年在日本出版的,里面诸如软盘等设备放到现在都是老古董了。其实计算机的历史也不是很长,作为一个计算机系的学生偶尔考考古也无伤大雅(笑)。
但是笔者并不打算写一个详细的教程,笔者只是想到什么写什么罢了。
地址和数值——C的象牙塔
《坚守精神的家园》周国平:天下滔滔,象牙塔一座接一座倾塌了。我平静地望着它们的残骸随波漂走,庆幸许多被囚的 普通灵魂获得了解放。可是,当我发现还有若干象牙塔依然零星地竖立着时,禁不住向它们深深鞠躬了。我心想, 坚守在其中的不知是一些怎样奇特的灵魂呢。
p = (char *) 0xa0000; //指定初始像素地址,用类型转换确保写一个字节
for (i = 0; i <= 0xffff; i++) {
*(p+i) = i & 0x0f; //每隔16个像素,色号反复一次
}
这是书中实现条纹状屏幕的C语言的少部分代码。
一直以来C的创始人给我们灌输一种理念:地址和数值是不同的概念。(从不加类型转化编译器就会给warning可以看出)
但稍微了解一点底层的人都知道,在寄存器眼里,地址和数值是一样的。
然而第一次发现寄存器随便拿起一个数值当地址时,笔者的内心如同象牙塔的倒塌,感叹原来还能这样。
继续深入底层的话,笔者不知道未知的前面还会有什么,唯一可以肯定的是一片从未涉足的荒凉感。
当然这只是比较矫情的说法。
比较客观的讲,MOV指令一条默认规则就是源数据和目的数据必须相同,像AL寄存器也就只能默认带入一个BYTE。
而C语言不限定指针类型,就不知道是写一个BYTE还是一个WORD,这才是C语言创始人的初衷吧。
不过,客观的解释总是容易被人遗忘,或许只有那种一片荒凉的感觉能刻骨铭心。
绘制三原色矩阵——界面的雏形!
起步阶段,我们先尝试用320x200的屏幕,假设左上点坐标(0,0),右下点(319,199)。那么像素坐标(x,y)对应的VRAM地址:0xa0000+x+y*320
//矩阵绘制函数:
void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1) {
int x, y;
for (y = y0; y <= y1; y++) {
for (x = x0; x <= x1; x++)
vram[y * xsize + x] = c;
}
return;
}
//OS调用的主函数
void HariMain(void)
{
char *vram;
init_palette(); //设置调色板
vram = (char *) 0xa0000;
boxfill8(vram, 320, COL8_FF0000, 20, 20, 120, 120);
boxfill8(vram, 320, COL8_00FF00, 70, 50, 170, 150);
boxfill8(vram, 320, COL8_0000FF, 120, 80, 220, 180);
for (; ; ) {
io_hlt();//系统待机
}
}
最终效果如图:
更进一步,我们修改主函数就可以得到界面的雏形:
void HariMain(void)
{
char *vram;
int xsize, ysize;
init_palette(); //设置调色板,并设置暗灰主基调
vram = (char *) 0xa0000;
xsize = 320;
ysize = 200;
//浅暗蓝桌面
boxfill8(vram, xsize, COL8_008484, 0, 0, xsize - 1, ysize - 29);
//桌面和功能栏的分界线
boxfill8(vram, xsize, COL8_C6C6C6, 0, ysize - 28, xsize - 1, ysize - 28);
boxfill8(vram, xsize, COL8_FFFFFF, 0, ysize - 27, xsize - 1, ysize - 27);
boxfill8(vram, xsize, COL8_C6C6C6, 0, ysize - 26, xsize - 1, ysize - 1);
//左下角凸出矩阵
boxfill8(vram, xsize, COL8_FFFFFF, 3, ysize - 24, 59, ysize - 24);
boxfill8(vram, xsize, COL8_FFFFFF, 2, ysize - 24, 2, ysize - 4);
boxfill8(vram, xsize, COL8_848484, 3, ysize - 4, 59, ysize - 4);
boxfill8(vram, xsize, COL8_848484, 59, ysize - 23, 59, ysize - 5);
boxfill8(vram, xsize, COL8_000000, 2, ysize - 3, 59, ysize - 3);
boxfill8(vram, xsize, COL8_000000, 60, ysize - 24, 60, ysize - 3);
//右下角凹陷矩阵
boxfill8(vram, xsize, COL8_848484, xsize - 47, ysize - 24, xsize - 4, ysize - 24);
boxfill8(vram, xsize, COL8_848484, xsize - 47, ysize - 23, xsize - 47, ysize - 4);
boxfill8(vram, xsize, COL8_FFFFFF, xsize - 47, ysize - 3, xsize - 4, ysize - 3);
boxfill8(vram, xsize, COL8_FFFFFF, xsize - 3, ysize - 24, xsize - 3, ysize - 3);
for (;;) {
io_hlt();
}
}
效果如图(感觉不错):