手写操作系统 - 汇编实现进入保护模式

简介: 手写操作系统 - 汇编实现进入保护模式

前言

  1. 在了解段页门得基础上,理解如何从实时模式进入保护模式
  2. 如何引入C语言得开发与调试
  • 生成内核:汇编与C语言如何生成内核
  • 调试C语言
  • 汇编、C语言如何互调

手写64位操作系统内核规划图:

boot程序起始0扇区,共占1个扇区
setup程序起始1扇区,共占一个扇区2个扇区
x86内核起始 3扇区,共占一个扇区大于30个扇区

1、从实时模式进入保护模式

  1. 关中断
cli:是一个汇编指令,用于清除(禁用)中断标志位(IF位)在eflags寄存器中。当IF位被清除时,处理器将不响应可屏蔽的硬件中断,这常用于临界区代码,以避免在执行关键任务时被中断。
sti:用于设置(启用)中断标志位在eflags寄存器中。执行sti后,处理器将开始响应可屏蔽的硬件中断。这通常用于完成关键任务后重新启用中断。
eflags.IF:一个寄存器,其中的IF(Interrupt Flag)是eflags中的一个位,用于控制处理器是否响应可屏蔽的硬件中断。cli和sti指令分别用于清除和设置这个标志位。
  1. 开A20总线
考虑为什么要开A20?
; 开A20
in    al,  92h
or    al,  00000010b
out   92h, al
  1. 设置段寄存器、加载gdt表
内核态
  代码段、数据段
  2
-----------------------------
x64长模式
  4
tss
  用户态切内核态
8个
------------------------------
调用门
  1. cr0寄存器,cr0.pe = 1
cr0 :   pe位(进入保护模式)、pg(开启分页)
cr1:
cr2:  内存异常      4G     0x10000000    页机制
cr3:  页表的基址
  1. 来一个练习:32位,0-4g,代码段
Base;0
Limit::0xfffff
G:1        ;为0时Segment Limit单位为字节 2^20*1Byte = 1M  为1时单位4K 2^20*4K =4G
D/B:1
AVL:0
P:1
DPL:0   
S:1   ;代码段
TYPE:1000   ;Execule Only
-------------------------------------
高32位:0000 0000 1100 1111 1001 1000 0000 0000  ---> 0x00cf9800
低32位:0000 0000 0000 0000 1111 1111 1111 1111  ---> 0x0000ffff

2、如何引入C语言得开发与调试

  1. 生成内核:汇编与C语言如何生成内核
${BUILD}/kernel.bin: ${BUILD}/boot/head.o ${BUILD}/init/main.o
ld -m elf_i386 $^ -o $@ -Ttext 0x1200
非常重要:-Ttext 0x1200,指定代码入口,调试时候需要用
调试的时候,要选kenel.bin,因为这里面有调试符号,如果说你编译.o文件的时候,不带-g,那内核就是没办法调试
${BUILD}/system.bin: ${BUILD}/kernel.bin
objcopy -O binary ${BUILD}/kernel.bin ${BUILD}/system.bin
nm ${BUILD}/kernel.bin | sort > ${BUILD}/system.map(不是必须的)
  1. 调试C语言
1、内核依赖的所有文件编译的时候应该要带-g,生成调试符号
2、指定入口-Ttext 0x1200
3、要用qemu调试模式运行
    -s -S   socket  lo
    127.0.0.1:1234
    gdb kernel.bin
    target remote:1234
  1. 汇编、C语言如何互调
  • 汇编如何调用C语言中的函数
以汇编中掉调用C语言中c_test()函数,核心全局函数
汇编代码中增加:
  extern c_test
  gq_ctest:
     call c_test
C语言中:
  void c_test(void) {
      int a = 0;
      char* video = (char*)0xb8000;
      *video = 'Z';
  }

汇编如何访问C语言中的全局变量


         

C语言如何调用汇编语言的函数

C语言中调用gq_ctest()函数,核心是要将汇编中的void gq_ctest(void) 申明成全局函数

C语言如何访问汇编中定义的变量:地址

总结

代码地址

相关文章
|
4月前
|
存储 Java C语言
手写操作系统 --汇编执行流(一)
手写操作系统 --汇编执行流(一)
|
4月前
|
前端开发 Unix Linux
手写操作系统 --汇编执行流(二)
手写操作系统 --汇编执行流(二)
超详细汇编注释 操作系统实验二 操作系统的引导(哈工大李治军)(二)
超详细汇编注释 操作系统实验二 操作系统的引导(哈工大李治军)(二)
128 0
超详细汇编注释 操作系统实验二 操作系统的引导(哈工大李治军)(二)
|
存储 Ubuntu Linux
超详细汇编注释 操作系统实验二 操作系统的引导(哈工大李治军)(一)
超详细汇编注释 操作系统实验二 操作系统的引导(哈工大李治军)(一)
175 0
超详细汇编注释 操作系统实验二 操作系统的引导(哈工大李治军)(一)
|
程序员 C语言 编译器
《操作系统真象还原》——0.16 为什么说汇编语言比C语言快
不管用什么语言,程序最终都是给CPU运行的,只有CPU才能让程序跑起来。CPU不知道什么是汇编语言、C语言,甚至Java、PHP、Python等,它根本不知道交给它的指令曾经经历过那么多的解释、编译工序。不管什么语言,编译器最终翻译出来的都是机器指令。
2615 0
|
21天前
|
监控 Unix Linux
Linux操作系统调优相关工具(四)查看Network运行状态 和系统整体运行状态
Linux操作系统调优相关工具(四)查看Network运行状态 和系统整体运行状态
32 0
|
22天前
|
Linux 编译器 开发者
Linux设备树解析:桥接硬件与操作系统的关键架构
在探索Linux的庞大和复杂世界时🌌,我们经常会遇到许多关键概念和工具🛠️,它们使得Linux成为了一个强大和灵活的操作系统💪。其中,"设备树"(Device Tree)是一个不可或缺的部分🌲,尤其是在嵌入式系统🖥️和多平台硬件支持方面🔌。让我们深入了解Linux设备树是什么,它的起源,以及为什么Linux需要它🌳。
Linux设备树解析:桥接硬件与操作系统的关键架构
|
2月前
|
Linux 数据安全/隐私保护 虚拟化
Linux技术基础(1)——操作系统的安装
本文是龙蜥操作系统(Anolis OS) 8.4 的安装指南,用户可以从[龙蜥社区下载页面](https://openanolis.cn/download)获取ISO镜像。安装方法包括物理机的光驱和USB闪存方式,以及虚拟机中的VMware Workstation Pro设置。安装过程涉及选择语言、配置安装目标、选择软件集合和内核,设置Root密码及创建新用户。安装完成后,可通过文本模式或图形化界面验证系统版本,如Anolis OS 8.4,标志着安装成功。