Page 1 of 1

Compile problems... ---> GCC

Posted: Fri Aug 23, 2002 4:03 pm
by Warmaster199
Hello, I am creating an operating system (kernel for now) and when I compile, I get some "conflicting types for built-in function 'memset' " error. I know for a fact that the memset function is correct.

Code: Select all

extern inline void * memset(void * s,char c,unsigned int count)
{
__asm__("cld\n\t"
   "rep\n\t"
   "stosb"
   : /* no output */
   :"a" (c),"D" (s),"c" (count)
   :"cx","di","memory");
return s;
}
Several other assembler-embedded C functions such as strncmp have the same error. With no compile flags, I get "undefined SIREG and CREG while reloading asm". So far, these errors have only occured beyond the last : in the assembler code blocks.

Is there some other flags I should pass to GCC? Is there something wrong with GCC? Or should I drop those functions in favour of C equivalents?

In the make file:

Code: Select all

GCC=gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -I../include
7

Re:Compile problems... ---> GCC

Posted: Mon Aug 26, 2002 3:36 am
by Pype.Clicker
hmmm ... maybe you could try "static inline" rather than "extern inline" ?

For the memset function, it's prototype (known by default by the compiler as it's a function it sometimes uses on its own for making large structure ready if you allocate them on the stack ;) is

void* memset (void* , int , size_t )
and not
void* memset(void *, char, unsigned_int).

so, just convert your char argument into a int argument and the rest should be fine .

Re:Compile problems... ---> GCC

Posted: Mon Aug 26, 2002 3:38 am
by Pype.Clicker
Warmaster199 wrote: H

Code: Select all

extern inline void * memset(void * s,char c,unsigned int count)
{
__asm__("cld\n\t"
   "rep\n\t"
   "stosb"
   : /* no output */
   :"a" (c),"D" (s),"c" (count)
   :"cx","di","memory");
return s;
}
The "cx" "di" and "memory" aren't correct imho, either you should use "c" and "D", or i should read the GCC inlining manual once again ...

Re:Compile problems... ---> GCC

Posted: Mon Aug 26, 2002 11:01 pm
by Warmaster199
Thanks for the response, but I decided to redo them in C. Thanks to that decision, My kernel is bootable! I have implemented an interrupt handler, but when I want to display all the registers, I generate a "GENERAL PROTECTION FAULT". After about 5 seconds (When my timer interrupt fires to display a message), the screen is flooded with "INVALID OPCODE EXCEPTION". I think that I should add __asm__("iret\n\t"); to the end of each exception function, but I tried it and then the screen immediately gets flooded as soon as the display_regs is called. It's very ugly, but I am happy that I at least got this far...
Thanks for any responses.

Re:Compile problems... ---> GCC

Posted: Tue Aug 27, 2002 6:15 am
by Pype.Clicker
the easiest way to handle exceptions is to write a small stub-code in ASM that will call your real (C) exception handler.

ex:

gpf_stub:
pusha
push ds
mov ds,OS_DATA_SELECTOR
mov ebp,esp
push ebp
call gpf_handler
mov esp, ebp
pop ds
popa
iretd

void gpf_handler(dword* registers) {
// do anything you want. registers is a pointer to the
// location of the backup-values of the registers on the stack
return;
}

Re:Compile problems... ---> GCC

Posted: Tue Aug 27, 2002 12:43 pm
by Warmaster199
OK, but I am still generating my General Protection Fault.

Here is my IRQ handler code:

Code: Select all


;-----Assembler doesn't like it when macro args are
; pushed onto stack... So, a PUSHMacro was made-----
macro PUSHM 1
   db 6Ah
   db %1

;-----Saves all, calls do_IRQ(int, pt_regs*);
; Argument is 1 -----
macro BUILD_IRQ 1
   push gs      
   push fs      
   push es      
   push ds
   push ss
   pusha      
   mov eax, KERNEL_DS   
   mov ds,eax      
   mov es,eax      
   mov fs,eax      
   mov gs,eax
   sti
   mov ebp,esp      
   push ebp
   PUSHM %1   ; push macro
   call _do_IRQ
   mov esp, ebp
   cli
   popa
   pop ss
   pop ds      
   pop es
   pop fs
   pop gs
   iret

void do_IRQ(int irq, struct pt_regs * regs)
{
/* The sigaction structure from LINUX */
    struct sigaction * sa;
    sa = irq + irq_sigaction;
    sa->sa_handler(regs);
}

void timer(struct pt_regs *regs);
void key(struct pt_regs *regs);
timer increments int timer; if timer = 91(5 seconds), reset it and display "[t]"

key gets input from keyboard. When you press 'r', it will display all the registers in pt_regs. pt_regs contains eax, ebx, ebp, etc... as well as ds-gs.

Whenever regs is accessed inside void key(regs), it generates a GPF...

What am I doing wrong??? I have absolutely no clue what is wrong, yet it generates GPF. When the timer fires then it blows up...

Re:Compile problems... ---> GCC

Posted: Tue Aug 27, 2002 4:21 pm
by df
to answer your first question, you need to add -fno-builtin which disables GCCs built in functions for memcpy, and others it has, which will replace yours.

Re:Compile problems... ---> GCC

Posted: Tue Aug 27, 2002 5:33 pm
by Warmaster199
Sweetness... That got rid of almost all of the warnings I previously had... thanks!

Re:Compile problems... ---> GCC

Posted: Wed Aug 28, 2002 8:21 am
by Pype.Clicker
Warmaster199 wrote: OK, but I am still generating my General Protection Fault.

timer increments int timer; if timer = 91(5 seconds), reset it and display "[t]"

key gets input from keyboard. When you press 'r', it will display all the registers in pt_regs. pt_regs contains eax, ebx, ebp, etc... as well as ds-gs.

Whenever regs is accessed inside void key(regs), it generates a GPF...

What am I doing wrong??? I have absolutely no clue what is wrong, yet it generates GPF. When the timer fires then it blows up...
Just a question, do you have ss==ds or ss!=ds. If ss and ds aren't identical, then an offset from the stack (i.e. ebp) cannot be reused as a pointer in your code (for instance, the stack exp-down is 0xfffffffc -> 0xc00000 while your data section is 0x0000000 -> 0x8000000, thus trying to access ebp=0xffff.ff80 from ds results in a segfault ...)

Re:Compile problems... ---> GCC

Posted: Wed Aug 28, 2002 9:23 am
by Warmaster199
I had used eax before, but then I changed it to ebp, listening to the code you posted above... but it does the EXACT same thing. I load all the segments with KERNEL_DS in my bootcode, so that means DS==SS. I am thinking that I should make the kernel reset the stack in it's initialization routine. I'm going to test that now. BTW: I added a set_systimer(int hz) function to set the speed the timer makes an interrupt :)