Antz系统更新地址: https://www.cnblogs.com/LexMoon/category/1262287.html

  在前几天的任务中,我们已经简单实现了MBR,直接操作显示器和硬盘操作来加载其他扇区的程序,如今已经可以进入保护模式了,并且编写了我们自己的内核程序,这个内核虽然什么也没有做,但还是成功被加载进内存了。接下来我们要将这个内核程序编写详细的内容了。

0. 切换堆栈和GDT

 SELECTOR_KERNEL_CS    equ    

 extern    cstart
extern gdt_ptr [SECTION .bss]
StackSpace resb *
StackTop: [section .text]
global _start _start:
mov esp, StackTop
sgdt [gdt_ptr]
call cstart
lgdt [gdt_ptr]
jmp SELECTOR_KERNEL_CS:csinit
csinit:
hlt

  这四行代码就可以完成切换堆栈和更换GDT任务了。StackTop定义在.bss段中,大小为2KB,操作GDT时用到了gdt_ptr和cstart分别时一个全局变量和全局函数,定义在c代码start.c中。

#include "type.h"
#include "const.h"
#include "protect.h" PUBLIC void* memcpy(void* pDst, void* pSrc, int iSize);
PUBLIC void disp_str(char * pszInfo); PUBLIC t_8 gdt_ptr[];
PUBLIC DESCRIPTOR gdt[GDT_SIZE]; PUBLIC void cstart()
{
disp_str("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n-----\"cstart\" begins-----\n"); memcpy( &gdt,
(void*)(*((t_32*)(&gdt_ptr[]))),
*((t_16*)(&gdt_ptr[])) +
); t_16* p_gdt_limit = (t_16*)(&gdt_ptr[]);
t_32* p_gdt_base = (t_32*)(&gdt_ptr[]);
*p_gdt_limit = GDT_SIZE * sizeof(DESCRIPTOR) - ;
*p_gdt_base = (t_32)&gdt;
}

  cstart()首先把位于Loader中的原GDT全部复制给新的GDT,然后把gdt_ptr中的内容换为新的GDT的基地址和界限。复制GDT用的是memepy,至于它的函数定义就不详细写了,这个是c中非常出名的一个函数了。

  当然还有一些类型,结构体和宏,这些可以放置在.h的头文件中。

  protect.h :

 #ifndef    _TINIX_PROTECT_H_
#define _TINIX_PROTECT_H_ typedef struct s_descriptor /* 共 8 个字节 */
{
t_16 limit_low;
t_16 base_low;
t_8 base_mid;
t_8 attr1;
t_8 limit_high_attr2;
t_8 base_high;
}DESCRIPTOR; #endif

  type.h :

 #ifndef    _TINIX_TYPE_H_
#define _TINIX_TYPE_H_ typedef unsigned int t_32;
typedef unsigned short t_16;
typedef unsigned char t_8;
typedef int t_bool; #endif

  const.h :

 #ifndef    _TINIX_CONST_H_
#define _TINIX_CONST_H_ #define PUBLIC
#define PRIVATE static #define GDT_SIZE 128 #endif

  接下来在linux下编译链接。

  nasm -f elf -o kernel.o kernel.asm

  nasm -f elf -o string.o string.asm

  gcc -c -o start.o start.c

  ld -s  -Ttext 0x30400 -o kernel.bin kernel.o string.o start.o

  将bin使用工具写入(day01或者dd) ,打开查看结果。

  可以看到cstart成功切换了堆栈与GDT。

1. Makefile

  随着代码量的增多,编译链接的命令也越来越多了,你可能之前没有接触过Makefile,但这是一个非常高效的东西,值得学习。

  Makefile 是和 make 命令一起配合使用的,很多大型项目的编译都是通过 Makefile 来组织的, 如果没有 Makefile, 那很多项目中各种库和代码之间的依赖关系不知会多复杂,Makefile的组织流程的能力如此之强, 不仅可以用来编译项目, 还可以用来组织我们平时的一些日常操作. 这个需要大家发挥自己的想象力.。

  Makefile基本语法如下:

 target ... : prerequisites ...
command
...
 target ... : prerequisites ; command
command
...

  target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。

  prerequisites就是要生成那个target所需要的文件或是目标。

  command也就是make需要执行的命令。(任意的Shell命令)

  这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则。也就是Makefile中最核心的内容。

  来举个例子:

 # Makefile for boot

 # Programs, flags, etc.
ASM = nasm
ASMFLAGS = # This Program
TARGET = boot.bin loader.bin # All Phony Targets
.PHONY : everything clean all # Default starting position
everything : $(TARGET) clean :
rm -f $(TARGET) all : clean everything boot.bin : boot.asm ./include/load.inc ./include/fat12hdr.inc
$(ASM) $(ASMFLAGS) -o $@ $< loader.bin : loader.asm ./include/load.inc ./include/fat12hdr.inc ./include/pm.inc
$(ASM) $(ASMFLAGS) -o $@ $<

  #是注释的意思, =用来定义变量 , ASM和ASMFLAGS就是两个变量,使用变量要用$(ASM)和$(ASMFLAGS) 。

  对于 target :  prerequistites

          command

  意思就是想要得到target就需要指向命令command。

  target依赖于prerequistites,当prerequistites中至少有一个文件比target文件新时,command才会执行。

  看看最后两行,要想得到loader.bin就需要执行命令:$(ASM) $(ASMFLAGS) -o $@ $<

  loader.bin依赖于loader.asm load.inc fat12hdr.inc pm.inc ,这些中只要有一个比target新,command就会执行。

  那么这里的command是什么意思呢?

 $(ASM) $(ASMFLAGS) -o $@ $<

  $@  $< 其实就是target,prerequistites的第一个名字,所以这个命令等价于

 nasm -o loader.bin loader.asm

  此外你可能还发现了在外的大标签,他们是动作名称,如everything,all,clean,它们用于make后面,比如make all ,make clean,然后就会执行相应的当作。

  对于Makefile我们目前只需要知道这些就可以了。

  对于Antz内核的编写将会暂时停止几天,最近准备看看Linux内核的相关知识。同步会更新在https://www.cnblogs.com/LexMoon/category/1267413.html

自制操作系统Antz(8)——实现内核 (中) 扩展内核的更多相关文章

  1. 自制操作系统Antz -- 系列文章

    自制操作系统Antz day10——实现shell(上) AntzUhl 2018-10-10 16:25 阅读:192 评论:0   Linux内核源码分析 day01——内存寻址 AntzUhl ...

  2. 自制操作系统Antz(7)——实现内核 (上)

    Antz系统更新地址: https://www.cnblogs.com/LexMoon/category/1262287.html Linux内核源码分析地址:https://www.cnblogs. ...

  3. 自制操作系统Antz(13) 显示图片

    显示图片只是在多媒体课上看着bmp格式图片的突发奇想,然后就实现在了我自己的操作系统 Antz系统更新地址 Linux内核源码分析地址 Github项目地址 效果图: 显示图片的原理 在之前显卡操作时 ...

  4. 自制操作系统小样例——参考部分linux0.11内核源码

    详细代码戳这里. 一.启动引导 采用软件grub2进行引导,基于规范multiboot2进行启动引导加载.multiboot2的文档资料戳这里. 二.具体内容 开发环境 系统环境:Ubuntu 14. ...

  5. 自制操作系统Antz(6)——内核初步,引入c语言

    Antz系统更新地址: https://www.cnblogs.com/LexMoon/category/1262287.html Linux内核源码分析地址:https://www.cnblogs. ...

  6. 自制操作系统Antz(9)——实现内核 (下) 实现图形化界面

    Antz系统更新地址: https://www.cnblogs.com/LexMoon/category/1262287.html Linux内核源码分析地址:https://www.cnblogs. ...

  7. 自制操作系统Antz(3)——进入保护模式 (中) 直接操作显存

    Antz系统更新地址: https://www.cnblogs.com/LexMoon/category/1262287.html Linux内核源码分析地址:https://www.cnblogs. ...

  8. 自制操作系统Antz(4)——进入保护模式 (下) 实现内核并从硬盘载入

    Antz系统更新地址: https://www.cnblogs.com/LexMoon/category/1262287.html Linux内核源码分析地址:https://www.cnblogs. ...

  9. 自制操作系统Antz(5)——深入理解保护模式与进入方法

    Antz系统更新地址: https://www.cnblogs.com/LexMoon/category/1262287.html Linux内核源码分析地址:https://www.cnblogs. ...

随机推荐

  1. NTFS文件系统详细分析

    NTFS文件系统详细分析 第一部分 什么是NTFS文件系统 想要了解NTFS,我们首先应该认识一下FAT.FAT(File   Allocation   Table)是“文件分配表”的意思.对我们来说 ...

  2. PHP 简易聊天室 利用redis的订阅发布功能

    demo:http://www.200ok.fun:8083/api/chat/list 前言:这个种方式太耗redis连接数,每次订阅都会新起一个进程,仅供练手使用,切勿用于生产环境. 原理:1.P ...

  3. mysql5.7.17版本升级源码方式及恢复主主复制

    版本升级--自测 从库 ------------ 停止主从复制 stop slave 全库备份 mysqldump -u root -p -S mysql.sock --all-databases&g ...

  4. win7 64位系统下安装autoitlibrary库遇到问题解决

    转载来自http://blog.sina.com.cn/s/blog_53f023270101skyq.html 今天需要在win7 64位系统下安装autoitlibrary库,起初安装好了robo ...

  5. Java面试题和解答(二)

    1.字符流和字节流的区别,使用场景是什么,相关类有哪些 http://blog.csdn.net/zj8692286/article/details/126507312.线程安全的概念,实现线程安全的 ...

  6. request内置对象

    request内置对象(JSP九大内置对象之一)简述:内置对象即已在容器内部创建完成,可以直接调用的对象.容器在接收到客户端的请求后会创建一个对象用于处理请求信息,该对象就是内置对象(属于“javax ...

  7. 【PY】Python3.7+Anaconda3 + PyQt5 + Eric6

    Anaconda下载地址:https://www.continuum.io/downloads pip install pyenchant pip install QScintilla pip ins ...

  8. note_The Top Risks of Requirements Engineering

    The risk is greatest at several points: 1. Overlooking a crucial requirement This one the greatest r ...

  9. linux运维需要掌握什么知识?linux运维学习路线

    linux运维需要掌握什么知识?这个问题算是老生常谈了,但是本人认为知道需要掌握什么知识不是重点,重点是我们需要知道运维是做什么的?再来根据工作需求去讨论需要学习什么知识才是正途,须知知识是学不完的, ...

  10. JavaIO流——简单对文件的写入及读取(三)

    已经讲了写入和读取了,那么想要把一个文件的内容复制到另一个文件呢 不说太多,直接见代码 public static void copyFile(String srcFilename, String d ...