Autor Thema: Multitasking #2  (Gelesen 5035 mal)

nico

  • Beiträge: 16
    • Profil anzeigen
Gespeichert
« 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

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #1 am: 09. June 2008, 15:33 »
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

nico

  • Beiträge: 16
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 09. June 2008, 16:45 »
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.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #3 am: 09. June 2008, 17:08 »
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.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

 

Einloggen