C string doesn't work when cross compile c kernel.

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.
Post Reply
yuriyzam
Posts: 6
Joined: Sat Aug 10, 2019 11:46 am

C string doesn't work when cross compile c kernel.

Post by yuriyzam »

Issue: strings defined as

Code: Select all

const char* greeting_msg = "Hello, world!";
are not readable (defining them as const char greeting_msg[] solve problem).
Full source code:
https://github.com/YuRaZaKa/AltOS/tree/master
C file with issue:

Code: Select all

#include <stddef.h>
#include <stdint.h>

uint8_t* video;

void cls(){
    video = 0xb8000;
    for(size_t i = 0; i < 25*80; ++i){
        *(video++) = ' ';
        *(video++) = 0x1F;
    }
    video = 0xb8000;
}

void write(const char* data){
    for(size_t i = 0; data[i] != '\0'; ++i){
        *(video++) = data[i];
        *(video++) = 0x1F;
    }
}

void kmain(void){
    cls();
    const char* greeting_msg = "Hello, world!";
    write(greeting_msg);
}
Makefile

Code: Select all

osname = AltOS

init:
	rm -rf $(osname).iso
	rm -rf obj
	rm -rf bin
	rm -rf iso
	mkdir obj
	mkdir bin
	mkdir iso
	mkdir iso/boot
	mkdir iso/boot/grub
compile:
	x86_64-elf-gcc src/c/kmain.c -o obj/kmain.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra -nostdlib
assembly:
	nasm -f elf64 src/asm/multiboot_header.asm -o obj/multiboot_header.o
	nasm -f elf64 src/asm/boot.asm -o obj/boot.o
	nasm -f elf64 src/asm/long.asm -o obj/long.o
link:
	x86_64-elf-ld -n -o bin/kernel.bin -T src/ld/linker.ld obj/kmain.o obj/multiboot_header.o obj/boot.o obj/long.o 

grubprepare:
	cp bin/kernel.bin iso/boot
	echo 'set timeout=0' >> iso/boot/grub/grub.cfg
	echo 'set default=0' >> iso/boot/grub/grub.cfg
	echo 'menuentry "AltOS" {' >> iso/boot/grub/grub.cfg
	echo '	multiboot2 /boot/kernel.bin' >> iso/boot/grub/grub.cfg
	echo '	boot'  >> iso/boot/grub/grub.cfg
	echo '}' >> iso/boot/grub/grub.cfg

image:
	grub-mkrescue -o $(osname).iso iso

vm:
	qemu-system-x86_64 -cdrom $(osname).iso

run: init compile assembly link grubprepare image vm
I am using latest cross compiled gcc (9.1.0) and binutils (2.32)
MollenOS
Member
Member
Posts: 202
Joined: Wed Oct 26, 2011 12:00 pm

Re: C string doesn't work when cross compile c kernel.

Post by MollenOS »

What happens when the code runs?
yuriyzam
Posts: 6
Joined: Sat Aug 10, 2019 11:46 am

Re: C string doesn't work when cross compile c kernel.

Post by yuriyzam »

What happens when the code runs?
If const char[] used it outputs "Hello, world!" as it should. Otherwise, nothing will be displayed (only blue background will).
Before that, it checks multiboot and set long mode. Maybe the problems are in GDT?
User avatar
iansjack
Member
Member
Posts: 4662
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: C string doesn't work when cross compile c kernel.

Post by iansjack »

The difference between the two is where the string is stored.

const char * - the string is stored in the .rodata section
const char[] - the string is stored on the stack

This should work, except for the fact that you are giving your linker conflicting information. When you compile kmain.c you link it at the same time. So kmain.o is an executable, not a simple object file. The linker assumed that the file is loaded at 0x400000 (the default), with the .rodata section at 0x400151.

You then link the executable again, this time telling it that the program is loaded at 0x100000, with the .rodata section at 0x1001f0. When the program runs it thinks the string is at 0x400151, and prints the empty data there.

The answer is that you need to use the -c switch when compiling kmain.c to produce an object file rather than an executable.
yuriyzam
Posts: 6
Joined: Sat Aug 10, 2019 11:46 am

Re: C string doesn't work when cross compile c kernel.

Post by yuriyzam »

Thanks, it worked/
Btw, how I should solve this for multiply c files?

Code: Select all

x86_64-elf-gcc -c src/c/kmain.c src/c/vgacolor.c -o obj/kmain.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra -nostdlib
x86_64-elf-gcc: fatal error: cannot specify -o with -c, -S or -E with multiple files
compilation terminated.
User avatar
iansjack
Member
Member
Posts: 4662
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: C string doesn't work when cross compile c kernel.

Post by iansjack »

You compile each source file to an object file separately.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: C string doesn't work when cross compile c kernel.

Post by Solar »

Perhaps check out the wiki on Makefiles.
Every good solution is obvious once you've found it.
Post Reply