Page 1 of 2
Problem with a kernel call
Posted: Mon Dec 12, 2005 7:45 am
by Zioo
Hello again (:
The last few days have I written a few functions so I'm able to run flat binary programs. They are loaded into 0x1E00000 (30 MB) and it works fine. So now have I started writeing a set of include files with the normal functions like printf, scanf etc. (Isn't it called a SDK?) The functions call the kernel via an interrupt at 0x80. But i've problems with my puts() function. It looks like this.
Code: Select all
void puts(unsigned char *string)
{
asm("movl %0, %%ebx"::"r"(string)); // Move string into ebx
asm("movl $0x03, %eax"); // move function number into eax
asm("int $0x80"); // call the kernel
}
And in the kernel is the following code to print the text.
Code: Select all
void ServiceInt_puts() // Service Interrupt 03
{
unsigned char *string;
asm("movl %%ebx, %0":"=r"(string)); // move ebx into string
puts(string);
}
When I call this function from my program does I either get a Stack Fault or Invalid Opcode, But why?
I have putint, getchar, gets, cls, ect. functions which works fine. My assembly sucks so maybe there is a bug in there?
I'll appreciate any help
Re:Problem with a kernel call
Posted: Mon Dec 12, 2005 7:47 am
by Zioo
Oh, I forgot to say that I (normally) first get the Stack Fault or Invalid Opcode when I leave the program again
Re:Problem with a kernel call
Posted: Mon Dec 12, 2005 8:23 am
by Solar
Zioo wrote:
So now have I started writeing a set of include files with the normal functions like printf, scanf etc. (Isn't it called a SDK?)
No, it's called a C Library.
The functions call the kernel via an interrupt at 0x80. But i've problems with my puts() function. It looks like this.
0) I haven't checked the inline assembly syntax at all as I am not familiar enough with it yet.
1) I know nothing about your OS' memory layout. Does your kernel see the physical location of an application's string at the same virtual address as the application? (I.e., are you sure the mapping isn't affected by switching to kernel space?)
2) Unless you've been omitting some wrapper code, you are trying to do a C-style return from an interrupt handler, i.e. "ret" where you would need an "iret". See the FAQ for details.
3) I assume the puts() your kernel sees is not the same as the one your application sees?
4) You're jumping from an interrupt handler into an I/O function.
5) All this is stuff I've written in a minute without really thinking about it so please excuse if it's complete BS.
Re:Problem with a kernel call
Posted: Mon Dec 12, 2005 9:20 am
by Zioo
To Solars answer..
1) Haven't check that, but i don't think it's the problem.
2) I'm using iret
3) About this i figured of something strange.. if I first run gets() (scanf) and save this input in a char* and then print the char* works puts() without errors.. Se the code below.
But if I just run "puts("Yet Another Test");" does it all goes wrong. I've also tried to save the text in a char and then print the char like below, but that does also not work.
Code: Select all
char *d = "Yet Another Test";
puts(d);
So it looks like the errors happen when I tries to use a string in the source. This make me thing that there maybe is a bug in by linker script.. ???
Re:Problem with a kernel call
Posted: Mon Dec 12, 2005 9:31 am
by Solar
Ngngngng... we should award that one a price for the most-frequent bug of the forum.
Make sure you're linking *.rodata, as that is where strings are kept.
Re:Problem with a kernel call
Posted: Mon Dec 12, 2005 9:34 am
by Candy
I can't help but think of rodata again...
Re:Problem with a kernel call
Posted: Mon Dec 12, 2005 10:08 am
by Zioo
I've rodata in my linker script.
Code: Select all
INPUT("cls.o")
INPUT("libk\libk.a")
OUTPUT_FORMAT("binary")
ENTRY(main)
phys = 0x1E00000;
SECTIONS
{
.text phys : AT(phys) {
code = .;
*(.text)
*(.rodata*)
. = ALIGN(0);
}
.data : AT(phys + (data - code))
{
data = .;
*(.data)
. = ALIGN(0);
}
.bss : AT(phys + (bss - code))
{
bss = .;
*(.bss)
. = ALIGN(0);
}
end = .;
}
Shouldn't it be correct?
Re:Problem with a kernel call
Posted: Mon Dec 12, 2005 2:56 pm
by Kemp
It can also be called .rdata depending on what you're using.
Re:Problem with a kernel call
Posted: Tue Dec 13, 2005 12:30 am
by Zioo
It can also be called .rdata depending on what you're using.
Doesn't work
If I have
In another file and link the main file up against this file can I print char *test without problems. I can also not use functions defined in the main file. I looks like everything has to be in an extern file and then linked togehter. :-\
Re:Problem with a kernel call
Posted: Tue Dec 13, 2005 12:42 am
by Zioo
All right
This works.
This doesn't work.
Re:Problem with a kernel call
Posted: Tue Dec 13, 2005 1:48 am
by Solar
Hmm... this is strange... ???
Re:Problem with a kernel call
Posted: Tue Dec 13, 2005 2:24 am
by Candy
Solar wrote:
Hmm... this is strange... ???
Not quite as much as I'd expect.
when placed in a function is compiled to code that puts that on the stack, and then a call is made.
is compiled into a string constant in rodata (or rdata or whatever) that's then referred to.
At least, that's what I expect. Could you give us an objdump of the executable?
Re:Problem with a kernel call
Posted: Tue Dec 13, 2005 2:26 am
by Ytinasni
I'd suggest doing an objdump -h on your kernel, and looking for sections that your linker script doesnt include.
You'll need to change output format temporarily to something objdumpable, elf or pe are likely choices
notably, look for:
- .idata
- .gnu.linkonce.<t,r, or d>.*
Re:Problem with a kernel call
Posted: Tue Dec 13, 2005 2:35 am
by Candy
I would vote for an
which would also show what it actually ended up in, and what references were still in the executable (iow, did the linker think it did a good job).
Re:Problem with a kernel call
Posted: Tue Dec 13, 2005 6:10 am
by Solar
Candy wrote:
when placed in a function is compiled to code that puts that on the stack, and then a call is made.
is compiled into a string constant in rodata (or rdata or whatever) that's then referred to.
You never stop learning.