Page 1 of 2

C arrays

Posted: Fri Nov 15, 2013 5:56 pm
by teodori
Hello, I have a problem using arrays in C. I want to put text on the screen through VGA buffer.

Code: Select all

	// this works :-)
	vga_write(COLOR_BLACK, COLOR_WHITE, 't', 90);
	vga_write(COLOR_BLACK, COLOR_WHITE, 'e', 91);
	vga_write(COLOR_BLACK, COLOR_WHITE, 's', 92);
	vga_write(COLOR_BLACK, COLOR_WHITE, 't', 93);

	// this doesn't work :-(
	vga_write_str(COLOR_BLACK, COLOR_WHITE, "test", 4, 90);
Here are my two functions

Code: Select all

uint16_t* vga_buffer = (uint16_t*) 0xb8000;

void vga_clear(uint8_t background, uint8_t foreground){
	uint16_t i, data = (background << 12) | (foreground << 8) | ' ';

	for(i = 0; i < 2000; i++)
		vga_buffer[i] = data;
}

void vga_write(uint8_t background, uint8_t foreground, uint8_t byte, uint16_t offset){
	uint16_t data = (background << 12) | (foreground << 8) | byte;

	vga_buffer[offset] = data;
}

void vga_write_str(uint8_t background, uint8_t foreground, const uint8_t* string, uint16_t string_len, uint16_t offset){
	uint16_t i, data = (background << 12) | (foreground << 8);

	for(i = 0; i < string_len; i++){
		data |= string[i];
		vga_buffer[offset + i] = data;
	}
}

Re: C arrays

Posted: Fri Nov 15, 2013 7:01 pm
by Octocontrabass
It doesn't happen to print "tuww" instead of "test", does it?

Re: C arrays

Posted: Fri Nov 15, 2013 7:30 pm
by teodori
No it prints nothing except the colors I entered. It seems that the array is empty?

Re: C arrays

Posted: Fri Nov 15, 2013 7:40 pm
by Octocontrabass
The array is located in your rodata section. Either you've linked your rodata section incorrectly, or (if you're using your own bootloader) you're loading it incorrectly.

Re: C arrays

Posted: Fri Nov 15, 2013 7:57 pm
by teodori
Here is my linker script:

Code: Select all

OUTPUT_FORMAT(binary)
ENTRY(start)
SECTIONS{
	.text : { *(.text) }
	.rodata : { *(.rodata) }
	.data : { *(.data) }
	.bss : { *(.bss) }
}
And objdump -h gives me this:

Code: Select all

kmain.o:     file format elf64-x86-64

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         00001145  0000000000000000  0000000000000000  00000040  2**0
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  1 .data         00000001  0000000000000000  0000000000000000  00001185  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  0000000000000000  0000000000000000  00001186  2**0
                  ALLOC
  3 .rodata       00000006  0000000000000000  0000000000000000  00001186  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .comment      0000002c  0000000000000000  0000000000000000  0000118c  2**0
                  CONTENTS, READONLY
  5 .note.GNU-stack 00000000  0000000000000000  0000000000000000  000011b8  2**0
                  CONTENTS, READONLY
  6 .eh_frame     00000678  0000000000000000  0000000000000000  000011b8  2**3
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA

Re: C arrays

Posted: Fri Nov 15, 2013 8:07 pm
by teodori
I confirm that my kernel is correctly loaded into memory by my MBR code.

Re: C arrays

Posted: Fri Nov 15, 2013 8:57 pm
by Octocontrabass
You haven't specified the load address in your linker script, so the linker probably assumes your binary will be loaded to address 0. You need a proper load address so that the pointers to .rodata will be correct in the final binary.

Re: C arrays

Posted: Sat Nov 16, 2013 9:20 am
by bwat
I don't think you wanted to write this:

Code: Select all

 for(i = 0; i < string_len; i++){
      data |= string[i];
      vga_buffer[offset + i] = data;
   }
Ask yourself what happens to the least significant 7 bits of variable data as you run through the string. I think this is what Octocontrabass was trying to point out a few posts back.

Re: C arrays

Posted: Sun Nov 17, 2013 4:50 am
by teodori
Hm how do I specify the load address in my liker script? I read the the documentation of the gnu ld, but I don't know where to put the load address.

Code: Select all

OUTPUT_FORMAT(binary)
ENTRY(start)
SECTIONS{
   .text 0x7e00 : { *(.text) }
   .rodata : { *(.rodata) }
   .data : { *(.data) }
   .bss : { *(.bss) }
}
or

Code: Select all

OUTPUT_FORMAT(binary)
ENTRY(start)
SECTIONS{
   .text : AT(0x7e00) { *(.text) }
   .rodata : { *(.rodata) }
   .data : { *(.data) }
   .bss : { *(.bss) }
}

Re: C arrays

Posted: Sun Nov 17, 2013 5:09 am
by Combuster
To start off, it's a flat binary. It doesn't tell your loader anything, not load addresses, not execute addresses. If you try objdump on your kernel it it'll cry havoc instead of providing an answer, which means that everything past linking has to be checked by hand to be sure.

Bottom line is that your bootloader decides where it goes in memory, and the linker has to be told (before that!) to use the same location as the execute address. Since the linker doesn't have any logic on booting, that means you need to conciously make that choice in advance, and dictate both the linker and bootloader to follow that choice..

When you're done, read the linker script example: http://wiki.osdev.org/Higher_Half_bare_bones

Re: C arrays

Posted: Sun Nov 17, 2013 12:16 pm
by teodori
Ok in my assembler code I manage the addresses correctly, because I know where put things and where to find them. But what about my C code? I thaught that the linker would do that when my program is linked? My kernel is a simple bootloader and virtual address is equal linear address for now. To make it simple the MBR code loads 127 sectors right behind the loaded MBR code, then jumps to it. The frshly loaded code goes to Protected Mode then to Long Mode, remaps the 2 PICs, sets up the PIT, PS/2 and the DMA. My VGA driver doesn't work because of stored variables in my .data section. How do I tell the compiler and/or the linker to correct it?

Re: C arrays

Posted: Sun Nov 17, 2013 12:34 pm
by Combuster
I thaught[sic] that the linker would do that when my program is linked?
Then begin with posting your proof that it doesn't.

Re: C arrays

Posted: Mon Nov 18, 2013 1:14 pm
by teodori
Okay can you please tell me what I should do. At his part I am completly lost... Where should I begin searching? Is there something wrong with the stack?

Re: C arrays

Posted: Mon Nov 18, 2013 1:46 pm
by teodori
My gcc adds some functions during compilaion it seems...

Code: Select all

ld -T kernel.ld
kmain.o: In function `kmain':
kmain.c:(.text+0x1c4): undefined reference to `__stack_chk_fail'

Re: C arrays

Posted: Mon Nov 18, 2013 2:47 pm
by Combuster
teodori wrote:ld
See the FAQ and Posting Checklist