Problem with a kernel call

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Zioo

Problem with a kernel call

Post 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 :)
Zioo

Re:Problem with a kernel call

Post by Zioo »

Oh, I forgot to say that I (normally) first get the Stack Fault or Invalid Opcode when I leave the program again :)
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Problem with a kernel call

Post 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. ;-)
Every good solution is obvious once you've found it.
Zioo

Re:Problem with a kernel call

Post 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.

Code: Select all

char *s =d 0;
gets(s);
puts(s);
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.. ???
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Problem with a kernel call

Post by Solar »

Ngngngng... we should award that one a price for the most-frequent bug of the forum. :P :D

Make sure you're linking *.rodata, as that is where strings are kept.
Every good solution is obvious once you've found it.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Problem with a kernel call

Post by Candy »

I can't help but think of rodata again...
Zioo

Re:Problem with a kernel call

Post 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?
Kemp

Re:Problem with a kernel call

Post by Kemp »

It can also be called .rdata depending on what you're using.
Zioo

Re:Problem with a kernel call

Post by Zioo »

It can also be called .rdata depending on what you're using.
Doesn't work :(


If I have

Code: Select all

char test*  = "test..";
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. :-\
Zioo

Re:Problem with a kernel call

Post by Zioo »

All right

Code: Select all

char test[9] = "test..";
This works.

Code: Select all

char *test  = "test..";
This doesn't work.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Problem with a kernel call

Post by Solar »

Hmm... this is strange... ???
Every good solution is obvious once you've found it.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Problem with a kernel call

Post by Candy »

Solar wrote: Hmm... this is strange... ???
Not quite as much as I'd expect.

Code: Select all

char test[9] = "test..";
when placed in a function is compiled to code that puts that on the stack, and then a call is made.

Code: Select all

char *test = "test..";
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?
Ytinasni

Re:Problem with a kernel call

Post 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>.*
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Problem with a kernel call

Post by Candy »

I would vote for an

Code: Select all

objdump -d -t
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).
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Problem with a kernel call

Post by Solar »

Candy wrote:

Code: Select all

char test[9] = "test..";
when placed in a function is compiled to code that puts that on the stack, and then a call is made.

Code: Select all

char *test = "test..";
is compiled into a string constant in rodata (or rdata or whatever) that's then referred to.
You never stop learning. ;)
Every good solution is obvious once you've found it.
Post Reply