1

Currently, I'm learning RISC-V, use the RISC-V toolchain, and edit a new ld script for my embedded. I write a example, and compile to watch the opcode.

Example:

#include <stdio.h> //float.c

int main()
{
float a=1.04;
printf("a=%f\n",a);
return 0;
}

My steps is:

1. riscv64-unknown-elf-gcc -S float.c  *//generate assembly code*

2. riscv64-unknown-elf-as float.s -o float.o  *//generate obj file*

3. riscv64-unknown-elf-ld -T elf64lriscv1.x float.o *//use own script to link, -T is using other script*

and then,it will show "float.c:(.text+0x50): undefined reference to `printf'

I'm try

Add -lc parameter, but doesn't working, it will show more undefined message.

My ld script

OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv","elf64-littleriscv")
OUTPUT_ARCH(riscv)
ENTRY(_start)
SEARCH_DIR("/path/to/install/riscv/toolchain/riscv64-unknow-elf/lib");
/*MEMORY{  //for my embedded allocation
  flash : org = 0x0, l = 0x10000
  ram : org= 0x10000, l = 512
}*/
SECTIONS{
_start =0x10000;
.text :
{
  *(.text)
}
.bss :
{
  *(.bss)
  *(.sbss)
}}

Also, i'm trying to use the default script, like this command:

$ riscv-unknown-elf-ld float.o -o float

but it is same result.... please help me!

Regards!

Owen
  • 41
  • 7
  • You need to learn not only RISC-V but much much more. See http://norvig.com/21-days.html – Basile Starynkevitch Nov 03 '17 at 06:53
  • BTW, why don't you use Linux on your RISCV-V ? It might be easier, even if Linux is not completely mature on that platform... – Basile Starynkevitch Nov 03 '17 at 06:59
  • I got a RISCV VM on linux, and i relocated to my MCU(TI 320F28335) using CCS, now i'm trying to compile C code(the toolchain is on linux) and get the RISCV instruction load to MCU and execute – Owen Nov 03 '17 at 07:15
  • My guess is that you are lacking a lot of skills and knowledge. You might need months or years of efforts to get them. What you want to achieve is much more difficult and complex than what you imagine (because you need to learn a lot). And I was suggesting running Linux on your RISCV hardware (even if it is some virtual one). – Basile Starynkevitch Nov 03 '17 at 07:17
  • Yes.... I'm learning a lot new knowledge everyday... that is difficult for me – Owen Nov 03 '17 at 07:21
  • No, RISC-V is quite easy (easier than x86-64). But **programming is difficult**. What you need to learn is *not* RISC-V specific. And you need to learn a lot. So be patient. Did you consider following some formal programming class, and some CS education ? – Basile Starynkevitch Nov 03 '17 at 07:21
  • For example, reading [SICP](https://mitpress.mit.edu/sicp/), [ALP](http://www.makelinux.net/alp/) and the [Dragon Book](https://en.wikipedia.org/wiki/Compilers:_Principles,_Techniques,_and_Tools) would be useful to you (in addition of the links given in my answer) and they are unrelated to RISC-V. It seems that you are missing some basics. – Basile Starynkevitch Nov 03 '17 at 07:26
  • And floating point is difficult; read http://floating-point-gui.de/ for more. Why do you need an example with `float` ? – Basile Starynkevitch Nov 03 '17 at 07:28
  • The hints [here](https://stackoverflow.com/a/47082345/841108) also apply to you... – Basile Starynkevitch Nov 03 '17 at 07:30
  • hi Starynkevitch, thank you for your answer, the float just a example, my problem is about "printf" cannot link, i will do my best to learning more knowledge! – Owen Nov 03 '17 at 07:37
  • Be aware (and tell your manager, if you are employed) that you'll need *months* of work, and perhaps more. Your lack of knowledge is mostly unrelated to RISC V. – Basile Starynkevitch Nov 03 '17 at 07:46

1 Answers1

1

printf is provided by the C standard library (and is very difficult to implement). You need to link it (perhaps by adding -lc to your riscv-unknown-elf-ld command, or by giving the complete path of that library)

You might pass additional options to your riscv-unknown-elf-ld perhaps -M, -L search-dir, --trace, --verbose, etc. Read also more carefully the chapter about ld scripts.

Since you are cross-compiling, you might need to cross-compile some libc from source code.

You need to spend more time understanding the behavior of linkers and ELF object files and executable format (see also elf(5)). Consider reading Linkers and Loaders

You could use other cross- binutils programs (like cross- objdump, nm, readelf etc...) to explore the relevant object files.

If you are coding for a bare metal system, you might want to compile in freestanding mode (passing -ffreestanding to your GCC) and provide so implement your own printf (or other output) function. Existing free software C libraries could inspire you (but you need to find one or work many months to develop some equivalent). Study for inspiration the source code of GNU libc or of musl-libc.

I recommend also reading about OSes, e.g. Operating Systems: Three Easy Pieces (since the OS concepts are relevant to you, because an embedded system on the bare metal share features with OSes). OSDEV wiki might also be helpful (but is not about RISC-V).

You could need several months of work (or even years), so budget it appropriately.

BTW, I am surprized that you use a float in your example. Floating point is difficult. See floating-point-gui.de ; For a first try, I would consider using integer only.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547