一步一步实现一个简单的OS(进入保护模式)
2016-03-03 10:12
363 查看
这块的基础至少,网上太多了,自己看去吧,
废话不多说,直接贴代码
具体代码到群里面找。。。。。。。
545250960
废话不多说,直接贴代码
# bootasm.S # 加载Setup模块 .set SETUP_SEG, 0x0000 # SETUP模块加载段地址 .set SETUP_OFF, 0x7D00 # SETUP模块加载偏移地址 .globl start start: # 入口地址 .code16 # 声明是16位代码(为什么启动时要用16位代码。。。。自己百度去,,,) cld # 字符串运算方向,(具体的,百度吧,基础) # 初始化各个段寄存器 xorw %ax, %ax movw %ax, %ds movw %ax, %es movw %ax, %ss movw $start, %sp # 保存引导驱动器号 movb %dl, (bootdrv) # 清屏 movw $0x02, %ax int $0x10 # 显示信息 movw $str, %si call puts # 读第二个扇区,到内存的0x07D00(0x0000:0x7D00)处, 两个扇区 movl $1, %eax # 扇区号 movw $2, %cx # 扇区数 movw $SETUP_SEG, %bx # buffer 地址 movw %bx, %es movw $SETUP_OFF, %bx call readdisk # 跳转到刚刚加载到内存中的SETUP模块 ljmp $SETUP_SEG, $SETUP_OFF # # 字符串显示函数 # 输入: # ds:si = 字符串地址 # puts: movw $0x07, %bx movb $0x0E, %ah 1: lodsb orb %al, %al jz 1f int $0x10 jmp 1b 1: ret # # 读磁盘扇区 # # 输入: eax = 要读LBA扇区号 # cx = 扇区数(一次读入的字节数不能大于64KB) # es:bx = 数据缓存区 # readdisk: pushal movb (bootdrv), %dl pushl $0 pushl %eax pushw %es pushw %bx pushw %cx pushw $0x0010 movb $0x42, %ah movw %sp, %si int $0x13 addw $0x10, %sp popal ret bootdrv: .byte 0 str: .string "in the boot code\n\r"
# setupasm.S # 开启保护模式 #include "asm.h" .set SETUP_SEG, 0x0000 # SETUP模块加载段地址 .set SETUP_OFF, 0x7D00 # SETUP模块加载偏移地址 .set PROT_MODE_CSEG, 0x8 # 代码段选择符 .set PROT_MODE_DSEG, 0x10 # 数据段选择符 .set CR0_PE_ON, 0x1 # 保护模式开启标志位 .globl start start: # 入口地址 .code16 # 声明是16位代码(为什么启动时要用16位代码。。。。自己百度去,,,) cld # 字符串运算方向,(具体的,百度吧,基础) # 初始化各个段寄存器 movw %cs, %ax movw %ax, %ds movw %ax, %es movw %ax, %ss movw $start, %sp # 显示信息 movw $info, %si call puts # --------------------------------------------------------------------------# # 下面是进入保护模式的代码,和网上的多少有些不一样。。。 # # --------------------------------------------------------------------------# # 关中断 cli # 加载GDTR lgdt gdtdesc # 保护模式标志位置位 movl %cr0, %eax orl $CR0_PE_ON, %eax movl %eax, %cr0 # 长跳转,进入32位代码段, 开启保护模式在这条以后就彻底搞定了 ljmp $PROT_MODE_CSEG, $start32 # # 字符串显示函数 # 输入: # ds:si = 字符串地址 # puts: movw $0x07, %bx movb $0x0E, %ah 1: lodsb orb %al, %al jz 1f int $0x10 jmp 1b 1: ret # --------------------------------------------------------------------------# # 这个就是32位保护模式的代码了。。。 # # --------------------------------------------------------------------------# .code32 # 下面的代码编译为32位的 start32: # 初始化保护模式下的各个段的段寄存器 movw $PROT_MODE_DSEG, %ax movw %ax, %ds movw %ax, %es movw %ax, %fs movw %ax, %gs movw %ax, %ss movl $start32, %esp # 之前的代码没用了,让堆栈覆盖了吧 # 得显示个东西,这样就知道CPU是不是真的跑到这里了 # 那本书上这一块显示的是一个红色的P, # 那咱们这里,为了证明是原创,就显示一个绿色的P吧,嘿嘿 movw $0x0A00 | 'P', (0xB8100) # 好了,到这里死循环吧,下节,弄C语言的,这样看起来就简单多了 # 其实,我觉得,还是这个简单 1: hlt jmp 1b info: .string "in the setup code!!!\n\r" # GDT,需要4字节对齐 .p2align 2 gdt: SEG_NULLASM # 空的,保留了 SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff) # 代码段 SEG_ASM(STA_W, 0x0, 0xffffffff) # 数据段 gdtdesc: .word 0x17 # gdt长度减1 .long gdt # gdt物理地址
具体代码到群里面找。。。。。。。
545250960
相关文章推荐
- 如何设置端口对外网开放
- 《C++高级进阶》读书笔记 第一章 C++基础知识
- .Net Discovery 系列之七--深入理解.Net垃圾收集机制(拾贝篇)
- CPU呈现正弦函数曲线
- EXCEL 如何将多个工作表或工作簿合并到一个工作表
- 很有用的PHP笔试题系列二
- 基于wheel的省市县,界面实现优化
- Android Studio导入eclipse的工程
- Android Studio导入eclipse的工程
- 什么是EJB
- Android Studio的Git与Github配置
- Caffe的卷积原理
- android 控件的setClickable、setEnabled 、setFocusable
- iOS开发UI篇—CAlayer层的属性
- 成都Uber优步司机奖励政策(3月3日)
- Android版:验证手机号码的正则表达式 (转)
- swap()函数的几种情况详解
- 很有用的PHP笔试题系列一
- PHP笔试题
- .Net Discovery 系列之六--深入浅出.Net实时编译机制(下)