1个人开发操作系统之数组与字符串的使用
《1个人开发操作系统之界面与字体》一文中有遗留一个困扰我3周的问题。既字符串和数组编译后属于.data section,使用objcopy,将obj文件转换为binary文件后,程序不能正确地找到这些.data section的地址。其实问题不在objcopy,而是LD。静态数组和字符串指针地址是.data section在内存中的相对地址。所谓相对地址指相对于内存中.text section地址。在没有制定ld连接器.text section地址时,ld默认为.text section地址为0x1000。这样,.data section的地址是根据0x1000计算出来的。而我的ColimasMain函数是从0x280000开始运行的,所以数组与字符串的地址是错的。要改正.data section的地址非常简单,只需要告诉LD我的text section的正确地址。
我在Makefile文件里加入LD的Flags LDFLAGS =-Ttext 0x280000。修改bootpack.c,增加数据组变量,用于设置16种颜色。
static unsigned char table_rgb[16 * 3] = {
0x00, 0x00, 0x00,/* 0:黒 */
0xff, 0x00, 0x00, /* 1:正红 */
0x00, 0xff, 0x00, /* 2:正绿 */
0xff, 0xff, 0x00, /* 3:正黄 */
0x00, 0x00, 0xff, /* 4:正青 */
0xff, 0x00, 0xff, /* 5:正紫 */
0x00, 0xff, 0xff, /* 6:正蓝 */
0xff, 0xff, 0xff, /* 7:白 */
0xc6, 0xc6, 0xc6, /* 8:灰 */
0x84, 0x00, 0x00, /* 9:暗红 */
0x00, 0x84, 0x00, /* 10:暗绿 */
0x84, 0x84, 0x00, /* 11:暗黄 */
0x00, 0x00, 0x84, /* 12:暗青 */
0x84, 0x00, 0x84, /* 13:暗紫 */
0x00, 0x84, 0x84, /* 14:暗蓝 */
0x84, 0x84, 0x84 /* 15:暗灰 */
};
修改set_palette函数
void set_palette(unsigned char *rgb)
{
int i, eflags;
eflags = io_load_eflags();
io_cli();
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>8, 0);
for (i = 0; i <= 15; i++) {
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, rgb[0] / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, rgb[1] / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, rgb[2] / 4);
rgb += 3;
}
io_store_eflags(eflags);
return;
}
编译后和前文结果一样。
《OS自作入门》给出一套完整的字体对象文件,该obj文件可以和我的程序连接在一起,因此就不需要font.h和font.c文件。显示字符串函数为:
void drawstring(char *vram, int xsize, int x, int y, char c, unsigned char *s)
{
extern char hankaku[4096]; /*日文,半角的意思。是字体对象文件内的全局数组*/
for (; *s != 0x00; s++) {
putfont8(vram, xsize, x, y, c, hankaku + *s * 16);
x += 8;
}
return;
}
在界面上显示字符串:
void ColimasMain(void)
{
struct BOOTINFO *binfo = (struct BOOTINFO *) 0x0ff0;
init_palette();
init_screen(binfo->vram, binfo->scrnx, binfo->scrny);
char *str="Hello world";
drawstring(binfo->vram, binfo->scrnx, 18, 10, COL8_FFFFFF, str);
str="Start";
drawstring(binfo->vram, binfo->scrnx,10, binfo->scrny-20, COL8_000000, str);
for (;;) {
io_hlt();
}
}
运行结果:
<shapetype id="_x0000_t75" stroked="f" filled="f" path="[email protected]@[email protected]@[email protected]@[email protected]@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 297pt; HEIGHT: 201pt" type="#_x0000_t75"><imagedata o:title="" src="file:///C:%5CDOCUME~1%5C%E8%B6%99%E7%A3%8A%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.png"></imagedata></shape>