21
Lowlevel-Coding / Re: Ringwechsel und VM86
« am: 01. April 2009, 18:45 »
Das ist der Codeschnipsel aus Ausgabe 3 APM Powerdown.
27. September 2023, 23:51
Diese Sektion erlaubt es dir alle Beiträge dieses Mitglieds zu sehen. Beachte, dass du nur solche Beiträge sehen kannst, zu denen du auch Zugriffsrechte hast.
void out(unsigned short _port, unsigned char _data)
{
__asm__ ("out %%al, %%dx" : : "a" (_data), "d" (_port));
}
unsigned char in(unsigned short _port)
{
unsigned char result;
__asm__ ("in %%dx, %%al" : "=a" (result) : "d" (_port));
return result;
}
void outw(unsigned short _port, unsigned short _data)
{
__asm__ ("out %%ax, %%dx" : : "a" (_data), "d" (_port));
}
unsigned short inw(unsigned short _port)
{
unsigned short result;
__asm__ ("in %%dx, %%ax" : "=a" (result) : "d" (_port));
return result;
}
Oder es liegt an etwas anderen.
mov cs, wort ptr ds:[bx+0x1f14]
BIOS Befehl c086:0005 müsste beim Starten überall gleich sein.
mov cs, [ds + 0x1f14]
diesen Befehl gibt es wohl nur im RealMode. (er wird disassembelt, deswegen gibt es ihn wohl doch irgendwie)ctx->cs = ivt[ip[1] * 2 + 1];
ctx->eip = ivt[ip[1] * 2];
Auf was zeigt dieser Zeiger. Die Adresse aus der ivt muss doch auch auf den User-Stack, damit das ausgeführt werden kann. if (current->v86_if)
stack[2] |= EFLAG_IF;
else
stack[2] &= ~EFLAG_IF;
Ist beim Rinwechsel noch etwas wichtiges zu beachten?
_int53:
pop eax ;eip
pop eax ;cs
pop ebx ;eflags
or ebx, 0x20000
push 0
push 0
push 0
push 0
push 0x9000 ;ss
push 0
push ebx
push 0x8000 ;cs
push 0 ;ip
iret
Das geht nämlich nichtIch wollte das nur noch erwähnen wo das nicht geht. Xor ax,ax geht, aber int 10h halt nicht, was zum Absturz führt.
void f3(){while(1);}
Tasks.add(0x0 ,0xffffffff,(unsigned int) &t_f1,0,(unsigned int) f1,0, true);
Tasks.add(0x0 ,0xffffffff,(unsigned int) &t_f3,0,(unsigned int) f3,3, true);
unsigned short CTask::add(unsigned int base, unsigned int size, unsigned int tss_base , unsigned int page_base, unsigned int start,unsigned char privileg , bool update) //paging noch nicht enthalten
/// Code Segement
i = GDT->add(base,size,0x9A | ((privileg & 3) << 5),G); //G==3
p_tss->CS = (i << 3) | (privileg & 3);
/// Data Segement
i = GDT->add(base,size,0x92 | ((privileg & 3) << 5),G);
i = (i << 3) | (privileg & 3);
p_tss->DS = i;
p_tss->ES = i;
p_tss->FS = (privileg & 3);
p_tss->GS = (privileg & 3);
p_tss->EIP = start;
p_tss->EFLAGS = 0x90200;
p_tss->CR3 = page_base;
//noch schlecht
p_tss->ESP = 0x300000 + task_Eintraege * 0x10000;
p_tss->SS = i;//0x10;
a = (int*)f2- (int*)f1;
doch die Differenz ist viel zu hoch.typedef int (*(KeyDown_T)(char scan1, char scan2, unsigned char shift));
typedef int (*(KeyPress_T)(char Ascii));
typedef int (*(KeyUp_T)(char scan1, char scan2, unsigned char shift));
struct key_func
{
KeyDown_T Key_down;
KeyPress_T Key_press;
KeyUp_T Key_up;
unsigned char Activ;
} Key_Functionen;
void Add_Keydown(KeyDown_T Func)
{
Key_Functionen.Key_down = Func;
}
void Add_Keydown(KeyPress_T Func)
{
Key_Functionen.Key_press = Func;
}
void Add_Keydown(KeyUp_T Func)
{
Key_Functionen.Key_up = Func;
}
Und dann kommen diese Fehlermedungen heraus:driver.cpp:255: error: invalid use of member (did you forget the '&' ?)
driver.cpp: In function 'void Add_Keydown(int* (*)(char))':
driver.cpp:260: error: invalid use of member (did you forget the '&' ?)
driver.cpp: In function 'void Add_Keydown(int* (*)(char, char, unsigned char))':
driver.cpp:263: error: redefinition of 'void Add_Keydown(int* (*)(char, char, un
signed char))'
driver.cpp:253: error: 'void Add_Keydown(int* (*)(char, char, unsigned char))' p
reviously defined here
driver.cpp:265: error: invalid use of member (did you forget the '&' ?)
struct key_func
{
int (*(Key_down)(unsigned char scan1, unsigned char scan2, unsigned char shift));
int (*(Key_press)(unsigned char Ascii));
int (*(Key_up)(unsigned char scan1, unsigned char scan2, unsigned char shift));
unsigned char Activ;
}Key_Functionen;
Mit einer Add Funktion will ich jetzt der Struktur Funktionen zuweisen: void Add(int Type, void Func())
{
switch (Type)
{
case 1: //Key_down
Key_Functionen.Key_down = &Func;
break;
case 2: //Key_press
Key_Functionen.Key_press = &Func;
break;
case 3: //Key_up
Key_Functionen.Key_up = &Func;
break;
}
}
Hier weis ich nicht genau wie das geht.
IDT[x].offset_low
immer eine 1 hinein, wenn ich jetzt in der Main Funktion, für z.B. IDT[50] das eintrage funktioniert das für INT 50: int a;
char H[12];
IDT[50].offset_low = (((unsigned int) int50) & 0xffff);
a = IDT[50].offset_low;
Video.IntToStr(a,H);
Video.TextOut(H,10);
Ich hab auch überprüft, ob andere Funktion auf IDT zugreifen, was keine, außer die gewünschten, tut. (einmal Lokal IDT deklariert)call_protected: CS selector null
Ich kann mir denke was das bedeutet, aber nicht, wie das entsteht.irq:
mov al, 00010001b ;Das ICW in AL schreiben
out 0x20, al ;ICW an PIC1 senden
out 0xA0, al ;ICW an PIC2 senden
mov al, 0x20 ;AL auf 32 setzen
out 0x21, al ;ICW2 an ersten PIC senden
mov al, 0x28 ;AL auf 40 setzen
out 0xA1, al ;ICW2 an zweiten PIC senden
mov al, 00000100b ;Die IRQ2 Leitung auf 1 setzen
out 0x21, al ;An den Master-PIC senden
mov al, 2 ;Hier nun die NUMMER der IRQ-Leitung angeben
out 0xA1, al ;An den Slave-PIC senden
mov al, 00000001b ;Die Bits wie oben beschrieben setzen
out 0x21, al ;ICW4 an Master-PIC senden
out 0xA1, al ;ICW4 an Slave-PIC senden
retn
Und im C Kernel hab ich dazu folgenden Code:struct idt_daten{
unsigned short limit;
unsigned int base;
} __attribute__((packed));
struct idt_entry
{
unsigned short offset_low;
unsigned short selector;
unsigned char zero;
unsigned char access;
unsigned short offset_high;
} __attribute__((packed));
struct idt_entry IDT[256];
void setup_IDT()
{
unsigned char i;
make_IDT(i,(unsigned int) int0,8,0x8E);
make_IDT(i,(unsigned int) int1,8,0x8E);
…
make_IDT(i,(unsigned int) int50,8,0x8E);
for(i = 51; i < 256; i++)
{
make_IDT(i,(unsigned int) int00,8,0x8E);
}
}
void make_IDT(unsigned char n, unsigned int iBase, unsigned short shSelector, unsigned char cAccess)
{
IDT[n].offset_low = ((iBase) && 0xffff);
IDT[n].selector =shSelector;
IDT[n].zero =0;
IDT[n].access = cAccess;
IDT[n].offset_high = ((iBase >> 16) & 0xffff);
}
void LoadIDT()
{
struct idt_daten idt_ptr;
idt_ptr.limit = 256*8 - 1;
idt_ptr.base = (unsigned int)IDT;
//IDT laden
asm("lidt %0" : : "m" (idt_ptr));
}
Und eine Funktion im asm Teil._int50:
mov esi, 0xb8030
mov byte [esi], 'T'
mov byte [esi+1], 10
iret
setup_IDT();
LoadIDT();
asm("int $50");
Jedoch sehe ich kein Ergebnis auf den Bildschirm.