Home arrow Forums
OSDEV Forums  


sngskunk
User

Junior Osdever
Posts: 5
graphgraph
Karma: 0  
64-bit kernel not passing (char *) correctly - 2008/06/18 14:28 Okay, I have a 64-bit kernel, which boots correctly sets up paging, jumps into long mode and everything works great.

I can put characters to the screen, but I cannot write strings to the screen because I can not get my write function to work properly.

Code:

 void write(char *c) {     int i 0;     while(c[i]) {         put(c[i++]);     } }



For some reason it doesn't work, c[0] == 0, and so it never puts any character to the screen. c[1], c[2], c[any number] == 0, no matter what.

I have tried different ways of doing it, and it doesn't work, the compiler doesn't give any errors or warning. The put function works fine, I can type put('c'); and I get c on the screen.

I also have a write_int(c[0]) and it prints 0.

I call the write function just like this:

write("abc");

nothing gets printed, any help would be appreciated.
  | | The administrator has disabled public write access.
OSDEV
Community
Advertisement
   
ChazZeromus
User

Junior Osdever
Posts: 5
graphgraph
Karma: 0  
Re:64-bit kernel not passing (char *) correctly - 2008/06/18 14:35 It is stressed many times in msdn(kernel development counts too) 64-bit programming that in order to use pointer correctly(you can still use normal 32-bit data types and others) the pointers MUST always be 64-bits wide! When you switch to 64-bit mode, you have to make sure your compiler makes all pointers 64-bits wide. Using 32-bit pointers makes a truncated 64-bit pointer. So make sure your compiler or you make that char* pointer 64-bits wide.
  | | The administrator has disabled public write access.
sngskunk
User

Junior Osdever
Posts: 5
graphgraph
Karma: 0  
Re:64-bit kernel not passing (char *) correctly - 2008/06/18 15:38 i did make sure that it is the correct size,

I did sizeof(char *) and i got 8 which is in bytes which would be 64bit, is that correct then?

I then did sizeof(char) and got 1 byte which is 8 bits which is correct.

What can i do to get it to work?

Post edited by: sngskunk, at: 2008/06/18 14:39
  | | The administrator has disabled public write access.
ChazZeromus
User

Junior Osdever
Posts: 5
graphgraph
Karma: 0  
Re:64-bit kernel not passing (char *) correctly - 2008/06/18 19:00 So you can print an array of characters by monolithically calling put right?

So you would try to do write("Hello World") and it wouldn't work? Maybe your compiler put strings in another section other than data and code and the final compilation probably doesn't it or something.

Oh yeah, and does the function push the entire 8 bytes instead of 4? Is the stack's segment descriptor aware of 64-bits? Does the segment descriptor have the L flag(64-bit flag) set?

Post edited by: chazzeromus, at: 2008/06/18 23:13
  | | The administrator has disabled public write access.
sngskunk
User

Junior Osdever
Posts: 5
graphgraph
Karma: 0  
Re:64-bit kernel not passing (char *) correctly - 2008/06/18 23:53 After doing some objdump i found this, it looks a little wierd but might be correct:

Code:

 <.rodata>:    0:   68 65 6c 6c 6f          pushq  $0x6f6c6c65



Also here is my linker script maybe I need to change some thing in there.

Code:

 OUTPUT_FORMAT(binary) ENTRY(start) SECTIONS {     . = KERNEL_VMA;     .text AT(ADDR(.text) - KERNEL_VMA)     {         _code = .;         *(.text)         *(.rodata/* Also tryed *(.rodata*) niether work */         . = ALIGN(4096);     }    .data AT(ADDR(.data) - KERNEL_VMA)    {         _data = .;         *(.data)         . = ALIGN(4096);    }        .ehframe AT(ADDR(.ehframe) - KERNEL_VMA)    {        _ehframe = .;        *(.ehframe)         . = ALIGN(4096);    }    .bss AT(ADDR(.bss) - KERNEL_VMA)    {        _bss = .;        *(.bss)        . = ALIGN(4096);    }    _end = .;    /DISCARD/ :    {         *(.comment)    } }



Post edited by: sngskunk, at: 2008/06/18 22:54
  | | The administrator has disabled public write access.
ChazZeromus
User

Junior Osdever
Posts: 5
graphgraph
Karma: 0  
Re:64-bit kernel not passing (char *) correctly - 2008/06/19 00:24 Okay, I think I might just see the problem. Okay, since you probably used single characters to put one character onto the screen like "put('C')", the character data is constant with the code, like "pushd 'C'". But a string is different, an address that is that points to the array of characters is passed like every programmer should know. Judging by the large address given in "pushq $0x6f6c6c65", you kernel can't be THAT big. So make sure that your strings are in your kernel. And make sure that the string's section is in the right order of sections. Cause I know that in order for 0x6f6c6c65 to be valid your kernel has to be placed pretty high in address space 64-bit or not.
  | | The administrator has disabled public write access.
sngskunk
User

Junior Osdever
Posts: 5
graphgraph
Karma: 0  
Re:64-bit kernel not passing (char *) correctly - 2008/06/19 07:30 I checked my binary out put file and the string is in the binary, since the string is in rodata and i put it after the .text section, then that is where it is, just don't know why its not work, becuase the linker is putting it in the binary.

Code:

 0x3f0 C0 75 D8 C9 C3 68 65 6C 6C 6F 00 00 00 00 00 00 00 00         .  u  .  .  .  h  e  l  l  o  .  .  .  .  .  .  .  .   

  | | The administrator has disabled public write access.
ChazZeromus
User

Junior Osdever
Posts: 5
graphgraph
Karma: 0  
Re:64-bit kernel not passing (char *) correctly - 2008/06/19 14:22 Alright, since its pushing a value that is very high in address space, and your kernel shouldn't be that big, this means that the linker assumes that the rodata section is places somewhere far away from code.

You can try another linking method. You can use mine. Well I don't really use linker scripts because the final output can be messed up easily. So I'll give you the just equivalent and see if it works. In your final build step(the making of the binary), instead of using the linker script, make the output another object file.
Then use objcopy on the final object file emitted in this manner(Replace the brackets with your own):
Code:

  objcopy [final object name] -.comment -.note -O binary [binary output name]


This will put your sections together while removing the unneeded.

Post edited by: chazzeromus, at: 2008/06/19 13:30
  | | The administrator has disabled public write access.
sngskunk
User

Junior Osdever
Posts: 5
graphgraph
Karma: 0  
Re:64-bit kernel not passing (char *) correctly - 2008/06/20 00:08 I did the objcopy but I still got the same result, nothing printed. I know this is driving me insane because I am so confused on why this wont work.
  | | The administrator has disabled public write access.
ChazZeromus
User

Junior Osdever
Posts: 5
graphgraph
Karma: 0  
Re:64-bit kernel not passing (char *) correctly - 2008/06/20 18:13 Can you give me the your code, data and stack segment descriptor?
They should all be 64-bits no matter what bit mode. Have you set the mode in 64-bit mode or compataiblity? Have you setup the appropriate stuff yet? There are a lot of things you have to do for 64-bit mode compatibility. Because 64-bit start-up is way too different than 32-bit mode.

Post edited by: chazzeromus, at: 2008/06/20 17:27

Post edited by: chazzeromus, at: 2008/06/20 17:28
  | | The administrator has disabled public write access.

A WebArticles site. Sponsored by Evoleto. Motorola V525 / Business Directory / Delaware Incorporation / Home Made Bazaar