Внимание - защищенный режим
NB! Код написан на ассемблере GNU, так что синтаксис AT&T-шный.
/*
Idioma
Copyright (C) 2001-2004 Sergey Gotsulyak
Stub.s
16&32-bit startup code
*/
.globl start
.text
.code16
start:
mov %cs,%ax
mov %ax,%ds
mov %ax,%es
mov %ax,%fs
mov %ax,%gs
// lss StackStart,%esp
// cld
mov $Green,%bl
mov $StubMessage,%si
call Print
/*
Set protected mode
*/
// Enable A20
mov $Green,%bl
mov $EnableA20Message,%si
call Print
mov $0x02,%al
out %al,$0x92
mov $Yellow,%bl
mov $OK,%si
call Print
// Disable interrupts
mov $Green,%bl
mov $DisableInterruptsMessage,%si
call Print
cli
mov $Yellow,%bl
mov $OK,%si
call Print
// Disable NMI
mov $Green,%bl
mov $DisableNMIMessage,%si
call Print
in $0x70,%al
or $0x80,%al
out %al,$0x70
mov $Yellow,%bl
mov $OK,%si
call Print
// Init PIC
mov $Green,%bl
mov $InitPICMessage,%si
call Print
mov $0x15,%al /* ICW1 */
out %al,$0x20
out %al,$0xA0
mov $0x20,%al /* ICW2 for first PIC */
out %al,$0x21
mov $0x28,%al /* ICW2 for second PIC */
out %al,$0xA1
mov $0x04,%al /* ICW3 for first PIC */
out %al,$0x21
mov $0x02,%al /* ICW 3 for second PIC */
out %al,$0xA1
mov $0x0D,%al /* ICW4 for first PIC */
out %al,$0x21
mov $0x09,%al /* ICW4 for second PIC */
out %al,$0xA1
mov $0xFC,%al /* enable timer & keyboard (master) */
out %al,$0x21
mov $0xFF,%al /* disable all (slave) */
out %al,$0xA1
mov $Yellow,%bl
mov $OK,%si
call Print
// Load gdtr&idtr
mov $Green,%bl
mov $LoadGDTRAndIDTRMessage,%si
call Print
lgdt GDTDescriptor
/* mov $DATA_SELECTOR,%ax
mov %ax,%ds
mov %ax,%es
mov %ax,%fs
mov %ax,%gs
mov %ax,%ss
*/
// lidt IDTDescriptor
mov $Yellow,%bl
mov $OK,%si
call Print
pushl $0x00000000
popfl
// Go to PM!!!
mov $Green,%bl
mov $GoToPMMessage,%si
call Print
// Compute offset for jump
/* xor %eax,%eax
mov %cs,%ax
shl $4,%eax
add $PMOffset,%eax
mov %eax,PMOffset
*/
mov %cr0,%eax
or $0x01,%al
mov %eax,%cr0
.code32
/* .byte 0xea
PMOffset: .long 0x00000000
.word 0x0008
*/
ljmp $0x0008,$2004
// Jump for init cs by code selector
2004:
mov $DATA_SELECTOR,%ax
mov %ax,%ds
mov %ax,%es
mov %ax,%fs
mov %ax,%gs
mov %ax,%ss
movb $0xB6,%al
outb %al,$0x43
movb $0x0D,%al
outb %al,$0x42
movb $0x11,%al
outb %al,$0x42
inb $0x61,%al
orb $3,%al
outb %al,$0x61
IL4: jmp IL4
movb $0xB6,%al
outb %al,$0x43
movb $0x0D,%al
outb %al,$0x42
movb $0x11,%al
outb %al,$0x42
inb $0x61,%al
orb $3,%al
outb %al,$0x61
// .byte 0xea
//PMOffset: .long 0x00000000
// .word CODE_SELECTOR
go32:
mov $0x000b8000,%edi
mov $OK32,%esi
mov $OK32Length,%ecx
rep movsb
IL: jmp IL
// Simulate main arguments then call main
push %eax
push %eax
push %eax
call _main
.code16
/*
Print string
si - offset of string
bl - char attributes
*/
Print:
xor %bh,%bh
mov $GetCursorPosition,%ah
int $0x10
mov $0x0001,%cx
PrintLoop:
lodsb
cmp $0x00,%al
je PrintReturn
cmp $0x0a,%al
je Inc
mov $PutChar,%ah
int $0x10
// Increment horizontal cursor position
inc %dl
cmp $80,%dl
jge Inc
mov $SetCursorPosition,%ah
int $0x10
jmp PrintLoop
Inc:
// Increment vertical cursor position
xor %dl,%dl
inc %dh
cmp $24,%dh
jge ScrollScreen
mov $SetCursorPosition,%ah
int $0x10
jmp PrintLoop
ScrollScreen:
// Scroll screen by teletype 0x0d-0x0a sequence
mov $0x0d,%al
mov $0x0e,%ah
int $0x10
mov $0x0a,%al
mov $0x0e,%ah
int $0x10
// Set new cursor coordinates
xor %dl,%dl
mov $24,%dh
mov $SetCursorPosition,%ah
int $0x10
jmp PrintLoop
PrintReturn:
ret
Beep:
movb $0xB6,%al
outb %al,$0x43
movb $0x0D,%al
outb %al,$0x42
movb $0x11,%al
outb %al,$0x42
inb $0x61,%al
orb $3,%al
outb %al,$0x61
ret
.code32
Print32:
mov $0x000B8000,%edi
mov $OK32Length,%ecx
rep movsb
ret
.data
KernelSegment=0x0200
KernelOffset=0x0000
GetCursorPosition=0x03
SetCursorPosition=0x02
PutChar=0x09
//BIOSInt=0x10
Red=0x8c
Green=0x8a
Yellow=0x8e
/*
.align 2
InerruptHandler:
pushl $InterruptMessage
call __Z5PrintPKc
iret
*/
//MaxTasks = 8
/*
.org 0x1000
_PageDirectory:
.org 0x2000
_PageTable:
*/
/*
Global descriptor table
*/
.ascii "!!!---!!!"
.align 4
.word 0
GDTDescriptor:
.word 4*8-1
.long _GDT
.align 4
_GDT:
.quad 0x0000000000000000 /* NULL descriptor */
.quad 0x00cf9a000000ffff /* 0x08 kernel 4Gb code at 0x00000000 */
.quad 0x00cf92000000ffff /* 0x10 kernel 4Gb data at 0x00000000 */
.quad 0x0000000000000000 /* Reserved */
// .quad 0x00cbfa00000007ff /* 0x23 user 8Mb code at 0x00000000 */
// .quad 0x00cbf200000007ff /* 0x2b user 8Mb data at 0x00000000 */
// .fill 252,8,0
CODE_SELECTOR = 0x0008
DATA_SELECTOR = 0x0010
/*
Interrupt descriptor table
*/
/* .align 4
.word 0
IDTDescriptor:
.word 256*8-1
.long _IDT
.align 4
_IDT:
.fill 256,8,0 */ /* IDT is uninitialized */
StubMessage: .string "\n\n[ Stub ]"
OK: .string "OK!"
EnableA20Message: .string "\nEnable A20: "
DisableInterruptsMessage: .string "\nDisable interrupts: "
DisableNMIMessage: .string "\nDisable NMI: "
InitPICMessage: .string "\nInit PIC: "
JumpInfiniteLoopMessage: .string "\nJump Infinite Loop..."
LoadGDTRAndIDTRMessage: .string "\nLoad GDTR and IDTR: "
GoToPMMessage: .string "\nGo to protected mode: "
InterruptMessage: .string "\nUnknown interrupt!"
OK32: .ascii "O"
.byte 0x8e
.ascii "K"
.byte 0x8e
.ascii "!"
.byte 0x8e
OK32Length=.-OK32
Цитата:
Originally posted by SerGo
Прощу помочь со следующим листингом - после перехода в PM (установки бита PE в CR0) он вылетает...
/* .byte 0xea
PMOffset: .long 0x00000000
.word 0x0008
*/
Прощу помочь со следующим листингом - после перехода в PM (установки бита PE в CR0) он вылетает...
/* .byte 0xea
PMOffset: .long 0x00000000
.word 0x0008
*/
Попробуй перед этим поставить байт 0x66, т.е. так:
юинеу 0x66
.byte 0xEA
PMOffset: .long 0x00000000
.word 0x0008
Цитата:
Originally posted by (C)dragon
Попробуй перед этим поставить байт 0x66, т.е. так:
юинеу 0x66
.byte 0xEA
PMOffset: .long 0x00000000
.word 0x0008
Попробуй перед этим поставить байт 0x66, т.е. так:
юинеу 0x66
.byte 0xEA
PMOffset: .long 0x00000000
.word 0x0008
Нет, дело точно не в этом.
После установки бита PE мы сразу переходим в 32-битный режим, а этот jump идет за директивой .code32, так что никаких префиксов изменения кода (0x66) не требуется.
Впрочем, я пробовал загружать в стек селектор и смещение для возврата из подпрограммы (якобы) и делал lret = retf с тем же печальным результатом.
Видимо, дело в абсолютном адресе размещения кода и в таблицах GDT...