Hi everyone, I have installed arm-elf-tools by typing sh arm-elf-tools-20030314.sh then I would like to compile a boot.S file for arm7tdmi. So I type : arm-elf-as -marm7tdmi boot.S And I obtain no error, no message in the console but a file called a.out that contain only one thing : ELF a What is the problem ? did I made something wrong ? Thanks for your help Regards,
I am no guru, but the following points may help you. 1) I am guessing you are not using WinARM. This is a WinARM forum, as you are using GNU tools a lot will be the same as WinARM. You may want to post on the GNU ARM yahoo group instead. 2) I would not suggest you start with nothing, it will take a long time to get where you want to be. Why not download some demo application for your chip. You do no mention what chaip that is???? 3) I suggest you download Jim Lynch's tutorial. It is based around Windows and Eclispe I know but a lot is still relevant to any GCC ARM development. 4) In your command line you did not specify an output file name GNU tools tend to default to outputting a if you do not specify. It seems to have output a.elf which is file which can contain both your machine code and debugging sysmbols to go with it. 5) The level of questions you are asking would lead me to think that the chances of a.elf doing anything useful is pretty close to zero. Read my comments above give yourself a better chance of getting something working. I may be wrong on this and do not take it personally. Good Luck. FordP armand iostrym wrote: > Hi everyone, > > I have installed arm-elf-tools by typing > sh arm-elf-tools-20030314.sh > > then I would like to compile a boot.S file for arm7tdmi. > > So I type : > > arm-elf-as -marm7tdmi boot.S > > And I obtain no error, no message in the console but a file called a.out > that contain only one thing : > > ELF a > > What is the problem ? did I made something wrong ? > > Thanks for your help > > Regards,
thanks for your help, the title of the forum is WinARM / ARM-GCC. isn't it also a gcc forum ? My processor is an ARM7TDMI and the chip is an ACTEL FPGA called M7 ProASIC3 in which you can implement an ARM7TDMI. the file I would like to compile is not very complex. It is a very simple boot sequence with some LDR and ADR... the strange things is that the a.out seems to be empty (ELF a) unless I don't have the right software to read it ? However I will look at the tutorial you indicate previously.
Why don't you use gcc (or better a makefile) to call the assembler? The *.S extension is for assembler files which should be parsed by the preprocessor (see 'Assembler code which must be preprocessed' http://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html#Overall-Options). I don't know whether the assembler calls the preprocessor itself, but i don't think so. Normally this is the job of gcc arm-elf-gcc -mcpu=arm7tdmi -c boot.S -o boot.obj should work. Stefan
I don't understand the difference between *.s and *.S : file.s Assembler code. file.S Assembler code which must be preprocessed. the preprocessor action is for *.c file, to remplace #define by the real value for exemple. As an assembler file hasn't any #define or include, why is there a need to preprocessor an assembler file ? Stefan wrote: > Why don't you use gcc (or better a makefile) to call the assembler? > > The *.S extension is for assembler files which should be parsed by the > preprocessor (see 'Assembler code which must be preprocessed' > http://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html#Overall-Options). > > I don't know whether the assembler calls the preprocessor itself, but i > don't think so. Normally this is the job of gcc > > arm-elf-gcc -mcpu=arm7tdmi -c boot.S -o boot.obj > > should work. > > Stefan
> the title of the forum is WinARM / ARM-GCC. isn't it also a gcc forum ? Yes it is. WinARM is just a collection and the arm-elf gnu-toolchain is the main part of the collection so this forum has to be some kind of "arm gcc forum" too. It has been the intention to be not only a WinARM forum (see my "Welcome" message). > I don't understand the difference between *.s and *.S : > > file.s > Assembler code. > file.S > Assembler code which must be preprocessed. > > the preprocessor action is for *.c file, to remplace #define by the real > value for exemple. As an assembler file hasn't any #define or include, > why is there a need to preprocessor an assembler file ? It is very convinient. The preprocessor offers a lot of functions which are not available or less functional than the build-in functions of the assembler. You can use all options you know from your c-coding in your assembler-sources too (and do not need to learn about all assembler-"."-functions). The preprocessor is basicly an "automatic text-replacer" and does not care if it works on a text which is c-source-code or assembler-source-code. Martin Thomas
Thanks you all for your help. So to conclude, a *.s file containing C and asm should be pre-processored with gcc and a *.S file with only assembler code should be assembled with as ? gcc --> pre-processor and compilation as --> assembling. but sometimes gcc can also do all the compilation flow including as? And finally another question, to be sure, extension .s, .S, .cpp etc. are only used to indicate to the user what sort of file is it but the extension is not important for gcc ? Great thanks to everyone, Regards,
*.s = only assembler code as only is possible, but gcc invoking as is better *.S = assembler code and preprocessor (cpp) macros gcc invoking cpp and later as is better gcc is the caller for preprocessor and/or compiler and/or assembler and/or linker. You can call the whole toolchain or parts of it with gcc. And make is the caller of gcc... And the extension is very important. gcc decides whether to call cpp (*.c, *.S) or not (*.s) with the extension! Regards Stefan
Thanks, So it seems that arm-elf-gcc -mcpu=arm7tdmi -S boot.S would be ok to make the pre-processoring and the compilation of my assembling file. I thought I would get as a result a .s file but this command doesn't create anything. I have no error but also no output file. I try also arm-elf-gcc -mcpu=arm7tdmi -E boot.S and I see that the preprocessing is ok because it remplace that #define by their value. but the output is print on the console. So maybe I have to make something like : toto.s << arm-elf-gcc -mcpu=arm7tdmi -E boot.S but it's weird because I thought that with arm-elf-gcc -mcpu=arm7tdmi -S boot.S I could get the final *.s file.
-S : Stop after compilation and generate the assembly code. This code will be saved in a file with the extension ".s". A extract of the assembler code is given below. Input files that don't require compilation are ignored. => You don't have a source file to compilate, because you havn't a c source file but a assembler source file. gcc doesn't make anything. -E : Do only preprocessing, no compiling or assembling. Output results to standard output file a.out. -o file : Place output in file file. This applies regardless to whatever sort of output is being produced, whether it be an executable file, an object file, an assembler file or preprocessed C code. If -o is not specified, the default is to put an executable file in a.out, the object file for source.suffix in source.o, its assembler file in source.s, a precompiled header file in source.suffix.gch, and all preprocessed C source on standard output. OK. I would try arm-elf-gcc -mcpu=arm7tdmi -E boot.S -o boot.s
arm-elf-gcc -mcpu=arm7tdmi -E boot.S -o boot.s work and arm-elf-gcc -mcpu=arm7tdmi -E boot.S > boot.s work also. thanks for your help; Everything is okay, I unerstand quite perfectly the gcc flow thanks to all of you. Nevertheless, I have a new problem with the linker. If I want to run a complete gcc flow to compile boot.S, I have the following error : /tmp/cc4Zc7LE.o: In function `_start': /tmp/cc4Zc7LE.o(.text+0x0): multiple definition of `_start' /usr/local/arm-elf/lib/crt0.o(.text+0x0): first defined here /usr/local/arm-elf/lib/libc.a(__uClibc_main.o): In function `__uClibc_start_main': __uClibc_main.o(.text+0xf4): undefined reference to `main' collect2: ld returned 1 exit status nm boot.o : 00000020 t Remap_address 0000001c t Remap_command 00000000 T _start and nm crt0.o: U abort U main 00000000 T _start U __uClibc_main I made a some research and I have found that crt0.o is an "execution startup routine". the two are using _start and it seems to be incompatible. However I don't call crt0.o somewhere so I don't understand why there is a problem with this object file. Moreover, crt0.o need to define main that obviously I don't define... What is the purpose of this object file and do you know why it seems to be linked with my boot.s ? Best regards and thanks a lot for everything
You don't have a problem with the linker, but with your project. Did you mix startup code from different projects? When you wrote boot.S, how could you be sure that other source files in your project didn't use the global symbol _start already? Often the startup code is organized in several source files, which are assembler files for the initial and low-level work and later some c source files for the higher-level work. Typical tasks in crt0.c or crt0.s are * copy DATA from ROM to RAM * zero BSS * open file descriptors (optional) * call main (optional with arguments) * handle an abort or an exit or a return from main You can extent crt0.c to perform other tasks too i.e. REMAP and exception vectors, but other people prefer to do this in another source file and call this file boot.S, startup.S or vectors.S.... > __uClibc_main.o(.text+0xf4): undefined reference to `main' You need at least an application function main() in your project. This function is called after initialization. But this is basic C.
Hi, great thanks for your help ! It's strange because my project in fact is one file : boot.S : #define I_BIT (1 << 7) #define F_BIT (1 << 6) #define ARM_MODE_SVC 0x13 // SVC -> supervisor mode. .global _start // make symbol visible to the linker _start: mov r0, #(ARM_MODE_SVC | I_BIT | F_BIT ) /* disable interrupts. r1 = 11010011*/ msr cpsr, r0 /* Load the address where to jump */ ldr r12, uClinux_kernel_decompression_address /* get the real jump address ( after remap ) */ adr r0, Remap_command adr r1, Remap_address str r0, [r1] /* REMAP command */ mov pc, r12 /* jump to the uClinux_kernel_decompression address and break the pipeline */ Remap_command: .long 0x00000001 /* REMAP command */ Remap_address: .long 0x20000000 /* REMAP address */ It's a bootloader that perform a remap, the disable of interruptions and then jump to the adress a another program that will be compiled indepenantly of this file. I would like to program the ROM with the bootloader at the adress 0x00000000 and separatly made another program (anything) that I will just have to program at the precedent jump adress. In my case it will be the decompression of the kernel in the ram to prepare its execution. (quite ambitious, but I will try :-) ) Do you think my approach is good ? or maybe I have to compile the bootloader and the called program in one project ? But today, this project is composed by one file, boot.S and there should be no call to crt0.s. I still don't understand why this file is include "by default" in my project... Maybe it due to my cross compilation tools chain that may be specific to uClinux... If I understand what you said, the real boot of my project is crt0.s whereas I havn't specified it anywhere ? Regards,
When you > If I want to run a complete gcc flow to compile boot.S, then there might be command lines and/or options in your makefile and/or gcc environment options which include the libraries and the c-runtime-library-startup-code aka crt0 for a complete project named uClinux. But you can switch on verbose mode for gcc and get all command lines and so on for the project in order to check this. The algorithm of your boot.S and the relevance for a emulated ARM7 system in a FPGA chip (right?) is too complicated for me. I don't understand your new symbol uClinux_kernel_decompression_address and its relevance to the Remap_address esp. with =Remap_address = 0x20000000. It is hard enough to start a simple application program (main) on a chip from scratch, but you try even something harder - you try to start a OS (uClinux) which will start automatically an application user program (main)... this is way above my experience level now. I would look in the porting section of the OS whether somebody has already written a port (startup code including crt0...) for my target (processor type and layout of the board = type/addresses of RAM/ROM...) or i would modify an existing port. But writing a startup code from scratch, uff ;-)
armand iostrym wrote: > I would like to program the ROM with the bootloader at the adress > 0x00000000 and separatly made another program (anything) that I will > just have to program at the precedent jump adress. > In my case it will be the decompression of the kernel in the ram to > prepare its execution. (quite ambitious, but I will try :-) ) > Do you think my approach is good ? or maybe I have to compile the > bootloader and the called program in one project ? Both methods are possible and used within the programming community.
The step by step flow is working: Pre-processor: arm-elf-gcc -mcpu=arm7tdmi -E boot.S -o boot.s assembly : arm-elf-as -arm7tdmi boot.s -o boot.o link : arm-elf-ld boot.o And I get a.out that is the final object file. But if I do directly the complete flow with Arm-elf-gcc -mcpu=arm7tdmi boot.S I have the precedent error. Right, it's an ARM7TDMI included in ACTEL FPGA. Have you ever heard of it? uuu, how do you guess that it was included in a FPGA? you are very strong :-) The boot.S isn't complex, the "uClinux_kernel_decompression_address" will be the adress to jump after the remap and it will perform the decompression of the kernel. It's already done, I use a uClinux distribution for ATMEL AT91. It's not completely clear for me but at least I don't do things from scratch :-) All the work is done for uClinux (not entirely :-/ ), there is already a startup code for the kernel ... but as these distribution are made for people who use a eveluation board with integrated bootloader I have to do mine. Remap_address and Remap_command are the adresses where to write the Remap_command in order to perform the Remap. Maybe there is a better way to write it but the remap is only done by writing a data in a specific register of the memory controller. I agree with you, it's hard to start with an OS but that's why I train myself with this small bootloader. As I said in a post in another topic, I would like to compile separately the boot.S and the uClinux distribution. There is already a makefile for the uClinux distribution. I have a lot of thing to do to adapt the uClinux distrib' for my architecture. At the end of the process I would like to get one executable file for the bootloader to put at adresse 0x00000000 and one binary file for the uClinux. That's why I would like to compile the boot.S separately and absolutely not include crt0.o... Okay, I understand now... I use the verbose mode and I see that : assembler: /usr/local/arm-elf/bin/as -marm7tdmi -o /tmp/cc0973Dx.o /tmp/cc9NAHkj.s linker: /usr/local/lib/gcc-lib/arm-elf/2.95.3/collect2 -X /usr/local/arm-elf/lib/crt0.o -L/usr/local/lib/gcc-lib/arm-elf/2.95.3 -L/usr/local/arm-elf/lib /tmp/cc0973Dx.o -lgcc -lc -lgcc So in the complete gcc flow, there is an inclusion of the crt0.o in my project due to the fact it's a tool chain made for uClinux. And that why my step by step approach is working. Thanks to you !