《自己动手写操作系统》第五章:扩充内核

从后面的章节开始,orange的书籍上往往没有解释为什么要这样做。我们在学习这段内容的时候,尽量多查找资料,从三个层次思考问题:应该怎么做?为什么要这样做?从本质上来看,这是一个什么问题。

1、切换堆栈和GDT

先来看看是如何切换的:

108     mov esp, StackTop   ; 堆栈在 bss 段中
109 
110     mov dword [disp_pos], 0
111 
112     sgdt    [gdt_ptr]   ; cstart() 中将会用到 gdt_ptr
113     call    cstart      ; 在此函数中改变了gdt_ptr,让它指向新的GDT
114     lgdt    [gdt_ptr]   ; 使用新的GDT
115 
116     lidt    [idt_ptr]
117 
118     jmp SELECTOR_KERNEL_CS:csinit
119 csinit:     ; “这个跳转指令强制使用刚刚初始化的结构”——<<OS:D&I 2nd>> P90.
120 
121     ;jmp 0x40:0
122     ;ud2
123 
124     sti
125 
126     hlt

sgdt和lidt分别是store和load GDT的意思,其中cstart改变了gdt_ptr,我们来看一下这个函数

22 PUBLIC void cstart()
 23 {
 24     disp_str("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n-----\"cstart\" begins-----\n");
 25 
 26     // 将 LOADER 中的 GDT 复制到新的 GDT 中
 27     memcpy( &gdt,                   // New GDT
 28         (void*)(*((t_32*)(&gdt_ptr[2]))),   // Base  of Old GDT
 29         *((t_16*)(&gdt_ptr[0])) + 1     // Limit of Old GDT
 30         );
 31     // gdt_ptr[6] 共 6 个字节:0~15:Limit  16~47:Base。用作 sgdt 以及 lgdt 的参数。
 32     t_16* p_gdt_limit = (t_16*)(&gdt_ptr[0]);
 33     t_32* p_gdt_base  = (t_32*)(&gdt_ptr[2]);
 34     *p_gdt_limit = GDT_SIZE * sizeof(DESCRIPTOR) - 1;
 35     *p_gdt_base  = (t_32)&gdt;
 36 }

    在csstart之中,我们用到了PUBLIC、PRIVATE等修饰符,也用到t_32等数据类型,要知道的是,这个程序现在已经是C语言的程序了。我们在这里已经用int等数据类型,想一想,此刻能不能用printf呢?

    我们将打印函数进行封装处理,然后编译。需要注意的是,gcc在处理字符串的时候,会传入函数的是字符串地址,而且字符串的末尾会加上‘/0’,也就是ASCII编码0,这也是为什么dis_str能够找到末尾的原因。

2、整理我们的文件

    到现在为之,我们的代码已经比较多而乱了,整理归类:
启动和引导:booot.asm 和loader.asm放在目录boot中
库文件:klib.asm  && string.asm放在/lib之中
内核:kernel.asm && start.c放在kernel之中

3、makefile

    makefile的语法我们不打算在本文讲解,你可以参考这里:makefile快速入门


4、添加中断处理

    操作系统中最重要的部分,可以算得上的进程调度。为了实现进程调度,我们需要一种控制权转换机制,这种机制变是中断。因为端口操作是写外部芯片的端口,所以可能会有一定的延迟,我们要在端口写命令后面加上延迟指令。
    对于全局变量的处理:我们需要全局变量在某个文件中是定义,而在其他文件中仅仅是申明,所以就有一个对extern进行处理的小trick。
    如果你对这一部分有一些疑问,那么或许你应该回忆一下中断的处理流程了:中断处理程序

    添加中断处理需要做哪些工作呢?

     初始化8259A、初始化IDT、添加中断和异常处理函数。

5、总结

    到现在为止,我们已经将框架搭建起来了,剩下的工作才是从内存、进程、文件系统等方面编写文件系统,自此,万里长征走完了第一步。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值