第五天
参考《30天自制操作系统》GDT&IDT - 谷月轩 - 博客 梳理一下文件
现在我们拥有这么9个文件:
- ipl10.nas InitialProgramLoader, 占用了软盘的第一个扇区并符合启动盘的规范, 默认被载入地址是0x7c00 到 0x7e00,负责将10个柱面读入到0x8200到0x34fff (10个柱面共10218 = 360 个扇区但是第一个没有被读入);
- asmhead.nas 画面设定,内存装载,键盘响应,BIOS的一些调用,还包含一些暂时未知的设定;
- naskfun.nas 包含供C语言程序使用的汇编函数;
- bootpack.c 各种常量定义, 函数定义,目前主要用来进行颜色设定;
- make.bat 调用make工具,传入9个空参数
- Makefile 定义文件生成和一些dos指令
- !cons_nt.bat 启动命令行的DOS批处理脚本
关于cmd中的$
$并不是命令的一部分,而是指代你需要用普通user的权限来执行这条命令,例如:
用普通用户执行命令行时,先是用户名+@ 再是本机名称+:再是当前位置+ $,如下所示:
bob@work-station:~ $
用root发命令时,则是:
root@work-station:~#所以命令前的 $代表普通权限, #代表root权限。
bat文件中的%符号 批处理变量引导符
这个百分号严格来说是算不上命令的,它只是批处理中的参数而已(多个%一起使用的情况除外,以后还将详细介绍)。
引用变量用%var%,调用程序外部参数用%1至%9等等
%0 %1 %2 %3 %4 %5 %6 %7 %8 %9 %为命令行传递给批处理的参数
%0 批处理文件本身,包括完整的路径和扩展名
%1 第一个参数
%9 第九个参数
% 从第一个参数开始的所有参数
参数%0具有特殊的功能,可以调用批处理自身,以达到批处理本身循环的目的,也可以复制文件自身等等。
第一节
为了防止asmhead.nas中的SCRNY分辨率X,SCRNX分辨率Y,VRAM图像缓冲区的起始地址等值随着显卡模式VMODE的改变而改变,故用指针代替
第二节
结构体指针
struct BOOTINFO {
char cyls, leds, vmode, reserve;
short scrnx, scrny;
char *vram;
};
void HariMain(void)
{
char *vram;
int xsize, ysize;
struct BOOTINFO *binfo;
init_palette();
binfo = (struct BOOTINFO *) 0x0ff0;//强制类型转换
xsize = (*binfo).scrnx;
ysize = (*binfo).scrny;
vram = (*binfo).vram;
······
第三节
箭头符号标记模式:binfo->scrnx等于(*binfo).scrnx
第四节
void putfont8(char *vram, int xsize, int x, int y, char c, char *font)
{
int i;
char d /* data */;
for (i = 0; i < 16; i++) {
d = font[i];
if ((d & 0x80) != 0) { vram[( y + i) * xsize + x + 0] = c; }
if ((d & 0x40) != 0) { vram[( y + i) * xsize + x + 1] = c; }
// 下面就是从0加到7
/*
( y + i) * xsize是定位横行,x是空出来十个像素
*/
······
}
return;
}
// 改良版
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;
}
(1条消息) 30天自制操作系统第五天_xiaoana_139的博客-CSDN博客
第五节
hankaku.txt
文本文件包括OSASK字体
第六节
putfonts8_asc函数
现在可以显示字符串
第七节
sprintf()函数:不是按照指定格式输出,只是写在内存当中
输出字符串到屏幕的方法printf()都要使用操作系统
第八节
设置了鼠标的颜色和位置
第九节
GDT和IDT
段:segmentation
为了防止内存使用范围重叠,需要分段、分页
分段是分割整个内存,分页是有多少任务就要分多少页
每一个段的起始位置都看成0来处理
段的表示:
- 段的大小
- 起始地址
- 管理属性
先把段号放在储存器中,段号可以用8191的数,段寄存器低三位不能使用,所以只能使用13位,需要8192*8=64字节的地址,CPU写不了,只能放在内存中。
GDT:global(segment) descriptor table register:全局段号记录表
IDT:interrupt descriptor table:中断记录表
IDT记录了0~255的中断号码与调用关系函数的对应关系
右移:舍弃右边溢出的,左边不足的补零
注意C中进行指针的加减法时隐含着乘法,对指针的操作+1,使得地址+8
过了20天,终于重新开始了,主要期中太忙了