05day 文字显示 GDT/IDT初始化
来源:互联网 发布:android 爱奇艺源码 编辑:程序博客网 时间:2024/05/28 11:48
我们想向屏幕上输出ABC 123
void HariMain(void){ struct BOOTINFO *binfo = (struct BOOTINFO *) 0x0ff0; extern char hankaku[4096]; init_palette(); init_screen(binfo->vram, binfo->scrnx, binfo->scrny); putfont8(binfo->vram, binfo->scrnx, 8, 8, COL8_FFFFFF, hankaku + 'A' * 16); putfont8(binfo->vram, binfo->scrnx, 16, 8, COL8_FFFFFF, hankaku + 'B' * 16); putfont8(binfo->vram, binfo->scrnx, 24, 8, COL8_FFFFFF, hankaku + 'C' * 16); putfont8(binfo->vram, binfo->scrnx, 40, 8, COL8_FFFFFF, hankaku + '1' * 16); putfont8(binfo->vram, binfo->scrnx, 48, 8, COL8_FFFFFF, hankaku + '2' * 16); putfont8(binfo->vram, binfo->scrnx, 56, 8, COL8_FFFFFF, hankaku + '3' * 16); for (;;) { io_hlt(); }}
输出字体函数如下
void putfont8(char *vram, int xsize, int x, int y, char c, char *font){ int i; char *p, d /* data */; for (i = 0; i < 16; i++) { p = vram + (y + i) * xsize + x; d = font[i]; if ((d & 0x80) != 0) { p[0] = c; } if ((d & 0x40) != 0) { p[1] = c; } if ((d & 0x20) != 0) { p[2] = c; } if ((d & 0x10) != 0) { p[3] = c; } if ((d & 0x08) != 0) { p[4] = c; } if ((d & 0x04) != 0) { p[5] = c; } if ((d & 0x02) != 0) { p[6] = c; } if ((d & 0x01) != 0) { p[7] = c; } } return;}
封装一下 变成一个可以显示字符串的函数
void putfonts8_asc(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;}
不管怎么说 我觉得书的作者做的画面还是蛮帅的。。
使用stdio.hh 的 sprintf
sprintf(s, "scrnx = %d", binfo->scrnx); putfonts8_asc(binfo->vram, binfo->scrnx, 16, 64, COL8_FFFFFF, s);
以上代码存在于主函数中。
我们也可以在屏幕上见到结果。
显示鼠标指针
这并不是什么难事,问题是我们应该怎么能够移动它。
首先要了解GDT IDT,其实他们都是有关CPU的设定。
在32位下 为了表示一个段,需要有一下信息: 段的大小,起始地址,段的管理属性。CPU用8个字节来表示这些信息,而用于指定段的寄存器只有16位,由于CPU设计上的原因,段寄存器的低3位不能使用,所以我们能使用的只有13位,能够处理 0~8191的区域。
GDT 就是全局段号记录表 (global segment descriptor table),我们将有关段的信息整齐的排列在内粗你的某个地方,然后将内存的其实地址和有效谁定个数放在CPU内被称作为GDTR的特殊寄存器中,设定就完成了。
IDT 就是 interrupt descriptor table ,就是中断记录表。当CPU遇到外部状况变化或者是内部偶然错误就会切换过去处理突发事件。这就是中断功能的实现。
{ struct BOOTINFO *binfo = (struct BOOTINFO *) 0x0ff0; char s[40], mcursor[256]; int mx, my; init_gdtidt(); init_palette(); init_screen8(binfo->vram, binfo->scrnx, binfo->scrny); mx = (binfo->scrnx - 16) / 2; /* 夋柺拞墰偵側傞傛偆偵嵗昗寁嶼 */ my = (binfo->scrny - 28 - 16) / 2; init_mouse_cursor8(mcursor, COL8_008484); putblock8_8(binfo->vram, binfo->scrnx, 16, 16, mx, my, mcursor, 16); sprintf(s, "(%d, %d)", mx, my); putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, s); for (;;) { io_hlt(); }}
主函数中init_gdtidt。
看init_gdtidt
short limit_low, base_low; char base_mid, access_right; char limit_high, base_high;};struct GATE_DESCRIPTOR { short offset_low, selector; char dw_count, access_right; short offset_high;};
void init_gdtidt(void){ struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) 0x00270000;//0x270000~0x27ffff struct GATE_DESCRIPTOR *idt = (struct GATE_DESCRIPTOR *) 0x0026f800;//0x26f800~0x26ffff int i; /* GDT初始化 */ for (i = 0; i < 8192; i++) { set_segmdesc(gdt + i, 0, 0, 0); } set_segmdesc(gdt + 1, 0xffffffff, 0x00000000, 0x4092);//段号1 起始地址0 set_segmdesc(gdt + 2, 0x0007ffff, 0x00280000, 0x409a);//段号2 其实地址0x280000 长度0x7ffff 也就是512kb 这正好是为我们的bootpack.hrb准备的 load_gdtr(0xffff, 0x00270000);//通过汇编语言给GDTR赋值 /* IDT初始化 */ for (i = 0; i < 256; i++) { set_gatedesc(idt + i, 0, 0, 0); } load_idtr(0x7ff, 0x0026f800);//这部分以后说 return;}void set_segmdesc(struct SEGMENT_DESCRIPTOR *sd, unsigned int limit, int base, int ar){ if (limit > 0xfffff) { ar |= 0x8000; /* G_bit = 1 */ limit /= 0x1000; } sd->limit_low = limit & 0xffff; sd->base_low = base & 0xffff; sd->base_mid = (base >> 16) & 0xff; sd->access_right = ar & 0xff; sd->limit_high = ((limit >> 16) & 0x0f) | ((ar >> 8) & 0xf0); sd->base_high = (base >> 24) & 0xff; return;}void set_gatedesc(struct GATE_DESCRIPTOR *gd, int offset, int selector, int ar){ gd->offset_low = offset & 0xffff; gd->selector = selector; gd->dw_count = (ar >> 8) & 0xff; gd->access_right = ar & 0xff; gd->offset_high = (offset >> 16) & 0xffff; return;}
0 0
- 05day 文字显示 GDT/IDT初始化
- 五、结构体、文字显示与GDT/IDT初始化
- 5、结构体、文字显示与GDT/IDT初始化
- 结构体,文字显示与GDT/IDT初始化
- 第5天 结构体、文字显示与GDT/IDT初始化
- [读书笔记]30 天自制操作系统 day5 结构体, 文字显示与GDT/IDT初始化
- GDT和IDT的初始化
- GDT和IDT的初始化
- GDT/IDT
- 1个人开发操作系统之GDT和IDT的初始化
- About GDT LDT IDT
- About GDT LDT IDT
- IDT GDT LDT
- 段、GDT/IDT 相关知识点
- gdt初始化
- 操作系统之GDT和IDT(三)
- minix中的GDT,LDT,IDT和TSS
- IDT表的初始化
- MyBatis_整合ehcache
- PHP获取毫秒时间戳
- 【项目】Nuget更新
- Axure实际操作中的隐藏技能点
- 文章标题
- 05day 文字显示 GDT/IDT初始化
- Linux的SOCKET编程详解
- [LeetCode-118] Pascal's Triangle(帕斯卡三角形)
- 设计模式-原型模式
- 自学考试-“网络经济与企业管理”
- C#网站部署后提示App_Code.w3o10pfm.dll拒绝访问
- Linux Epoll介绍和程序实例
- UML示例
- leetcode:283. Move Zeroes(Java)解答