Page 1 of 1
Syscall troubles
Posted: Wed Aug 26, 2009 3:56 am
by dak91
I implemented gdt idt isr and irq following Bran's tutorial (
http://www.osdever.net/bkerndev/), now, I've started a syscall interface.
This is my C syscall handler: (only a piece)
Code: Select all
void syscall_callback(regs_t *r)
{
printf("Syscall: %d -> ", r->eax);
if(r->eax == SYSCALL_FS_FOPEN) { ...
called from an assembler function:
Code: Select all
global syscallisr
extern syscall_callback
syscallisr:
call syscall_callback
iret
and the handler was added with this call:
Code: Select all
idt_set_gate(84, (unsigned)syscallisr, 0x08, 0x8E);
I wanted to try if syscalls correctly run. I only put 1 on eax, and call the interrupt of syscall:
Code: Select all
asm volatile("mov $1,%eax\n int $84\n");
but into the C syscall handler, (regs_t *)->eax doesn't have the value that I putted with mov, why? Sorry for my bad english xD
Re: Syscall troubles
Posted: Wed Aug 26, 2009 4:04 am
by pcmattman
dak91 wrote:
called from an assembler function:
Code: Select all
global syscallisr
extern syscall_callback
syscallisr:
call syscall_callback
iret
and the handler was added with this call:
Code: Select all
idt_set_gate(84, (unsigned)syscallisr, 0x08, 0x8E);
You may want to try pushing the general purpose registers and segments to actually build your stack frame before you call "syscall_callback". An interrupt like the one you're doing only pushes CS:EIP and the EFLAGS (and possibly SS:ESP, if a privilege level change occurs - see section 5.12.1, Volume 3A, of the Intel Manuals).
Re: Syscall troubles
Posted: Wed Aug 26, 2009 4:08 am
by Brendan
Hi,
Your "syscall_callback(regs_t *r)" function expects the real EAX (the first and only parameter) to be a pointer to a structure. I would assume that your ISR handler is meant to build this structure on the stack (e.g. by using PUSH and maybe PUSHA), then set EAX to the address of this structure before calling the C code. For the C code, "r->eax" would access the copy of EAX in this structure, that was saved on the stack by "syscallisr". I'd also assume that your ISR handler is meant to load values from the stack back into general registers before it returns (e.g. with POP and maybe POPA).
For example, if might go something like:
Code: Select all
syscallisr:
push ds
push es
pusha
mov eax,<kernel's_data_selector>
mov ds,eax
mov es,eax
mov eax,esp ;eax = pointer to the structure on the stack
call syscall_callback
popa
pop es
pop ds
iret
Of course what you put on the stack (and what order you do it) must match the fields in your "regs_t" structure, and must match what you take off of the stack before you IRET.
Cheers,
Brendan
Re: Syscall troubles
Posted: Wed Aug 26, 2009 4:29 am
by Velko
Your "syscall_callback(regs_t *r)" function expects the real EAX (the first and only parameter) to be a pointer to a structure.
Am I missing something? Shouldn't pointer to structure be pushed onto stack?
Re: Syscall troubles
Posted: Wed Aug 26, 2009 4:44 am
by Brendan
Hi,
Velko wrote:Your "syscall_callback(regs_t *r)" function expects the real EAX (the first and only parameter) to be a pointer to a structure.
Am I missing something? Shouldn't pointer to structure be pushed onto stack?
Ah - yes
I'm used to my own calling conventions (assembly language)...
Cheers,
Brendan