30天自制操作系统学习-第6天

1 分割源文件

观察我们昨天写好的bookpack.c主文件,发现它已达到三百多行,这样对不利于我们的维护,为此,我们将其对os功能除了的函数进行分类,独立到一个C文件中。而且bookpack主函数中对于函数的声明部分未免有点过于庞大,我们使用C中的头文件这一概念,独立出一个bookpack.h头文件,对于我们需要使用到的一些功能函数进行声明,这样我们在bookpack.c中只需#include bookpack.h,这样就可以使用到其他c文件中的函数了:

其中独立出来的graphic.c,用于处理图像:

其中用于处理中断的dsctbl.c文件:

bookpack.h头文件:

这时我们的bookpack.c主函数将会是这样:

嗯,整理后就变得十分简洁了。但是Makefile文件只是对于特定的C文件进行编译生成,这样以后我们在不断的加入更多的C文件时又需要频繁修改了,为此我们修改Makefile将适用于所有的C文件:

将链接编译特定的C文件用*号替代就可以对任意的C文件自动编译链接了。

2 中断处理程序的制作

我们需要控制键盘鼠标,否则我们制作处理的"操作系统"就没多大意义了,这里涉及到中断的知识,其中键盘是IRQ1,鼠标是IRQ12,中断程序的制作单单靠C无法实现,我们需要借助汇编的力量,向naskfuc.nas中继续添加几个用于控制键鼠中断的函数吧:

_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

_asm_inthandler27:
		PUSH	ES
		PUSH	DS
		PUSHAD
		MOV		EAX,ESP
		PUSH	EAX
		MOV		AX,SS
		MOV		DS,AX
		MOV		ES,AX
		CALL	_inthandler27
		POP		EAX
		POPAD
		POP		DS
		POP		ES
		IRETD

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

新建一个int.c文件用于处理鼠标键盘输入:

/* 中断关系 */

#include "bootpack.h"

void init_pic(void)
/* PIC初始化 */
{
	io_out8(PIC0_IMR,  0xff  ); /* 不接受全部分配 */
	io_out8(PIC1_IMR,  0xff  ); /* 不接受全部分配 */

	io_out8(PIC0_ICW1, 0x11  ); /* 边缘触发模式 */
	io_out8(PIC0_ICW2, 0x20  ); /* LQ0-7以INT20-27接受 */
	io_out8(PIC0_ICW3, 1 << 2); /* PIC1在IQ2连接*/
	io_out8(PIC0_ICW4, 0x01  ); /* 无缓冲模式 */

	io_out8(PIC1_ICW1, 0x11  ); /* 边缘触发模式 */
	io_out8(PIC1_ICW2, 0x28  ); /* LQ8-15由INT28-2f接受 */
	io_out8(PIC1_ICW3, 2     ); /* PIC1在IQ2连接 */
	io_out8(PIC1_ICW4, 0x01  ); /* 无缓冲模式 */

	io_out8(PIC0_IMR,  0xfb  ); /* 11111011 PIC1除此之外全部禁止 */
	io_out8(PIC1_IMR,  0xff  ); /* 11111111 不接受全部分配 */

	return;
}

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();
	}
}

void inthandler2c(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 2C (IRQ-12) : PS/2 mouse");
	for (;;) {
		io_hlt();
	}
}

void inthandler27(int *esp)
/* 从PIC0中的不完全加入对策

在Athlon 66X2机等方面,根据芯片组的情况,在PIC的初始化时,这个插孔只有一次

这个AA制处理函数,对那个分配什么都不做过得过

为什么什么都不做就好了?

→这是由于PIC初始化时的电噪声而产生的。

没有必要认真地处理些什么 */
{
	io_out8(PIC0_OCW2, 0x67); /*向PIC通知ISQ-07受理完成 */
	return;
}

主函数bookpack.c中调用int中断函数:

/* bootpack主函数*/

#include "bootpack.h"
#include <stdio.h>

void HariMain(void)
{
	struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;
	char s[40], mcursor[256];
	int mx, my;

	init_gdtidt();
	init_pic();
	io_sti(); /* IDT/PICの因为初始化结束了,所以解除了CPU的中断禁止*/

	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);

	io_out8(PIC0_IMR, 0xf9); /* PIC1允许键盘(11111001) */
	io_out8(PIC1_IMR, 0xef); /* 允许鼠标(11101111) */

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

使用make run命令:

我们进入虚拟机键盘输入:

成功调用中断处理键盘输入了。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
创建一个完整操作系统是一个复杂而庞大的项目,通常涉及到操作系统内核、驱动程序、系统架构等多个层面,对于30天的时间来说,这是不现实的。然而,如果你对操作系统编程有兴趣,你可以尝试学习和理解操作系统的基本原理,并用一些轻量级的框架或工具如QEMU、Minix等来进行实践。 以下是一个简化的步骤概述: 1. **理论学习**:阅读操作系统相关的书籍,如《深入理解计算机系统》(The Art of Computer Programming, Volume 3),了解进程管理、内存管理、文件系统等基础概念。 2. **选择平台**:决定从用户空间(比如Linux内核的clone() API)还是内核模式(比如使用QEMU模拟)开始,因为内核开发涉及更多底层硬件知识。 3. **编写基本结构**:创建进程控制块(PCB)、内存管理模块,开始实现基本的系统调用接口。 4. **进程管理**:实现进程的创建、调度、同步和通信机制。 5. **内存管理**:设计虚拟内存映射、内存分配和回收算法。 6. **I/O管理**:处理设备驱动程序,实现简单的输入输出操作。 7. **文件系统**:如果要做全功能操作系统,你需要实现一个基本的文件系统,用于存储和读取数据。 8. **构建测试环境**:编写单元测试和系统测试,确保每个部分都能正常工作。 9. **持续学习和改进**:在整个过程中,不断查阅文档、源代码和参考资料,以解决遇到的问题。 记住,这是一个高度概括的过程,实际操作中每一步都需要大量的研究和编码。如果你是初学者,可能需要投入更多时间来学习相关基础知识。关于30天的具体代码示例,由于这个项目的规模和复杂性,这里无法提供详细的代码片段,但你可以通过在线教程和开源项目如MINIX的学习来找到起点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值