美文网首页
[OS64位][019]源码阅读:程序4-4 异常/中断(一)显

[OS64位][019]源码阅读:程序4-4 异常/中断(一)显

作者: AkuRinbu | 来源:发表于2019-05-28 06:42 被阅读0次

    学习笔记

    使用教材(配书源码以及使用方法)
    《一个64位操作系统的设计与实现》
    http://www.ituring.com.cn/book/2450
    https://www.jianshu.com/p/28f9713a9171

    源码结构

    • 配书代码包 :第4章 \ 程序 \ 程序4-4
    程序4-4 源码结构
    • main.c
    #include "lib.h"
    #include "printk.h"
    #include "gate.h"
    
    void Start_Kernel(void)
    {
    
     . . . 
    
        color_printk(YELLOW,BLACK,"Hello\t\t World!\n");
    
        i = 1/0;
    
        while(1)
            ;
    }
    

    测试运行

    • 反汇编 objdump -D system 查看 color_printk 函数调用情况

      反汇编 查看 color_printk函数调用.png
    • 当遇到 1/0 除法错误时,触发中断,在屏幕显示黑底红字的错误信息"Unknown interrupt or fault at RIP\n"

      程序4-4 运行结果
    [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  -mcmodel=large -fno-builtin -m64 -c main.c
    main.c: In function ‘Start_Kernel’:
    main.c:72: warning: division by zero
    gcc  -mcmodel=large -fno-builtin -m64 -c printk.c
    ld -b elf64-x86-64 -z muldefs -o system head.o main.o printk.o -T Kernel.lds 
    objcopy -I elf64-x86-64 -S -R ".eh_frame" -R ".comment" -O binary system kernel.bin
    
    [anno@localhost 4-4]$ ls
    bochsrc  boot.img  bootloader  kernel  media
    
    [anno@localhost 4-4]$ sudo mount boot.img media -t vfat -o loop
    [anno@localhost 4-4]$ sudo cp bootloader/loader.bin media
    [anno@localhost 4-4]$ sync
    [anno@localhost 4-4]$ sudo cp bootloader/boot.bin media
    [anno@localhost 4-4]$ sync
    [anno@localhost 4-4]$ sudo cp kernel/kernel.bin media
    [anno@localhost 4-4]$ sync
    
    [anno@localhost 4-4]$ bochs -f ./bochsrc
    
    

    源码分析

    程序4-4 代码功能

    • 模块setup_IDT负责往IDT(中断描述符表)填入中断描述符(单个表项占用16Byte),中断描述符的格式参考(Figure 6-7. 64-Bit IDT Gate Descriptors);

    • 目前,只写了一个中断处理程序ignore_int,功能是在发生中断时在屏幕显示黑底红字的错误信息"Unknown interrupt or fault at RIP\n",并随即进入死循环;

    • 根据描述符格式要求,现在利用ignore_int所在的内核数据段选择子0x10以及ignore_int入口偏移地址,来创建中断描述符,并且往目前的IDT表的全部256个表项都填入这个相同的描述符(即目前无论发什么异常错误,都调用的是ignore_int

    程序4-4 源码解析

    内存示意图

    程序4-4 内存示意图.png

    setup_IDT :格式化中断描述符

    程序4-4 setup_IDT.png

    ignore_int :中断处理程序

    程序4-4 ignore_int.png
    • color_printk函数原型定义在源码文件 kernel\printk.h
    • kernel\main.c 文件中,通过#include "printk.h"导入了这个头文件,使用color_printk(YELLOW,BLACK,"Hello\t\t World!\n"); 进行函数调用,这是C语言的做法;
    • kernel\head.S 文件中,通过寄存器传递输入参数,使用汇编语句 callq color_printk 进行函数调用,这是汇编里的 callq + 标号名的做法;
    • 在反汇编之后,可以看到全部的源码文件被集合到了一起,大家都是汇编、大家都是机器码,这就是为什么可以用callq + 标号名了;

    setup_TSS64 :格式化TSS描述符,并填入GDT表

    程序4-4 setup_TSS64.png

    参考资料

    • IA-32e 中断处理过程 以及 IDT 中断描述符格式

    Intel® 64 and IA-32 Architectures
    Software Developer’s Manual

    Volume 3 (3A, 3B, 3C & 3D): System Programming Guide

    Figure 6-3. Interrupt Procedure Call
    Figure 6-7. 64-Bit IDT Gate Descriptors

    6.2 EXCEPTION AND INTERRUPT VECTORS

    7.2.2 TSS Descriptor

    7.2.2 TSS Descriptor

    • 汇编指令 lea
    lea

    相关文章

      网友评论

          本文标题:[OS64位][019]源码阅读:程序4-4 异常/中断(一)显

          本文链接:https://www.haomeiwen.com/subject/mfcctctx.html