Page 1 of 1
Creating Interrupts in a C kernel
Posted: Thu Jul 07, 2005 11:00 pm
by earlz
I can not figure out how to create an interrupt in C i have tried many different ways but keep getting trivial errors
here is my C code(turboC)
Code: Select all
void testi(void)
{
printf("hey whats up");
asm iret
}
asm itesti:
asm jmp _testi
asm ret
void int_init()
{
word tmp;
asm cli;
asm xor ax,ax
asm mov es,ax
asm mov bx,itesti
asm mov WORD [es:83*4], bx
asm mov WORD [es:83*4+2], CS
asm sti
}
i have heard not to have anything in C outside of a function(even inline) so how would u go about doing what im trying to do
btw yes i have a custom made printf function thats not based on the C library(so it would work in my os)
Re: Creating Interrupts in a C kernel
Posted: Thu Jul 07, 2005 11:00 pm
by ezanahka
@hckr83
Using software interrupts require (afaik but I might be wrong... obviously):
1) the entries of the loaded GDT must be suitable (assuming pmode... protection, etc. issues)
2) interrupt descriptor table set up
3) that the table is loaded into IDTR
4) the proper entries are filled in
5) the interrupt handler must use "iret" to return
6) the soft interrupt is initiated/called with asm "int 0x??"
So to invoke interrupt handler 0x53:
asm int 0x53
or
asm { int 0x53 }
or whatever...
Re: Creating Interrupts in a C kernel
Posted: Thu Jul 07, 2005 11:00 pm
by earlz
ok so how do i accomplish those
1-no im not in pmode
i do not need help calling an int
i need help initializingt the interrupt which is what that code does(or attempts to) but i am having problems
Re: Creating Interrupts in a C kernel
Posted: Fri Jul 08, 2005 11:00 pm
by ezanahka
This seems ok. You just put an "iret" before the "ret" created by the C compiler?
Code: Select all
void testi(void)
{
printf("hey whats up");
asm iret
}
What do you want to do with this? Is it necessary? I don't think that you will need this wrapper. Just reference "void test(void)" directly in the IDT entry.
Code: Select all
asm itesti:
asm jmp _testi
asm ret
This looks ok too... it should make a correct entry in the IDT.
However its always good to double check. I suggest that you print out the IDT entry you make here in hex and the address of the interrupt handler it should reference just in case before you try the interrupt call. If they match then everything is ok.
Code: Select all
void int_init()
{
word tmp;
asm cli;
asm xor ax,ax
asm mov es,ax
asm mov bx,itesti
asm mov WORD [es:83*4], bx
asm mov WORD [es:83*4+2], CS
asm sti
}
Do you use Bochs? If you do then you could just put the both values in registers, enter an infinite loop, stop Bochs and read the values from the output file instead of printing them out.
Re: Creating Interrupts in a C kernel
Posted: Fri Jul 08, 2005 11:00 pm
by earlz
well thats not the problem
the problem is this code is not even compiling
it is getting an asm level error with the asm mov bx,itesti
it just doesnt like using labels(tasm btw) and it compiled some way before but the interrupt didnt work(bochs didnt say the interrupt didnt exist it just didnt do anything)
and yes i do use bochs, how do u get it to output registers and such?
"This seems ok. You just put an "iret" before the "ret" created by the C compiler?"
its weird the compiler dont have a ret, such as this is the asm code of testi function
Code: Select all
_testi proc near
; ?debug L 184
; ?debug L 185
mov ax,offset DGROUP:s@
push ax
call near ptr _printf
pop cx
; ?debug L 186
iret
; ?debug L 187
@16:
; ?debug L 188
ret
_testi endp
; ?debug L 191
it dont make sense also why mov 0000:780,bx or something similar to that wont work in tasm yet works in a ton of other asm compilers(which is very annoying having to use workarounds)
Re: Creating Interrupts in a C kernel
Posted: Sat Jul 09, 2005 11:00 pm
by ezanahka
hckr83 wrote:
well thats not the problem
the problem is this code is not even compiling
it is getting an asm level error with the asm mov bx,itesti
it just doesnt like using labels(tasm btw) and it compiled some way before but the interrupt didnt work(bochs didnt say the interrupt didnt exist it just didnt do anything)
What exactly is the error you get?
And have you tried separating C/inline asm and pure asm into separate source files? I use inline asm in C source only when I can keep it really simple. I put all longer or more complicated assembly procedures into a separate .asm file and it works ok. Of course then I have to use extern/extrn and global/public keywords to declare the public interfaces for the object files so that the linker won't complain.
hckr83 wrote:
and yes i do use bochs, how do u get it to output registers and such?
When all goes well I just use a debugging function I've made to print out the number I need to check on the screen as a hex number in ascii when I'm running my kernel.
Code: Select all
/* put_char just writes a character on the screen
at the cursors current position and then advances */
void put_digit(ulong i) {
if (i>=10) put_char(i+65-10);
else put_char(i+48);
}
void put_int(ulong i) {
if (i>=10) put_int(i/10);
put_digit(i%10);
}
void put_hex_r(ulong i) {
if (i>=16) put_hex_r(i/16);
put_digit(i%16);
}
void put_hex(ulong i) {
put_char('0');
put_char('x');
put_hex_r(i);
}
Code: Select all
;; FASM syntax
;; its easier to play around with registers using asm
extrn put_hex ;; in case I haven't done this already
public dbg_foo
dbg_foo:
push ebx
call put_hex
ret
Code: Select all
/* actually printing the register from C */
extern void dbg_foo(void); /* the function prototype for C */
void main(void) {
...
dbg_foo();
...
}
When I run into trouble I just do something like this:
Code: Select all
mov edi, [variable_i_need_to_check]
jmp $
I stop Bochs when I know it has reached the loop and then just check the value in edi from the bochsout.txt
Re: Creating Interrupts in a C kernel
Posted: Sat Jul 09, 2005 11:00 pm
by earlz
ok so i want to compile 1 asm file in nasm or something like that then use turboc as the main thing
so how would i go about calling C functions or jumping from C functions to asm procs
using object files then linking them together
Re: Creating Interrupts in a C kernel
Posted: Sat Jul 09, 2005 11:00 pm
by ezanahka
You aren't going to use tasm for assembler?
You're using some version of Windows, right? I'm not that well acquinted with programming in a Windows environment. I think that we need to get some tasm/turboc expert in here.
You will probably need to make a .h file for C which contains external function prototypes for all of the asm procs you need to call from C. And then you must of course do the same thing for the assembler module i.e., define external names defined in the C code so that you can use them from asm. In the asm files you should also export the names your C code needs.
I don't know if and how borland's tools mangle symbol names for the linker but you can always do some kind of object file dump to find out the symbol names (if no dumping tools are available for extracting the symbol table then it might be possible to do it by hand... dunno).
The compiling and linking depends upon what kind of a binary you want to produce... do you use GRUB, do you have your own loader, etc...
Re: Creating Interrupts in a C kernel
Posted: Sat Jul 09, 2005 11:00 pm
by earlz
I have my own loader so i want to compile to straight binary or a .com file(.com=.bin)
Thanks a lot for the help
im going to try to mix them then read up on tlink and try to link them