这块的基础至少,网上太多了,自己看去吧,
废话不多说,直接贴代码
# 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