Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: nico am 09. June 2008, 14:28
-
Hi,
da es sich um ein anderes problem handelt, als im vorherigen thread, mache ich mal einen neuen auf. ich habe folgendes problem (bestimmt aufgrund von einigen missverständnissen beim multitasking). aber vllt erstmal der code:
gdt.asm:
%define USER_CODE_SEL 0x0B
%define USER_DATA_SEL 0x13
%define KERN_CODE_SEL 0x18
%define KERN_DATA_SEL 0x20
[extern tss]
[section .text]
setup_gdt:
pusha
mov eax,tss
mov [sys_tss+2],ax
shr eax,16
mov [sys_tss+4],al
mov [sys_tss+7],ah
; load gdt_ptr into gdt register
lgdt [gdt_ptr]
; update segment registers
mov ax,KERN_DATA_SEL
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
; far jump to update code segment
jmp KERN_CODE_SEL:.return
.return:
popa
ret
[section .data]
gdt_ptr:
.limit dw gdt_end-gdt-1
.base dd gdt
gdt:
; gdt null descriptor
null_desc dw 0x0000,0x0000,0x0000,0x0000
; user code descriptor, ring 0
user_code dw 0xFFFF,0x0000,0xFA00,0x00CF
; user data descriptor, ring 0
user_data dw 0xFFFF,0x0000,0xF200,0x00CF
; kernel code descriptor, ring 3
kern_code dw 0xFFFF,0x0000,0x9A00,0x00CF
; kernel data descriptor, ring 3, sel 0x20
kern_data dw 0xFFFF,0x0000,0x9200,0x00CF
; sys_tss
sys_tss dw 0x0067,0x0000,0x8900,0x0000
gdt_end:
boot.asm
[section .text]
mboot:
align 4
dd MBOOT_MAGIC
dd MBOOT_FLAGS
dd MBOOT_CKSUM
[global start]
start:
cli
; stack
mov esp,stack_end
; clear the screen
call screen_clear
call setup_gdt ; gdt
call setup_idt ; idt
mov [tss.esp0],dword esp
mov [tss.esp],dword task_stack_start
mov [tss.eip],dword foo
mov ax,0x28
ltr ax
jmp 0x28:0 ; ???
foo:
mov esi,bar
call screen_puts
mov ecx,0xFFFFFF
loop $
jmp foo
.nothing:
jmp .nothing
[section .data]
bar: db 'bar...',0x0A,0x0
[global tss]
tss:
.link dd 0
.esp0 dd 0
.ss0 dw KERN_DATA_SEL,0
.esp1 dd 0
.ss1 dd 0
.esp2 dd 0
.ss2 dd 0
.cr3 dd 0
.eip dd 0
.eflags dd 0
.eax dd 0
.ecx dd 0
.edx dd 0
.ebx dd 0
.esp dd 0
.ebp dd 0
.esi dd 0
.edi dd 0
.es dd 0
.cs dd 0
.ss dw USER_DATA_SEL,0
.ds dd 0
.fs dd 0
.gs dd 0
.ldt dd 0
.map dd 0
tss_end:
[section .bss]
task_stack_start: resb STACK_SIZE
tast_stack_end:
stack_start: resb STACK_SIZE
stack_end:
das ziel ist folgendes: ich möchte gerne einen ring0 task starten der einfach nur eine testzeichenkette ausgiebt. noch etwas unklar ist mir wie ich eigendlich zu diesen task springe. in der intel doku steht, dass ein einfacher jump ausreicht. ich habe in einigen referenzimplementationen gesehen, dass ein far jump zum TASK_SELECTOR:0 ausgeführt wird. reicht das aus? denn wenn ich das so machen, wie oben (siehe: ???) bekomme ich eine gp-exception und bochs endet mit "jump_protected: gate type 11 unsupported".
sieht vllt jemand den fehler?
besten dank im voraus,
bg nico
-
Nun ja, wenn ich mich nicht irre, sind die Makros mit den Selektoren falsch.
Du verwendest folgende reihenfolge:
# NULL Deskriptor
# User Code
# User Data
# Kernel Code
# Kernel Data
Den Selektor errechnet man, indem man die Nummer des aktuellen Eintrags -1 mit 0x8 berechnet, z.B.: (4-1)*0x8.
Das - 1 deswegen, weil der NULL Deskriptor nicht mitgezählt wird.
In deinem Fall wäre dass dan wie folgt:
# NULL Deskriptor 0x00
# User Code 0x08
# User Data 0x10
# Kernel Code 0x18
# Kernel Data 0x20
Das denke ich mal ist der Fehler. Es kann allerdings auch sein, dass ich mich irre...
Gruß Christian
-
naja nach intel doku, sind die ersten 2 bits eines segment selectors RPL und das 3. bit der table indicator (GDT=0,LDT=1). also müssten die selectoren passen, wenn man man für user_* noch bit 0&1 setzt.
-
Ok, ich denke was passiert ist folgendes: Wenn du den momentanen TSS-Deskriptor lädst (über ltr) dann wird das Busy-Bit (Byte 5, Bit 2, vgl. 6.2.2 Intel Manuals) gesetzt, um anzuzeigen, dass das TSS momentan benutzt wird. Wenn du nun zu dem gleichen TSS springst, stellt die CPU fest, dass es sich dabei um ein TSS handelt welches bereits in Gebrauch ist und wirft dir ne Exception. Die Bochs Fehlermeldung kommt denke ich mal daher, dass das Typfeld des TSS-Deskriptor (Byte 5, Bits 0-3) nicht mehr 9 sondern 11 ist und bochs dann halt nicht kapiert dass es sich um einen Sprung in ein TSS handelt.
Lösung: Zwei TSS(-Deskriptoren), den einen laden und zum anderen springen.