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