[RabbitOS] 进保护模式小玩了一下

NeuronR 2009-02-19
#include "pm.h"

.code16
.text

    jmp     LoaderStart

# descriptors
GDT_NA: Descriptor 0, 0, 0
ProModeCSDescriptor: Descriptor 0, (PM_LEN - 1), (DA_C + DA_32)
VideoDescriptor: Descriptor 0x0B8000, 0xffff, DA_DRW

.equ    SelectorProMode, (ProModeCSDescriptor - GDT_NA)
.equ    SelectorVideo, (VideoDescriptor  - GDT_NA)

GDT48:.word (. - GDT_NA - 1)
      .long 0

LoaderStart:
    xor     %eax, %eax
    mov     %cs, %ax
    shl     $4, %ax
    addl    $GDT_NA, %eax
    movl    %eax, (GDT48 + 2)         # set gdt base

    xor     %eax, %eax
    mov     %cs, %ax
    shl     $4, %ax
    addl    $ProModeStart, %eax
    FillDescBase ProModeCSDescriptor  # set protected mode descriptor

    lgdtw   GDT48
    cli

    inb     $0x92, %al
    orb     $0b00000010, %al
    outb    %al, $0x92        # enable a20 address line

    movl    %cr0, %eax
    orl     $1, %eax
    movl    %eax, %cr0        # enable pe-bit in cr0

    # go ~
    ljmpl   $SelectorProMode, $0

.code32
ProModeStart:
    mov     $(SelectorVideo), %ax
    mov     %ax, %gs

    movl    $((80 * 10 + 0) * 2), %edi
    movb    $0xC, %ah
    movb    $'P', %al

    mov     %ax, %gs:(%edi)

    jmp     .
.equ PM_LEN, . - ProModeStart

.org 510
.word 0xaa55

/* chapter3/1/pm.h

   Author: Wenbo Yang <solrex@gmail.com> <http://solrex.cn>

   This file is part of the source code of book "Write Your Own OS with Free
   and Open Source Software". Homepage @ <http://share.solrex.cn/WriteOS/>.

   This file is licensed under the GNU General Public License; either
   version 3 of the License, or (at your option) any later version. */

/* Comments below accords to "Chapter 3.4.5: Segment Descriptors" of "Intel
   64 and IA-32 Arch. SW Developer's Manual: Volume 3A: System Programming
   Guide". */

/* GDT Descriptor Attributes
     DA_  : Descriptor Attribute
     D    : Data Segment
     C    : Code Segment
     S    : System Segment
     R    : Read-only
     RW   : Read/Write
     A    : Access */
.set    DA_32,  0x4000  /* 32-bit segment */

/* Descriptor privilege level */
.set    DA_DPL0,  0x00  /* DPL = 0 */
.set    DA_DPL1,  0x20  /* DPL = 1 */
.set    DA_DPL2,  0x40  /* DPL = 2 */
.set    DA_DPL3,  0x60  /* DPL = 3 */

/* GDT Code- and Data-Segment Types */
.set    DA_DR,   0x90   /* Read-Only */
.set    DA_DRW,  0x92   /* Read/Write */
.set    DA_DRWA, 0x93   /* Read/Write, accessed */
.set    DA_C,    0x98   /* Execute-Only */
.set    DA_CR,   0x9A   /* Execute/Read */
.set    DA_CCO,  0x9C   /* Execute-Only, conforming */
.set    DA_CCOR, 0x9E   /* Execute/Read-Only, conforming */

/* GDT System-Segment and Gate-Descriptor Types */
.set    DA_LDT,      0x82    /* LDT */
.set    DA_TaskGate, 0x85    /* Task Gate */
.set    DA_386TSS,   0x89    /* 32-bit TSS(Available) */
.set    DA_386CGate, 0x8C    /* 32-bit Call Gate */
.set    DA_386IGate, 0x8E    /* 32-bit Interrupt Gate */
.set    DA_386TGate, 0x8F    /* 32-bit Trap Gate */

/* Selector Attributes */
.set    SA_RPL0, 0
.set    SA_RPL1, 1
.set    SA_RPL2, 2
.set    SA_RPL3, 3
.set    SA_TIG,  0
.set    SA_TIL,  4

/* MACROS */

/* Segment Descriptor data structure.
   Usage: Descriptor Base, Limit, Attr
    Base:  4byte 
    Limit: 4byte (low 20 bits available)
    Attr:  2byte (lower 4 bits of higher byte are always 0) */
.macro Descriptor Base, Limit, Attr
    .word  \Limit & 0xFFFF
    .word  \Base & 0xFFFF
    .byte   (\Base >> 16) & 0xFF
    .word  ((\Limit >> 8) & 0xF00) | (\Attr & 0xF0FF)
    .byte   (\Base >> 24) & 0xFF
.endm

/*
 * fill the BASE 4bytes of a descriptor
 * assuming %EAX holds base value.
 * after this macro the value in %EAX is junk, so save eax if needed.
 */
.macro FillDescBase Desc
    movw    %ax, (\Desc + 2)
    shr     $16, %eax
    movb    %al, (\Desc + 4)
    movb    %ah, (\Desc + 7)
.endm

/* Gate Descriptor data structure.
   Usage: Gate Selector, Offset, PCount, Attr
    Selector:  2byte
    Offset:    4byte
    PCount:    byte
    Attr:      byte */
.macro Gate  Selector, Offset, PCount, Attr
    .word     (\Offset & 0xFFFF)
    .word     \Selector
    .word     (\PCount & 0x1F) | ((\Attr << 8) & 0xFF00)
    .word     ((\Offset >> 16) & 0xFFFF)
.endm

第二个文件基本上原样使用的某参考资料中的,不过加了个宏FillDescBase用于填充一个描述符散落在各处的基址信息。
另外就是进了保护模式以后好像不能开中断了,我为了一个sti搞了半个下午……所以输出也只好抄来个视频段打印个大红的P在中间,这个视频段怎么玩啊,有文档否?

在cygwin下开发还是很郁闷的,因为不能mount,所以只好把东西都塞进引导扇区。。。
crackcell 2009-02-19
恩,不错……加油
lin_llx 2009-02-19
不错不错。。。我现在在实模式流连忘返了。。
crackcell 2009-02-22
NeuronR 写道
#include "pm.h"

.code16
.text

    jmp     LoaderStart

# descriptors
GDT_NA: Descriptor 0, 0, 0
ProModeCSDescriptor: Descriptor 0, (PM_LEN - 1), (DA_C + DA_32)
VideoDescriptor: Descriptor 0x0B8000, 0xffff, DA_DRW

.equ    SelectorProMode, (ProModeCSDescriptor - GDT_NA)
.equ    SelectorVideo, (VideoDescriptor  - GDT_NA)

GDT48:.word (. - GDT_NA - 1)
      .long 0

LoaderStart:
    xor     %eax, %eax
    mov     %cs, %ax
    shl     $4, %ax
    addl    $GDT_NA, %eax
    movl    %eax, (GDT48 + 2)         # set gdt base

    xor     %eax, %eax
    mov     %cs, %ax
    shl     $4, %ax
    addl    $ProModeStart, %eax
    FillDescBase ProModeCSDescriptor  # set protected mode descriptor

    lgdtw   GDT48
    cli

    inb     $0x92, %al
    orb     $0b00000010, %al
    outb    %al, $0x92        # enable a20 address line

    movl    %cr0, %eax
    orl     $1, %eax
    movl    %eax, %cr0        # enable pe-bit in cr0

    # go ~
    ljmpl   $SelectorProMode, $0

.code32
ProModeStart:
    mov     $(SelectorVideo), %ax
    mov     %ax, %gs

    movl    $((80 * 10 + 0) * 2), %edi
    movb    $0xC, %ah
    movb    $'P', %al

    mov     %ax, %gs:(%edi)

    jmp     .
.equ PM_LEN, . - ProModeStart

.org 510
.word 0xaa55

/* chapter3/1/pm.h

   Author: Wenbo Yang <solrex@gmail.com> <http://solrex.cn>

   This file is part of the source code of book "Write Your Own OS with Free
   and Open Source Software". Homepage @ <http://share.solrex.cn/WriteOS/>.

   This file is licensed under the GNU General Public License; either
   version 3 of the License, or (at your option) any later version. */

/* Comments below accords to "Chapter 3.4.5: Segment Descriptors" of "Intel
   64 and IA-32 Arch. SW Developer's Manual: Volume 3A: System Programming
   Guide". */

/* GDT Descriptor Attributes
     DA_  : Descriptor Attribute
     D    : Data Segment
     C    : Code Segment
     S    : System Segment
     R    : Read-only
     RW   : Read/Write
     A    : Access */
.set    DA_32,  0x4000  /* 32-bit segment */

/* Descriptor privilege level */
.set    DA_DPL0,  0x00  /* DPL = 0 */
.set    DA_DPL1,  0x20  /* DPL = 1 */
.set    DA_DPL2,  0x40  /* DPL = 2 */
.set    DA_DPL3,  0x60  /* DPL = 3 */

/* GDT Code- and Data-Segment Types */
.set    DA_DR,   0x90   /* Read-Only */
.set    DA_DRW,  0x92   /* Read/Write */
.set    DA_DRWA, 0x93   /* Read/Write, accessed */
.set    DA_C,    0x98   /* Execute-Only */
.set    DA_CR,   0x9A   /* Execute/Read */
.set    DA_CCO,  0x9C   /* Execute-Only, conforming */
.set    DA_CCOR, 0x9E   /* Execute/Read-Only, conforming */

/* GDT System-Segment and Gate-Descriptor Types */
.set    DA_LDT,      0x82    /* LDT */
.set    DA_TaskGate, 0x85    /* Task Gate */
.set    DA_386TSS,   0x89    /* 32-bit TSS(Available) */
.set    DA_386CGate, 0x8C    /* 32-bit Call Gate */
.set    DA_386IGate, 0x8E    /* 32-bit Interrupt Gate */
.set    DA_386TGate, 0x8F    /* 32-bit Trap Gate */

/* Selector Attributes */
.set    SA_RPL0, 0
.set    SA_RPL1, 1
.set    SA_RPL2, 2
.set    SA_RPL3, 3
.set    SA_TIG,  0
.set    SA_TIL,  4

/* MACROS */

/* Segment Descriptor data structure.
   Usage: Descriptor Base, Limit, Attr
    Base:  4byte 
    Limit: 4byte (low 20 bits available)
    Attr:  2byte (lower 4 bits of higher byte are always 0) */
.macro Descriptor Base, Limit, Attr
    .word  \Limit & 0xFFFF
    .word  \Base & 0xFFFF
    .byte   (\Base >> 16) & 0xFF
    .word  ((\Limit >> 8) & 0xF00) | (\Attr & 0xF0FF)
    .byte   (\Base >> 24) & 0xFF
.endm

/*
 * fill the BASE 4bytes of a descriptor
 * assuming %EAX holds base value.
 * after this macro the value in %EAX is junk, so save eax if needed.
 */
.macro FillDescBase Desc
    movw    %ax, (\Desc + 2)
    shr     $16, %eax
    movb    %al, (\Desc + 4)
    movb    %ah, (\Desc + 7)
.endm

/* Gate Descriptor data structure.
   Usage: Gate Selector, Offset, PCount, Attr
    Selector:  2byte
    Offset:    4byte
    PCount:    byte
    Attr:      byte */
.macro Gate  Selector, Offset, PCount, Attr
    .word     (\Offset & 0xFFFF)
    .word     \Selector
    .word     (\PCount & 0x1F) | ((\Attr << 8) & 0xFF00)
    .word     ((\Offset >> 16) & 0xFFFF)
.endm

第二个文件基本上原样使用的某参考资料中的,不过加了个宏FillDescBase用于填充一个描述符散落在各处的基址信息。
另外就是进了保护模式以后好像不能开中断了,我为了一个sti搞了半个下午……所以输出也只好抄来个视频段打印个大红的P在中间,这个视频段怎么玩啊,有文档否?

在cygwin下开发还是很郁闷的,因为不能mount,所以只好把东西都塞进引导扇区。。。


关于mount的问题,你再建立个虚拟机,装个windows,把img挂上去就可以用了。
视频段的操作参看stage2 console部分的代码,其实就是一个数组,对应屏幕上的一个位置,你放什么东西上去,就利马显示出来了。
NeuronR 2009-02-22
引用
关于mount的问题,你再建立个虚拟机

我现在就是这样做的,咩哈哈,是个ubuntu虚拟机,干脆就在虚拟机下开发好了,然后把文件贴到镜像里面去,hoho
Global site tag (gtag.js) - Google Analytics