|
源程序
------------------------------------------------------
#define CR0_PE 1
.text
.code16
.globl _start
_start:
jmp start0
nop
mesg1:
.ascii "Loading...... "
mesg2:
.ascii "Ready........ "
##################### idt ########################
idt:
.word 0
.word 0, 0
##################### gdt ########################
.align 16
gdt:
.word 0, 0
.byte 0, 0x00, 0x00, 0
bootcodeseg = . - gdt
.word 0xffff, 0
.byte 0, 0x9e, 0x4f, 0
bootdataseg = . - gdt
.word 0xffff, 0
.byte 0, 0x92, 0x4f, 0
videoseg = . - gdt
.word 0x3999, 0x8000
.byte 0x0b, 0x92, 0x00, 0x00
bootrealseg = . - gdt
.word 0xffff, 0
.byte 0, 0x9e, 0x00, 0
bootrealdata = . - gdt
.word 0xffff, 0
.byte 0, 0x92, 0x00, 0
gdtlen = . - gdt
.align 16
gdtarg:
.word gdtlen-1 /* limit */
.long 0 /* physical addr, will be inserted */
ourseg: .word 0 /* real mode code and data segment */
stkseg: .word 0 /* real mode stack segment */
stkdif: .long 0 /* diff. between real and prot sp */
#
# start of code
#
start0:
mov %cs, %ax /* don't trust values of ds, es or ss */
mov %ax, %ds
mov %ax, %es
mov %ax, %ss
mov $0xfffc, %sp
xor %ax, %ax /* in particular ah = 0 */
int $0x13
call clrscr
movw $mesg1,%bp
call prt_msg
call get_key
call clrscr
call gdt_fixup
movw $mesg2,%bp
call prt_msg
call get_key
call clrscr
call real_to_prot
loop:
jmp loop
gdt_fixup:
.code16
pushw %ax
pushw %dx
xorl %eax, %eax
mov %cs, %ax
mov %ax, ourseg
/* sort out stuff for %ss != %ds */
movw %ss, %dx
movw %dx, stkseg
subw %ax, %dx
shll $16, %edx
shrl $12, %edx
movl %edx, stkdif
/* fix up GDT entries for bootstrap */
mov %ax, %dx
shll $4, %eax
shr $12, %dx
#define FIXUP(gdt_index) \
movw %ax, gdt+gdt_index+2; \
movb %dl, gdt+gdt_index+4
FIXUP(bootcodeseg)
FIXUP(bootrealseg)
FIXUP(bootdataseg)
/* fix up GDT pointer */
addl $gdt, %eax
movl %eax, gdtarg+2
pop %dx
pop %ax
ret
real_to_prot:
.code16
pushl %eax
cli
lidt %cs:idt
lgdt %cs:gdtarg /* Global descriptor table */
movl %cr0, %eax
or $CR0_PE, %ax
movl %eax, %cr0 /* Enter 'protected mode' */
ljmp $bootcodeseg, $1f /* Jump into a 32bit segment */
1:
.code32
dbg:
jmp dbg
/* Set all the segment registers to map the same area as the code */
mov $bootdataseg, %eax
mov %ax, %ds
mov %ax, %es
mov %ax, %ss
addl stkdif, %esp /* Allow for real %ss != %ds */
mov $videoseg, %eax
mov %ax, %gs
movw $0x741,0x000b8000
spin:
jmp spin
popl %eax
ret
prt_msg:
.code16
movb $0x13,%ah
movb $0x00,%al
movw $0x0007,%bx
movw $0x14,%cx
movw $0x0000,%dx
int $0x10
ret
get_key:
.code16
movb $0x00,%ah
int $0x16
ret
clrscr:
.code16
movw $0x0600,%ax
movw $0x0000,%cx
movw $0x174f,%dx
movb $0x0, %bh
int $0x10
ret
.org 510
boot_flag:
.word 0xAA55
------------------------------------------------------
中间那个ljmp是进入32位代码,我加了个死循环在那里,每次
执行到这里系统就重启了,应该是发生异常了。
makefile:
------------------------------------------------------
boot : bootp.out
objcopy -S -O binary bootp.out boot
bootp.out : bootp.o
ld -nostdlib -static -N -e _start -Ttext 0x7c00 -o bootp.out : bootp.o
bootp.o : _bootp.S
as -o bootp.o _bootp.S
_bootp.S : bootp.S
cc -o _bootp.S -E bootp.S
clean :
rm -rf bootp.o bootp.out _bootp.S
install :
dd bs=512 if=boot of=/dev/fd0
------------------------------------------------------
执行make编译,make clean删除中间文件,make install 写到软盘
执行说明:
用生成的软盘启动,看到打印字符串按任意键继续
程序功能:
进入保护模式并使用显存地址0x000b:8000显示一个白色的A
问题:
一执行进入32位代码的跳转系统就重启,怎么也没搞明白为什么。
另:
大家有知道什么debug工具可以跟踪这种程序? |
|