LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 840|回复: 2

一段进入保护模式的程序,那位大侠给看看那有问题?

[复制链接]
发表于 2003-6-26 15:37:47 | 显示全部楼层 |阅读模式
源程序
------------------------------------------------------
#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工具可以跟踪这种程序?
 楼主| 发表于 2003-6-26 15:41:28 | 显示全部楼层

对不起格式坏了

源程序

  1. #define        CR0_PE                1

  2.         .text
  3.         .code16
  4.         .globl _start
  5. _start:
  6.         jmp  start0
  7.         nop  
  8. mesg1:
  9.         .ascii "Loading......       "
  10. mesg2:
  11.         .ascii "Ready........       "
  12. ##################### idt ########################
  13. idt:
  14.         .word   0
  15.         .word   0, 0
  16. ##################### gdt ########################
  17.         .align  16
  18. gdt:
  19.         .word        0, 0
  20.         .byte        0, 0x00, 0x00, 0
  21. bootcodeseg = . - gdt
  22.         .word        0xffff, 0
  23.         .byte        0, 0x9e, 0x4f, 0
  24. bootdataseg = . - gdt
  25.         .word        0xffff, 0
  26.         .byte        0, 0x92, 0x4f, 0
  27. videoseg    = . - gdt
  28.         .word 0x3999, 0x8000
  29.         .byte 0x0b, 0x92, 0x00, 0x00
  30. bootrealseg = . - gdt
  31.         .word        0xffff, 0
  32.         .byte        0, 0x9e, 0x00, 0
  33. bootrealdata = . - gdt
  34.         .word        0xffff, 0
  35.         .byte        0, 0x92, 0x00, 0
  36. gdtlen = . - gdt
  37.         .align        16
  38. gdtarg:
  39.         .word        gdtlen-1                /* limit */
  40.         .long        0                        /* physical addr, will be inserted */
  41. ourseg:        .word        0                        /* real mode code and data segment */
  42. stkseg:        .word        0                        /* real mode stack segment */
  43. stkdif:        .long        0                        /* diff. between real and prot sp */
  44. #
  45. # start of code
  46. #
  47. start0:
  48.         mov        %cs, %ax                /* don't trust values of ds, es or ss */
  49.         mov        %ax, %ds
  50.         mov        %ax, %es
  51.         mov        %ax, %ss
  52.         mov        $0xfffc, %sp

  53.         xor        %ax, %ax                /* in particular ah = 0 */
  54.         int        $0x13

  55.         call    clrscr
  56.         movw    $mesg1,%bp
  57.         call    prt_msg
  58.         call    get_key
  59.         call    clrscr
  60.         call    gdt_fixup
  61.         movw    $mesg2,%bp
  62.         call    prt_msg
  63.         call    get_key
  64.         call    clrscr
  65.         call    real_to_prot
  66. loop:
  67.         jmp loop
  68. gdt_fixup:
  69.         .code16
  70.         pushw        %ax
  71.         pushw        %dx

  72.         xorl        %eax, %eax
  73.         mov        %cs, %ax
  74.         mov        %ax, ourseg
  75.         /* sort out stuff for %ss != %ds */
  76.         movw        %ss, %dx
  77.         movw        %dx, stkseg
  78.         subw        %ax, %dx
  79.         shll        $16, %edx
  80.         shrl        $12, %edx
  81.         movl        %edx, stkdif

  82.         /* fix up GDT entries for bootstrap */
  83.         mov        %ax, %dx
  84.         shll        $4, %eax
  85.         shr        $12, %dx

  86. #define FIXUP(gdt_index)              \
  87.         movw        %ax, gdt+gdt_index+2; \
  88.         movb        %dl, gdt+gdt_index+4

  89.         FIXUP(bootcodeseg)
  90.         FIXUP(bootrealseg)
  91.         FIXUP(bootdataseg)

  92.         /* fix up GDT pointer */
  93.         addl        $gdt, %eax
  94.         movl        %eax, gdtarg+2       
  95.        
  96.         pop        %dx
  97.         pop        %ax
  98.         ret

  99. real_to_prot:
  100.         .code16
  101.         pushl        %eax
  102.         cli

  103.         lidt        %cs:idt
  104.         lgdt        %cs:gdtarg                /* Global descriptor table */

  105.         movl        %cr0, %eax
  106.         or        $CR0_PE, %ax
  107.         movl        %eax, %cr0                 /* Enter 'protected mode' */
  108.         ljmp        $bootcodeseg, $1f        /* Jump into a 32bit segment */
  109. 1:
  110.         .code32
  111. dbg:
  112.         jmp     dbg
  113.         /*  Set all the segment registers to map the same area as the code */
  114.         mov        $bootdataseg, %eax
  115.         mov        %ax, %ds
  116.         mov        %ax, %es
  117.         mov        %ax, %ss
  118.         addl        stkdif, %esp                /* Allow for real %ss != %ds */
  119.        
  120.         mov     $videoseg, %eax
  121.         mov     %ax, %gs
  122.         movw    $0x741,0x000b8000
  123. spin:
  124.         jmp     spin
  125.         popl        %eax
  126.         ret

  127. prt_msg:
  128.         .code16
  129.         movb $0x13,%ah
  130.         movb $0x00,%al
  131.         movw $0x0007,%bx
  132.         movw $0x14,%cx
  133.         movw $0x0000,%dx
  134.         int  $0x10
  135.         ret
  136. get_key:
  137.         .code16
  138.         movb   $0x00,%ah
  139.         int    $0x16
  140.         ret
  141. clrscr:
  142.         .code16
  143.         movw $0x0600,%ax
  144.         movw $0x0000,%cx
  145.         movw $0x174f,%dx
  146.         movb $0x0,   %bh
  147.         int  $0x10
  148.         ret


  149.         .org 510
  150. boot_flag:
  151.         .word 0xAA55
复制代码

make文件

  1. boot : bootp.out
  2.         objcopy -S -O binary bootp.out boot
  3. bootp.out : bootp.o
  4.         ld -nostdlib -static -N -e _start -Ttext 0x7c00 -o bootp.out bootp.o
  5. bootp.o : _bootp.S
  6.         as -o bootp.o _bootp.S
  7. _bootp.S : bootp.S
  8.         cc -o _bootp.S -E bootp.S
  9. clean :
  10.         rm -rf bootp.o bootp.out _bootp.S
  11. install :
  12.         dd bs=512 if=boot of=/dev/fd0
复制代码
发表于 2003-7-1 15:20:07 | 显示全部楼层
全局描述符设得对吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表