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