《30天自制操作系统》笔记----Day6

news/2024/7/5 18:32:37

DAY6:

1.分割源文件:


文件分类大致流程图:

bootpack.c
graphic.c
dsctbl.c
bootpack.c

段的属性:

段的属性
段的大小
段的起始地址
段的管理属性
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;
}

在这个结构体里base又分为low(2字节),mid(1字节),high(1字节) 3段,合起来刚好是32位. 段上限。它表示一个段有多少个字节。可是这里有一个问题,段上限最大是4GB,也就是一个32位的数值,如果直接放进去,这 个数值本身就要占用4个字节,再加上基址(base),一共就要8个字 节,这就把整个结构体占满了。这样一来,就没有地方保存段的管理属 性信息了,这可不行。因此段上限只能使用20位。这样一来,段上限最大也只能指定到1MB为止。明明有4GB,却只能用其中的1MB. 有种又回到了16位时代的错 觉,太可悲了。在这里英特尔的叔叔们又想了一个办法,他们在段的属 性里设了一个标志位,叫做Gbit。这个标志位是1的时候,limit的单位不 解释成字节(byte),而解释成页(page)。页是什么呢?在电脑的 CPU里,1页是指4KB。 这样一来,4KB × 1M = 4GB,所以可以指定4GB的段。总算能放心了。 顺便说一句,G bit的“G”,是“granularity”的缩写,是指单位的大小。

5.初始化PIC

PIC:programmable interrupt controller
PIC是将8个中断信号1集合成一个中断信号的装置。PIC监视着输入管脚 的8个中断信号,只要有一个中断信号进来,就将唯一的输出管脚信号 变成ON,并通知给CPU。IBM的大叔们想要通过增加PIC来处理更多的 中断信号,他们认为电脑会有8个以上的外部设备,所以就把中断信号 设计成了15个,并为此增设了2个PIC。(与CPU直接相连的PIC称为主PIC(master PIC),与主PIC相连的PIC称 为从PIC(slave PIC)。主PIC负责处理第0到第7号中断信号,从PIC负 责处理第8到第15号中断信号)

代码:
int.c的主要组成部分
void init_pic(void)
/* PIC的初始化 */
{
io_out8(PIC0_IMR, 0xff ); /* 禁止所有中断 */
io_out8(PIC1_IMR, 0xff ); /* 禁止所有中断 */
io_out8(PIC0_ICW1, 0x11 ); /* 边沿触发模式(edge trigger mode) */
io_out8(PIC0_ICW2, 0x20 ); /* IRQ0-7由INT20-27接收 */
io_out8(PIC0_ICW3, 1 << 2); /* PIC1由IRQ2连接 */
io_out8(PIC0_ICW4, 0x01 ); /* 无缓冲区模式 */
io_out8(PIC1_ICW1, 0x11 ); /* 边沿触发模式(edge trigger mode) */
io_out8(PIC1_ICW2, 0x28 ); /* IRQ8-15由INT28-2f接收 */
io_out8(PIC1_ICW3, 2 ); /* PIC1由IRQ2连接 */
io_out8(PIC1_ICW4, 0x01 ); /* 无缓冲区模式 */
io_out8(PIC0_IMR, 0xfb ); /* 11111011 PIC1以外全部禁止 */
io_out8(PIC1_IMR, 0xff ); /* 11111111 禁止所有中断 */
return;
}

PIC寄存器:
IMR(interrupt mask register)其8位分别对应8路IRQ信号。若某路为1,则该位的IRQ信号被屏蔽,PIC忽略该路信号。(具体原因参考书上)
ICW(initial control word) ICW共有4个,分别编号1~4,有4个字节的数据。(ICW1和ICW4与PIC 主板配线方式、中断信号的电气特性等有关,ICW3是有关主—从连接的设定,对主PIC而言,第几号IRQ与从PIC相连,是用8位来设定的。ICW2决定了IRQ以哪一号中断通知CPU)

比较重要的是:INT 0x20-0x2f 15而不使用0x00-0x0f是因为在某些程序想要破坏操作系统时,CPU内部会自动产生INT 0x00~0x1f,如果这些与IRQ重复,CPU就分不清楚到底是IRQ还是CPU的系统保护通知。

6.中断处理程序的制作

鼠标是IRQ12,键盘是IRQ1,所以要编写INT 0x2c 和INT 0x21的中断处理程序(handler)。

void inthandler21(int *esp)
/* 来自PS/2键盘的中断 */
{
struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;
boxfill8(binfo->vram, binfo->scrnx, COL8_000000, 0, 0, 32 * 8 - 1, 15);
putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, "INT 21 (IRQ-1) :
PS/2 keyboard");
for (;;) {
io_hlt();
}
}

由于中断处理完成不能执行“return”(RET指令),而是必须执行IRETD指令(无法用C语言写,所以得修改汇编文件)

EXTERN _inthandler21, _inthandler2c
_asm_inthandler21:
PUSH ES
PUSH DS
PUSHAD
MOV EAX,ESP
PUSH EAX
MOV AX,SS
MOV DS,AX
MOV ES,AX
CALL _inthandler21
POP EAX
POPAD
POP DS
POP ES
IRETD

这个函数只是将寄存器的值保存到栈里,然后将DS和ES调整到 与SS相等,再调用_inthandler21(所以又要修改naskfunc.nas中的函数),返回以后,将所有寄存器的值再返回 到原来的值,然后执行IRETD。

其次要将这个函数注册到IDT中去。

/* IDT的设定 */
set_gatedesc(idt + 0x21, (int) asm_inthandler21, 2 * 8, AR_INTGATE32);
set_gatedesc(idt + 0x2c, (int) asm_inthandler2c, 2 * 8, AR_INTGATE32);

这里的2 * 8表示的是asm_inthandler21属 于哪一个段,即段号是2,乘以8是因为低3位有着别的意思,这里低3位必须是0。“2 * 8” 也可以写成 “2<<3”

PS:
对于PUSH EAX指令(类比于):
ADD ESP,-4
MOV [SS:ESP],EAX
ESP的值减去4,以所得结果作为地址值,将寄存器中的值 保存到该地址所对应内存里。
对于POP EAX指令(类比于):
MOV EAX,[SS:ESP]
ADD ESP,4

PUSHAD相当于:
PUSH EAX
PUSH ECX
PUSH EDX
PUSH EBX
PUSH ESP
PUSH EBP
PUSH ESI
PUSH EDI   而POPAD指令相当于按以上相反的顺序。

http://www.niftyadmin.cn/n/2422847.html

相关文章

win7 远程桌面连接问题汇总

1.远程桌面虚拟机发现无法连接计算机右键属性-高级系统设置-远程-设置后确定计算机右键-管理-服务和应用程序-服务-启用Remote Desktop Services服务,如果不行关闭防火墙即可.2.win7远程桌面无法连接报错,发生身份验证错误,要求的函数不受支持.修改本地电脑&#xff0c;开始菜单…

java 函数中的函数_Java中的函数

我正在尝试在Java中定义类似于Haskell的仿函数的类.因此,仿函数定义为&#xff1a;/*** Programming languages allow only (just simply enough) endofunctor, that are functors from and to the same category.* In this case, the category is the one of the datatypes (i…

集合(四): Map

为什么80%的码农都做不了架构师&#xff1f;>>> 更多实现类的源码分析请点击链接地址。。。。。。。 一&#xff1a; java.util.Map<k,v> public interface Map<K,V> { //....} Map用于保存具有映射关系的数据&#xff0c;因此Map集合&#xff08;…

mysql 留言及回复_mysql - 用PHP写留言板,有回复功能,要写入数据库。

为情所困2017-05-24 11:36:301楼第一&#xff0c;最好不要和反饋信息表設計在同一張表裡。第二&#xff0c;你的反饋表最好加多一個字段status,表示該條信息是否已回复。反饋表設計id[int(11)]主鍵suggest_id[int(11)]反饋表idaid[int(11)]反饋人員idcontent[text]反饋信息isus…

mysql靶机_[Vulnhub]靶机渗透-Raven:2

0x01 Scan Host更加详细地扫描:0x02 Web Service还是有个wp&#xff0c;老规矩用wpscan看一下&#xff0c;同时扫描目录。flag1dirb扫描出错&#xff0c;所以这里用gobuster:挨个看了下发现了flag1:刚好wpscan的结果也出来了&#xff0c;wordpress的版本是4.8.7&#xff0c;主题…

第一节课作业 150206119

c语言首先老师提供一个C语言的飞机游戏让大家感受一下&#xff0c;首先安装c-free&#xff0c;然后是将代码进行运行&#xff0c;游戏以A.S.D.W键位来控制游戏中飞机的上下左右&#xff0c;击中敌机可获得积分&#xff0c;被敌机撞中死亡一次&#xff0c;每次游戏有3次生还机会…

Android 主题动态切换框架:Prism

Prism&#xff08;棱镜&#xff09; 是一个全新的 Android 动态主题切换框架&#xff0c;虽然是头一次发布&#xff0c;但它所具备的基础功能已经足够强大了&#xff01;本文介绍了 Prism 的各种用法&#xff0c;希望对你会有所帮助&#xff0c;你也可以对它进行扩展&#xff0…

openmp 互斥锁 mysql_并发读写OpenMp中的共享变量

我基本上有三个关于OpenMp的问题。并发读写OpenMp中的共享变量Q1。 OpenMp是否提供互斥共享变量&#xff1f;考虑下面的三个嵌套循环的简单矩阵乘法代码&#xff0c;使用C中的OpenMp并行化。这里A&#xff0c;B和C是动态空间分配双**类型的变量。线程数被适当分配一个值。#prag…