[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 |