|
发表于 2021-11-23 20:46:24
|
显示全部楼层
read.s .code16
.globl _start
_start:
lgdtw gdtr + 0x7c00
# 打开A20地址线
inb $0x92, %al
orb $0x02, %al
outb %al, $0x92
cli # bootsect不打算建立保护模式下的中断机制
# 进入保护模式
movl %cr0, %eax
orl $1, %eax
movl %eax, %cr0
ljmpl $8, $flush + 0x7c00
.code32
flush:
movw $16, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
movl $0xa0000, %esp
movl %esp, %ebp
subl $512, %esp
subl $8, %esp
leal -512(%ebp), %eax
movl $100, %ebx
movl %eax, (%esp)
movl %ebx, 4(%esp)
calll read_sect
leal -512(%ebp), %ebx
movb (%ebx), %al
movb %al, 0xb8000
movb 1(%ebx), %al
movb %al, 0xb8002
movb 2(%ebx), %al
movb %al, 0xb8004
movb 3(%ebx), %al
movb %al, 0xb8006
movb 4(%ebx), %al
movb %al, 0xb8008
leal -512(%ebp), %eax
movl $101, %ebx
movl %eax, (%esp)
movl %ebx, 4(%esp)
calll read_sect
leal -512(%ebp), %ebx
movb (%ebx), %al
movb %al, 0xb80a0
movb 1(%ebx), %al
movb %al, 0xb80a2
movb 2(%ebx), %al
movb %al, 0xb80a4
movb 3(%ebx), %al
movb %al, 0xb80a6
movb 4(%ebx), %al
movb %al, 0xb80a8
1:
hlt
jmp 1b
#void read_sect(uint8_t *buf, size_t start_sect);
read_sect:
pushl %ebp
movl %esp, %ebp
pushl %edi
# 读取1个扇区
movb $1, %al
movl $0x1f2, %edx
outb %al, %dx
# 下面发送逻辑扇区号
# 0~7
movl 12(%ebp), %ecx
movl %ecx, %eax
movl $0x1f3, %edx
outb %al, %dx
# 8~15
movl %ecx, %eax
shrl $8, %eax
movl $0x1f4, %edx
outb %al, %dx
# 16~23
movl %ecx, %eax
shrl $16, %eax
movl $0x1f5, %edx
outb %al, %dx
# LBA28模式, 主盘
# LBA地址24~27
movl %ecx, %eax
shrl $24, %eax
andl $0x0f, %eax
orl $0xe0, %eax
movl $0x1f6, %edx
outb %al, %dx
# 发送读命令
movb $0x20, %al
movl $0x1f7, %edx
outb %al, %dx
# 等待硬盘准备好
.L1:
inb %dx, %al
andb $0x88, %al
cmpb $0x08, %al
jne .L1
# 从硬盘读取数据
movl 8(%ebp), %edi
movl $256, %ecx
movl $0x1f0, %edx
cld
rep insw
popl %edi
popl %ebp
retl
.align 4
gdt:
# 空描述符
.int 0, 0
# 代码段描述符
# 段基地址: 0
# 段界限: 4GB
.int 0x0000ffff, 0x00cf9a00
# 数据段描述符
# 段基地址: 0
# 段界限: 4GB
.int 0x0000ffff, 0x00cf9200
gdtr:
.short (. - gdt - 1)
.int (gdt + 0x7c00)
write.s .code16
.globl _start
_start:
lgdtw gdtr + 0x7c00
# 打开A20地址线
inb $0x92, %al
orb $0x02, %al
outb %al, $0x92
cli # bootsect不打算建立保护模式下的中断机制
# 进入保护模式
movl %cr0, %eax
orl $1, %eax
movl %eax, %cr0
ljmpl $8, $flush + 0x7c00
.code32
flush:
movw $16, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
movl $0xa0000, %esp
movl %esp, %ebp
subl $512, %esp
subl $8, %esp
leal -512(%ebp), %ebx
movb $'h', (%ebx)
movb $'e', 1(%ebx)
movb $'l', 2(%ebx)
movb $'l', 3(%ebx)
movb $'o', 4(%ebx)
leal -512(%ebp), %eax
movl $100, %ebx
movl %eax, (%esp)
movl %ebx, 4(%esp)
calll write_sect
leal -512(%ebp), %ebx
movb $'w', (%ebx)
movb $'o', 1(%ebx)
movb $'r', 2(%ebx)
movb $'l', 3(%ebx)
movb $'d', 4(%ebx)
leal -512(%ebp), %eax
movl $101, %ebx
movl %eax, (%esp)
movl %ebx, 4(%esp)
calll write_sect
1:
hlt
jmp 1b
#void write_sect(const uint8_t *buf, size_t start_sect);
write_sect:
pushl %ebp
movl %esp, %ebp
pushl %esi
# 写入1个扇区
movb $1, %al
movl $0x1f2, %edx
outb %al, %dx
# 下面发送逻辑扇区号
# 0~7
movl 12(%ebp), %ecx
movl %ecx, %eax
movl $0x1f3, %edx
outb %al, %dx
# 8~15
movl %ecx, %eax
shrl $8, %eax
movl $0x1f4, %edx
outb %al, %dx
# 16~23
movl %ecx, %eax
shrl $16, %eax
movl $0x1f5, %edx
outb %al, %dx
# LBA28模式, 主盘
# LBA地址24~27
movl %ecx, %eax
shrl $24, %eax
andl $0x0f, %eax
orl $0xe0, %eax
movl $0x1f6, %edx
outb %al, %dx
# 发送写命令
movb $0x30, %al
movl $0x1f7, %edx
outb %al, %dx
# 等待硬盘准备好
.L1:
inb %dx, %al
andb $0x88, %al
cmpb $0x08, %al
jne .L1
# 把数据写入硬盘
movl 8(%ebp), %esi
movl $256, %ecx
movl $0x1f0, %edx
cld
rep outsw
popl %esi
popl %ebp
retl
.align 4
gdt:
# 空描述符
.int 0, 0
# 代码段描述符
# 段基地址: 0
# 段界限: 4GB
.int 0x0000ffff, 0x00cf9a00
# 数据段描述符
# 段基地址: 0
# 段界限: 4GB
.int 0x0000ffff, 0x00cf9200
gdtr:
.short (. - gdt - 1)
.int (gdt + 0x7c00)
|
|