自制操作系统Antz(8)——实现内核 (中) 扩展内核
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)——实现内核 (中) 扩展内核的更多相关文章
- 自制操作系统Antz -- 系列文章
自制操作系统Antz day10——实现shell(上) AntzUhl 2018-10-10 16:25 阅读:192 评论:0 Linux内核源码分析 day01——内存寻址 AntzUhl ...
- 自制操作系统Antz(7)——实现内核 (上)
Antz系统更新地址: https://www.cnblogs.com/LexMoon/category/1262287.html Linux内核源码分析地址:https://www.cnblogs. ...
- 自制操作系统Antz(13) 显示图片
显示图片只是在多媒体课上看着bmp格式图片的突发奇想,然后就实现在了我自己的操作系统 Antz系统更新地址 Linux内核源码分析地址 Github项目地址 效果图: 显示图片的原理 在之前显卡操作时 ...
- 自制操作系统小样例——参考部分linux0.11内核源码
详细代码戳这里. 一.启动引导 采用软件grub2进行引导,基于规范multiboot2进行启动引导加载.multiboot2的文档资料戳这里. 二.具体内容 开发环境 系统环境:Ubuntu 14. ...
- 自制操作系统Antz(6)——内核初步,引入c语言
Antz系统更新地址: https://www.cnblogs.com/LexMoon/category/1262287.html Linux内核源码分析地址:https://www.cnblogs. ...
- 自制操作系统Antz(9)——实现内核 (下) 实现图形化界面
Antz系统更新地址: https://www.cnblogs.com/LexMoon/category/1262287.html Linux内核源码分析地址:https://www.cnblogs. ...
- 自制操作系统Antz(3)——进入保护模式 (中) 直接操作显存
Antz系统更新地址: https://www.cnblogs.com/LexMoon/category/1262287.html Linux内核源码分析地址:https://www.cnblogs. ...
- 自制操作系统Antz(4)——进入保护模式 (下) 实现内核并从硬盘载入
Antz系统更新地址: https://www.cnblogs.com/LexMoon/category/1262287.html Linux内核源码分析地址:https://www.cnblogs. ...
- 自制操作系统Antz(5)——深入理解保护模式与进入方法
Antz系统更新地址: https://www.cnblogs.com/LexMoon/category/1262287.html Linux内核源码分析地址:https://www.cnblogs. ...
随机推荐
- mvc模式的理解
一开始总是觉得dao层和service层没有区别,甚至觉得service层根本就是多余的,service层就是把dao层的内容调用了一下,然后重写了一次,后来才理解到,dao层是数据链路层,是与数据库 ...
- poj2362
#include<iostream> using namespace std; ]; int total; int rec; int n; ]; int flag; int flag1; ...
- Linux基础命令2
1.修改网络状态: 1).Cd /etc/sysconfig/network-scripts/network-scripts 2).vi ifcfg-eth0 编辑 onboot=yes: 3 ...
- 点击按钮如何改变当前窗口的url
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- JDK1.8 LongAdder 空间换时间: 比AtomicLong还高效的无锁实现
我们知道,AtomicLong的实现方式是内部有个value 变量,当多线程并发自增,自减时,均通过CAS 指令从机器指令级别操作保证并发的原子性. // setup to use Unsafe.co ...
- iTerm2 与 Oh My Zsh的配套使用
详见: https://www.jianshu.com/p/7de00c73a2bb https://github.com/sirius1024/iterm2-with-oh-my-zsh https ...
- POJ2762 Going from u to v or from v to u? 强连通分量缩点+拓扑排序
题目链接:https://vjudge.net/contest/295959#problem/I 或者 http://poj.org/problem?id=2762 题意:输入多组样例,输入n个点和m ...
- Markdown学习示例
Markdown学习示例 什么是Markdown Markdown是一种在web显示带样式风格文本的方式.你能通过它控制文本的字体样式.插入图片.插入列表等.通常,Markdown使用一些特殊的非字母 ...
- windows 下面安装make
1.前面文章中已经提到了wingw32的安装,安装好之后设置相应环境变量.2.打开cmd,输入 mingw-get install mingw32-make,会进行安装.3.输入 mingw32-ma ...
- 解决页面使用ifrmae后,在session失效后登录页面在子页面中显示(子窗体出现父窗体)
在登录页面中添加js判断当前页面是否是父页面,诺不是则父页面跳转至登录页面. <script type="text/javascript"> //解决登录后多个父窗体问 ...