how to do ring0 -> ring3 -> ring0?
how to do ring0 -> ring3 -> ring0?
HI, I want to experience ring0 -> ring3 -> ring0
ring3 routine only display a character to show it ever runned.
Is there any basic skeleton code I can reference?
Thanks
Mulder
ring3 routine only display a character to show it ever runned.
Is there any basic skeleton code I can reference?
Thanks
Mulder
This is how I do it now (NOTE, I've only currently made this, maybe it's not the best way)
Your c implementation here
The code in userland
C prototype to the above asm
and you must install the _syscall_int isr in interrupt table at index 0x80 (that's arbitrary) as a trap gate (I'm not sure if it has to be a trap gate, and what would happen if it's not)
--
Sigurd Lerstad
Code: Select all
syscall_table:
dd 0
dd stream_read2
dd stream_write2
etc ...
dd 0
;
extern _stream_write
stream_write2:
mov eax,dword [esp + 16] ; user stack pointer
push dword[eax+12] ; len
push dword[eax+8] ; pv
push dword[eax+4] ; handle
call _stream_write
add esp,12
ret
;
global _syscall_int
_syscall_int:
call dword[syscall_table + eax*4]
iret
;
Code: Select all
int stream_write(int handle, const void* pv, int len)
{
...
}
Code: Select all
_write:
mov eax,2
int 0x80
ret
;
Code: Select all
int write(int handle, const void* pv, int len);
and you must install the _syscall_int isr in interrupt table at index 0x80 (that's arbitrary) as a trap gate (I'm not sure if it has to be a trap gate, and what would happen if it's not)
--
Sigurd Lerstad
HI, I use DEX's PM10.asm to test.
But i got bochs error:
00014827389e[CPU0 ] check_cs: non-conforming code seg descriptor dpl != cpl
00014829624p[CPU0 ] >>PANIC<< fetch_raw_descriptor: LDTR.valid=0
00014829624i[CPU0 ] protected mode
00014829624i[CPU0 ] CS.d_b = 32 bit
00014829624i[CPU0 ] SS.d_b = 32 bit
00014829624i[CPU0 ] EFER = 0x00000000
00014829624i[CPU0 ] | RAX=0000000000000000 RBX=0000000000000000
00014829624i[CPU0 ] | RCX=0000000000000000 RDX=0000000000000000
00014829624i[CPU0 ] | RSP=000000000000867d RBP=0000000000000000
00014829624i[CPU0 ] | RSI=0000000000000000 RDI=0000000000000000
00014829624i[CPU0 ] | R8=0000000000000000 R9=0000000000000000
00014829624i[CPU0 ] | R10=0000000000000000 R11=0000000000000000
00014829624i[CPU0 ] | R12=0000000000000000 R13=0000000000000000
00014829624i[CPU0 ] | R14=0000000000000000 R15=0000000000000000
00014829624i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt of df if tf sf zf af pf cf
00014829624i[CPU0 ] | SEG selector base limit G D
00014829624i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00014829624i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 000fffff 1 1
00014829624i[CPU0 ] | DS:0020( 0004| 0| 0) 00000000 000fffff 1 1
00014829624i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00014829624i[CPU0 ] | ES:0020( 0004| 0| 0) 00000000 000fffff 1 1
00014829624i[CPU0 ] | FS:0020( 0004| 0| 0) 00000000 000fffff 1 1
00014829624i[CPU0 ] | GS:0020( 0004| 0| 0) 00000000 000fffff 1 1
00014829624i[CPU0 ] | MSR_FS_BASE:0000000000000000
00014829624i[CPU0 ] | MSR_GS_BASE:0000000000000000
00014829624i[CPU0 ] | RIP=0000000000008084 (0000000000008083)
00014829624i[CPU0 ] | CR0=0x00000011 CR1=0x0 CR2=0x0000000000000000
00014829624i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00014829624i[CPU0 ] >> iretd : CF
/************/
here is my code:
mov [ss0],word ss
mov [esp0],dword esp
mov esp,TaskAStack
popad
pop ds
pop es
pop fs
pop gs
iret
TaskACode: mov [0xB8000],byte '0'
mov [0XB8000+1],byte 7
jmp $
stackA dd 0
TaskAStack: ; regs popped by popa (ESP is popped and discarded)
dd 0, 0, 0, 0, 0, 0, 0, 0 ; EDI, ESI, EBP, EBX, EDX, ECX, EDX
; regs popped by pop ds, etc.
dw 0x20, 0 ; DS
dw 0x20, 0 ; ES
dw 0x20, 0 ; FS
dw 0x20, 0 ; GS
; regs popped by iret
dd TaskACode ; EIP
dw 0x18, 0 ; CS
dd 0x200 ; EFLAGS (0x200 enables ints)
dd stackA ; ESP
dw 0x20, 0 ; SS
GDT: dw 6*8-1
dd .base
.base: dd 0x00000000,, dd 0x00000000
dd 0x0000FFFF,, dd 0x00CF9A00 ;kernel code
dd 0x0000FFFF,, dd 0x00CF9200 ;kernel data
dd 0x0000FFFF,, dd 0x00CFFA00 ;user code
dd 0x0000FFFF,, dd 0x00CFF200 ;user data
dd 0x8500FFFF,, dd 0x008FE900 ;dummytss
; TSS is located in 0x8500, I pad some bytes to make it align
TSS: dd 0 ;previous task linkage
esp0 dd 0 ;esp0
ss0 dd 0 ;ss0
dd 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
dd 0 ;ds
dd 0 ;fs
dd 0 ;gs
dd 0 ;ldt segment selector
dd 0x0 ;io map base address
But i got bochs error:
00014827389e[CPU0 ] check_cs: non-conforming code seg descriptor dpl != cpl
00014829624p[CPU0 ] >>PANIC<< fetch_raw_descriptor: LDTR.valid=0
00014829624i[CPU0 ] protected mode
00014829624i[CPU0 ] CS.d_b = 32 bit
00014829624i[CPU0 ] SS.d_b = 32 bit
00014829624i[CPU0 ] EFER = 0x00000000
00014829624i[CPU0 ] | RAX=0000000000000000 RBX=0000000000000000
00014829624i[CPU0 ] | RCX=0000000000000000 RDX=0000000000000000
00014829624i[CPU0 ] | RSP=000000000000867d RBP=0000000000000000
00014829624i[CPU0 ] | RSI=0000000000000000 RDI=0000000000000000
00014829624i[CPU0 ] | R8=0000000000000000 R9=0000000000000000
00014829624i[CPU0 ] | R10=0000000000000000 R11=0000000000000000
00014829624i[CPU0 ] | R12=0000000000000000 R13=0000000000000000
00014829624i[CPU0 ] | R14=0000000000000000 R15=0000000000000000
00014829624i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt of df if tf sf zf af pf cf
00014829624i[CPU0 ] | SEG selector base limit G D
00014829624i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00014829624i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 000fffff 1 1
00014829624i[CPU0 ] | DS:0020( 0004| 0| 0) 00000000 000fffff 1 1
00014829624i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00014829624i[CPU0 ] | ES:0020( 0004| 0| 0) 00000000 000fffff 1 1
00014829624i[CPU0 ] | FS:0020( 0004| 0| 0) 00000000 000fffff 1 1
00014829624i[CPU0 ] | GS:0020( 0004| 0| 0) 00000000 000fffff 1 1
00014829624i[CPU0 ] | MSR_FS_BASE:0000000000000000
00014829624i[CPU0 ] | MSR_GS_BASE:0000000000000000
00014829624i[CPU0 ] | RIP=0000000000008084 (0000000000008083)
00014829624i[CPU0 ] | CR0=0x00000011 CR1=0x0 CR2=0x0000000000000000
00014829624i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00014829624i[CPU0 ] >> iretd : CF
/************/
here is my code:
mov [ss0],word ss
mov [esp0],dword esp
mov esp,TaskAStack
popad
pop ds
pop es
pop fs
pop gs
iret
TaskACode: mov [0xB8000],byte '0'
mov [0XB8000+1],byte 7
jmp $
stackA dd 0
TaskAStack: ; regs popped by popa (ESP is popped and discarded)
dd 0, 0, 0, 0, 0, 0, 0, 0 ; EDI, ESI, EBP, EBX, EDX, ECX, EDX
; regs popped by pop ds, etc.
dw 0x20, 0 ; DS
dw 0x20, 0 ; ES
dw 0x20, 0 ; FS
dw 0x20, 0 ; GS
; regs popped by iret
dd TaskACode ; EIP
dw 0x18, 0 ; CS
dd 0x200 ; EFLAGS (0x200 enables ints)
dd stackA ; ESP
dw 0x20, 0 ; SS
GDT: dw 6*8-1
dd .base
.base: dd 0x00000000,, dd 0x00000000
dd 0x0000FFFF,, dd 0x00CF9A00 ;kernel code
dd 0x0000FFFF,, dd 0x00CF9200 ;kernel data
dd 0x0000FFFF,, dd 0x00CFFA00 ;user code
dd 0x0000FFFF,, dd 0x00CFF200 ;user data
dd 0x8500FFFF,, dd 0x008FE900 ;dummytss
; TSS is located in 0x8500, I pad some bytes to make it align
TSS: dd 0 ;previous task linkage
esp0 dd 0 ;esp0
ss0 dd 0 ;ss0
dd 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
dd 0 ;ds
dd 0 ;fs
dd 0 ;gs
dd 0 ;ldt segment selector
dd 0x0 ;io map base address
It works fine with interrupt disable. It jumps to ring3. When I try to enable timer irq, I got error
TaskAStack:dd 0,0,0,0, 0,0,0,0 ; EDI, ESI, EBP, ESP, EBX, EDX, ECX, EAX
dd 0x20+3 ; DS
dd 0x20+3 ; ES
dd 0x20+3 ; FS
dd 0x20+3 ; GS
; regs popped by iret
dd TaskACode ; EIP
dd 0x18+3 ; CS
dd 0x200 ; EFLAGS (0x200 enables ints)
dd 0 ; ESP
dd 0x20+3 ; SS
InterruptHandler_20: pushad
push gs
push fs
push es
push ds
; add dword [Counter],0x1
mov al,EOI
out PIC8259A_Port_Command,al
pop ds
pop es
pop fs
pop gs
popad
iret
TaskAStack:dd 0,0,0,0, 0,0,0,0 ; EDI, ESI, EBP, ESP, EBX, EDX, ECX, EAX
dd 0x20+3 ; DS
dd 0x20+3 ; ES
dd 0x20+3 ; FS
dd 0x20+3 ; GS
; regs popped by iret
dd TaskACode ; EIP
dd 0x18+3 ; CS
dd 0x200 ; EFLAGS (0x200 enables ints)
dd 0 ; ESP
dd 0x20+3 ; SS
InterruptHandler_20: pushad
push gs
push fs
push es
push ds
; add dword [Counter],0x1
mov al,EOI
out PIC8259A_Port_Command,al
pop ds
pop es
pop fs
pop gs
popad
iret
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Two things:
1) will you please give a proper description of the error (like, how to ask questions)
2) You do not show any sign of having debugged or researched the problem yourself. At the very least, read the wiki entry on interrupts
1) will you please give a proper description of the error (like, how to ask questions)
2) You do not show any sign of having debugged or researched the problem yourself. At the very least, read the wiki entry on interrupts
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
If things are not working in bochs then it is a strong hint that it won't on real hardware either.Dex wrote:I have some one on my forum, who uses this code and i asked him if he has any problems on enabling interrupts, He say it works fine in qemu and real PC, so may be it a problem with BOCHS.
Have you tryed it in real PC or another emulator ?.
That how it should be, But anyone who has use both real and emulators, knows this is not the case. Most coders need to mod there code just to get round some of these problems, with these emulators.Combuster wrote:If things are not working in bochs then it is a strong hint that it won't on real hardware either.Dex wrote:I have some one on my forum, who uses this code and i asked him if he has any problems on enabling interrupts, He say it works fine in qemu and real PC, so may be it a problem with BOCHS.
Have you tryed it in real PC or another emulator ?.
There also lots of examples where it will run fine in one emulator, but not in another.
Your best bet is to test on as many real PC as possible.
I tried it on my real machine, bochs, qemu. real machine got reset, bochs got ">>PANIC<< fetch_raw_descriptor: LDTR.valid=0", qemu got hang.
But all of them seem enter ring3, I can see the flashing byte on screen.
/**************/
sti
mov al,11111011b
out PIC8259A_Port_Data,al ;OCW for master
mov al,00111111b
out PIC8259B_Port_Data,al ;OCW for slave
mov [ss0],word ss
mov [esp0],dword esp
mov esp,TaskAStack
popad
pop ds
pop es
pop fs
pop gs
iret
do I need initialize the LDTR ?
But all of them seem enter ring3, I can see the flashing byte on screen.
/**************/
sti
mov al,11111011b
out PIC8259A_Port_Data,al ;OCW for master
mov al,00111111b
out PIC8259B_Port_Data,al ;OCW for slave
mov [ss0],word ss
mov [esp0],dword esp
mov esp,TaskAStack
popad
pop ds
pop es
pop fs
pop gs
iret
do I need initialize the LDTR ?