Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Внимание - защищенный режим

491
11 января 2004 года
SerGo
30 / / 20.12.1999
Прощу помочь со следующим листингом - после перехода в PM (установки бита PE в CR0) он вылетает...

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
424
13 января 2004 года
(C)dragon
307 / / 04.12.2002
Цитата:
Originally posted by SerGo
Прощу помочь со следующим листингом - после перехода в PM (установки бита PE в CR0) он вылетает...

/* .byte 0xea
PMOffset: .long 0x00000000
.word 0x0008
*/



Попробуй перед этим поставить байт 0x66, т.е. так:

юинеу 0x66
.byte 0xEA
PMOffset: .long 0x00000000
.word 0x0008

491
15 января 2004 года
SerGo
30 / / 20.12.1999
Цитата:
Originally posted by (C)dragon


Попробуй перед этим поставить байт 0x66, т.е. так:

юинеу 0x66
.byte 0xEA
PMOffset: .long 0x00000000
.word 0x0008



Нет, дело точно не в этом.

После установки бита PE мы сразу переходим в 32-битный режим, а этот jump идет за директивой .code32, так что никаких префиксов изменения кода (0x66) не требуется.

Впрочем, я пробовал загружать в стек селектор и смещение для возврата из подпрограммы (якобы) и делал lret = retf с тем же печальным результатом.

Видимо, дело в абсолютном адресе размещения кода и в таблицах GDT...

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог