[读书笔记]30 天自制操作系统 day5 结构体, 文字显示与GDT/IDT初始化

1. 接收启动信息

  1. 采用结构体, 将各个独立的变量联系起来, 让程序有更好的可读性
    原始未使用 结构体的代码:
void HariMain(void)
{
    char *vram;
    int xsize, ysize;
    short *binfo_scrnx, *binfo_scrny;
    int *binfo_vram;

    init_palette();
    binfo_scrnx = (short *) 0x0ff4;
    binfo_scrny = (short *) 0x0ff6;
    binfo_vram = (int *) 0x0ff8;
    xsize = *binfo_scrnx;
    ysize = *binfo_scrny;
    vram = (char *) *binfo_vram;

    init_screen(vram, xsize, ysize);

    for (;;) {
        io_hlt();
    }
}

使用了结构体之后的代码
明显代码的可读性提高了好多

struct BOOTINFO {
    char cyls, leds, vmode, reserve;
    short scrnx, scrny;
    char *vram;
};

void HariMain(void)
{
    struct BOOTINFO *binfo = (struct BOOTINFO *) 0x0ff0;

    init_palette();
    init_screen(binfo->vram, binfo->scrnx, binfo->scrny);

    for (;;) {
        io_hlt();
    }
}

4. 显示字符

  1. 之前显示字符使用的是 BIOS 中断, 现在cpu 处于 32 bit 模式, 需要手工绘制图形
  2. 通过将指定字符数据写入 VRAM 空间中, 实现字符的显示

    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;
    }
  3. 字体数据
    这里写图片描述

static char font_A[16] = {
        0x00, 0x18, 0x18, 0x18, 0x18, 0x24, 0x24, 0x24,
        0x24, 0x7e, 0x42, 0x42, 0x42, 0xe7, 0x00, 0x00
    };

5. 增加字体

  1. 这里采用的是OSASK 字体, 并通过在 MAKEFILE 中使用 makefont 编译字体文件得到字体数据
    这里写图片描述

  2. 封装字符串

    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;
    }
  3. 实现效果
    这里写图片描述

6. 显示变量值

  1. 通过sprintf 函数将变量值写入到字符串中

8. 显示鼠标

  1. 本质上就是读入鼠标cursor 的字符数组, 根据其中的字符将相应的vram 中的某个内存的数据设置成调色板中的某个标号, 来显示相应的字符。

9. GDT 和 IDT 的初始化

  1. 这里采用分段内存管理, 段寄存器表示 段的起始地址
  2. 段需要有以下信息
    1. 段的大小
    2. 段的起始地址
    3. 段的管理属性
  3. 但是, cpu的段寄存器只有16bit, 那么可以模仿调色板的做法, 建立段寄存器与段号之间的一种映射关系, 由于段寄存器德尔低三位表示权限, 可以使用的只有13bit, 因而, 可以处理 0 ~ 8191 的区域 (64KB)这个就是我们的 GDT(全局段号记录表)
  4. IDT 是中断记录表
    1. 为了处理外设的各种事件, 一般可以采用轮询方式, 不过轮询的频率不好控制, 太慢, 外设得不到响应, 太快, cpu做无意义处理, 因而, 一般采用 中断方式
    2. 本质上相当于, 将监控外设的任务委托给了第三方对象, 让第三方对象负责处理监控事件, 然后cpu专心处理手头的任务, 也可以理解成 cpu 请了一个小蜜
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值