学习笔记
使用教材(配书源码以及使用方法)
《一个64位操作系统的设计与实现》
http://www.ituring.com.cn/book/2450
https://www.jianshu.com/p/28f9713a9171
源码结构
- 配书代码包 :第4章 \ 程序 \ 程序4-10
程序4-10 运行结果
[anno@localhost bootloader]$ make
nasm boot.asm -o boot.bin
nasm loader.asm -o loader.bin
[anno@localhost kernel]$ make
gcc -E head.S > head.s
as --64 -o head.o head.s
gcc -E entry.S > entry.s
as --64 -o entry.o entry.s
gcc -mcmodel=large -fno-builtin -m64 -c main.c
gcc -mcmodel=large -fno-builtin -m64 -c printk.c
gcc -mcmodel=large -fno-builtin -m64 -c trap.c
gcc -mcmodel=large -fno-builtin -m64 -c memory.c
gcc -mcmodel=large -fno-builtin -m64 -c interrupt.c
ld -b elf64-x86-64 -z muldefs -o system head.o entry.o main.o printk.o trap.o memory.o interrupt.o -T Kernel.lds
objcopy -I elf64-x86-64 -S -R ".eh_frame" -R ".comment" -O binary system kernel.bin
[anno@localhost 4-10]$ sudo mount boot.img media -t vfat -o loop
[anno@localhost 4-10]$ sudo cp bootloader/loader.bin media
[anno@localhost 4-10]$ sync
[anno@localhost 4-10]$ sudo cp bootloader/boot.bin media
[anno@localhost 4-10]$ sync
[anno@localhost 4-10]$ sudo cp kernel/kernel.bin media
[anno@localhost 4-10]$ sync
[anno@localhost 4-10]$ bochs -f ./bochsrc
程序4-10 运行结果
程序4-10 源码阅读
程序 4-10 interrupt.c
void init_interrupt()
{
int i;
for(i = 32;i < 56;i++)
{
set_intr_gate(i , 2 , interrupt[i - 32]);
}
color_printk(RED,BLACK,"8259A init \n");
//8259A-master ICW1-4
io_out8(0x20,0x11);
io_out8(0x21,0x20);
io_out8(0x21,0x04);
io_out8(0x21,0x01);
//8259A-slave ICW1-4
io_out8(0xa0,0x11);
io_out8(0xa1,0x28);
io_out8(0xa1,0x02);
io_out8(0xa1,0x01);
//8259A-M/S OCW1
io_out8(0x21,0xfd);
io_out8(0xa1,0xff);
sti();
}
- 屏蔽代码清单4-86中的所有中断请求,只开启键盘中断请求
主8259A芯片的OCW1寄存器映射到I/O端口21H地址处
OCW10xfd
即1 1 1 1 - 1 1 0 1 B
只允许IRQ1中断
IRQ1中断就是键盘中断
(参考表4-12 OCW1寄存器位功能说明
以及表4-6 8259A的中断引脚与外部设备对照表
)
程序 4-10 lib.h
inline unsigned char io_in8(unsigned short port)
{
unsigned char ret = 0;
__asm__ __volatile__( "inb %%dx, %0 \n\t"
"mfence \n\t"
:"=a"(ret)
:"d"(port)
:"memory");
return ret;
}
- 输出部分 :
"=a"(ret)
输出结果到返回值ret
- 输入部分:
"d"(port)
即DX = port
代码清单4-88 interrupt.c
void do_IRQ(unsigned long regs,unsigned long nr) //regs:rsp,nr
{
unsigned char x;
color_printk(RED,BLACK,"do_IRQ:%#08x\t",nr);
x = io_in8(0x60);
color_printk(RED,BLACK,"key code:%#08x\n",x);
io_out8(0x20,0x20);
}
-
x = io_in8(0x60);
: 借助汇编指令IN
从I/O端口地址60h处读取出键盘扫描码
参考资料
- 对比 程序4-9 与程序4-10的void init_interrupt()
[OS64][023]源码阅读:程序4-9 中断处理 : 显示黑底红字的中断向量号
https://www.jianshu.com/p/332edb3149ef
网友评论