News:

Registered a URL and setup a forum as the IPCam stuff really needed its own site vs my irregular blog posts about IPCam hacking at http://www.computersolutions.cn/blog

Author Topic: Compiler Tips for uClinux #2 (...or how to get the BSP running on GCC3.3.4)  (Read 5867 times)

  • No avatar
  • *****
February 04, 2011, 08:36:52 am
If you've been following in the series of posts that no-one reads, you'll see that we have quite an old GCC toolchain for our BSP.

Lots of software that we want to compile really wants a newer toolchain, so what to do?

As a special gift for those of you who bother to actually read these posts, I've obtained an ARM gcc 3.3.4 toolchain (from MCUOS).

Lets download that.

Code: [Select]
su
mkdir /home/downloads
cd /home/downloads
axel http://www.openipcam.com/files/uCLinux/arm_tools_3.3MCUOS.tar.bz2
cd /usr/local
tar -xjvf /home/downloads/arm_tools_3.3MCUOS.tar.bz2

At this point, we should have a copy of the tools in arm_tools_3.3 in /usr/local
Lets rename the existing gcc 3.0 tools to something else, and make this our toolchain of choice.
(We could also change the compiler preference in our config.arch or set a new path, but this is quicker)

Code: [Select]
mv arm_tools arm_tools_3.0
mv arm_tools_3.3 arm_tools

Lets head back to the BSP now

Code: [Select]
cd /home/N745/W90N745-uClinux/uClinux-dist
make clean
make dep
make

If you've followed the above, you'll soon see that gcc borks at the checksum.h file.
The first place we'll look is the ucLinux cvs to see what they think

http://cvs.uclinux.org/cgi-bin/cvsweb.cgi/uClinux-2.4.x/include/asm-armnommu/checksum.h


Ahah!  revision 1.3 says - "the last gcc-3 changes broke the asm so that networking would not work,
get it right this time."

There is a newer revision however, so lets grab that, and see if its good.

Code: [Select]
cd uClinux-2.4.x/include/asm-armnommu
mv checksum.h checksum.h.2.4.20.orig
pico checksum.h

Copy and paste the code from http://cvs.uclinux.org/cgi-bin/cvsweb.cgi/uClinux-2.4.x/include/asm-armnommu/checksum.h?rev=1.4;content-type=text%2Fplain, and save the file.

Lets return to our folder and continue the make.

Code: [Select]
cd /home/N745/W90N745-uClinux/uClinux-dist
make

Sweet, it got further.

What does it complain about now?

Code: [Select]
cc1: error: invalid option `no-fpu'
Lets see what causes that

Code: [Select]
grep "\-mno\-fpu" * -R
linux-2.4.x/arch/armnommu/Makefile:AFLAGS += $(apcs-y) $(proc-y) -mno-fpu
linux-2.4.x/arch/arm/Makefile:AFLAGS +=$(apcs-y) $(arch-y) -mno-fpu -msoft-float

Ok, its the armnommu makefile. (as we don't use the arm architecture)

Lets check the CVS - http://cvs.uclinux.org/cgi-bin/cvsweb.cgi/uClinux-2.4.x/include/asm-armnommu.
Hmm, no Makefile.

Ok, back to google.
Interestingly we get zero results for -mno-fpu
This is obviously as its interpreting the -'s incorrectly.  Silly google.
Search for "-mno-fpu" instead, and we soon see that, its been depreciated, and we should be using -mfpu=softfpa

http://gcc.gnu.org/ml/gcc-patches/2003-04/msg00593.html
... Pass -mfpu=softfpa
   instead of -mno-fpu.

Lets make that change, and recompile.
Isn't life wonderful.

Oh wait, that didn't work either.

Code: [Select]
cc1: error: invalid option `fpu=softfpa'
Note to the gcc people, a fucking manual on when options were depreciated and their replacements would be of help.
Further googling ensues.

Ok, the same Nick now says this

http://readlist.com/lists/gcc.gnu.org/gcc/4/22911.html
There should be no need to recompile libgcc. Just change your build
script to use the -mfpu=softvfp switch instead of -mno-fpu.

Oh joy of joys.  Lets try that then shall we.
Guess what?

Code: [Select]
cc1: error: invalid option `fpu=softvfp'
Arghh.

Lets take a look at the compiler, and double check

Code: [Select]
arm-elf-gcc -dumpspecs
*subtarget_asm_float_spec:
%{mapcs-float:-mfloat} %{msoft-float:-mno-fpu}

Lets try -msoft-float shall we?

Grumble, shitty gcc documentation, grumble etc moan..  :-X

Yay, that worked.  Now onto our next issue.

Code: [Select]
process.c:390: error: parse error before "mov"
Lets just be lazy and copy the newer process.c from the 2.4.36 uClinux current kernel over and see if that will compile.

Woohoo, that works.

Lets continue to our next issue.

Code: [Select]
semaphore.c:221: error: request for member `align' in something not a structure or union
We'll do the same for that..

Run make again..., sweet we got a *lot* further there

Code: [Select]
setup.c:422: error: core_tagtable causes a section type conflict
Lets copy that over, and remake.

So close...

Code: [Select]
setup.c:430: error: `ATAG_INITRD2' undeclared here (not in a function)
Now we're hitting stuff thats been added to the kernel, and isn't in ours.
Lets grep to see where ATAG_INITRD2 was added.

Code: [Select]
grep ATAG_INITRD2 * -R
linux-2.4.x/arch/armnommu/kernel/setup.c:__tagtable(ATAG_INITRD2, parse_tag_initrd2);
linux-2.4.x/arch/arm/kernel/setup.c:__tagtable(ATAG_INITRD2, parse_tag_initrd2);
linux-2.4.x/include/asm-arm/setup.h:#define ATAG_INITRD2 0x54420005
linux-2.4.x/include/asm-armnommu/setup.h:#define ATAG_INITRD2 0x54420005

- Looks like we'll need to add this line in our setup.h file
 #define ATAG_INITRD2   0x54420005

Code: [Select]
pico /home/N745/W90N745-uClinux/uClinux-dist/linux-2.4.x/include/asm-armnommu/setup.h

Add that line under the ATAG_INITRD line.


Recompile, and we're almost there. (Famous last words haha).

Code: [Select]
/usr/local/arm_tools/bin/arm-elf-ld.real: ERROR: irq.o uses hardware FP, whereas kernel.o uses software FP
/usr/local/arm_tools/bin/arm-elf-ld.real: failed to merge target specific data of file irq.o

So, it looks like our edit of the kernel makefile to remove the fp stuff didn't quite work.
Lets just remove that and recheck.

Code: [Select]
make clean
make dep
make

Almost there...


Ok, now we compile fine, but have linker problems.

As we have a different linker available - the 3.3.4 buildchain from the BSP, lets try building with that.
I'll save you the trouble and cut to the chase.

That one also breaks in the same place.

Lets retrace our steps a bit then.

We've made changes to

semaphore.c
setup.c
process.c

and the Makefile

as well as setup.h

Lets try compile using our original 3.0 gcc compiler, and see what happens.
If we roll back the setup.c and process.c files, it will compile.

So, we know that the changes that cause issues are in either of those 2 files.

Lets take a closer look at the files, and see if we can spot why.





« Last Edit: February 04, 2011, 12:38:50 pm by admin »

  • No avatar
  • *****
February 04, 2011, 03:09:41 pm
If we look at setup.c, we can quickly see what the issue is.

Our MEM_SIZE is completely different.
Lets copy the defines from the original setup.c, and see how that one compiles up.

Code: [Select]
#ifndef MEM_SIZE

#ifndef DRAM_SIZE
#define MEM_SIZE (7*1024*1024) //lsshi
#else
#define MEM_SIZE        DRAM_SIZE
#endif
//#define END_MEM     (DRAM_BASE + MEM_SIZE)
//#define MEM_SIZE (END_MEM-PAGE_OFFSET) // FIXME

#endif

#ifndef CONFIG_CMDLINE
#define CONFIG_CMDLINE "root=/dev/rom0 rw"
#endif


Recompile, and

Code: [Select]
arch/armnommu/kernel/kernel.o: In function `parse_tag':
arch/armnommu/kernel/kernel.o(.text.init+0xd18): undefined reference to `__tagtable_begin'
arch/armnommu/kernel/kernel.o(.text.init+0xd1c): undefined reference to `__tagtable_end'
arch/armnommu/kernel/kernel.o: In function `setup_arch':
arch/armnommu/kernel/kernel.o(.text.init+0xefc): undefined reference to `squash_mem_tags'
make[1]: *** [linux] Error 1
make[1]: Leaving directory `/home/N745/W90N745-uClinux/uClinux-dist/linux-2.4.x'
make: *** [linux] Error 1

Better, but no cigar.

Well, we do know that the squash_mem_tags are an extern reference in our setup.c
Lets go take a look at that again, and take a look at the newer uclinux files.

Seems that squash_mem_tags is defined in compat.c

Lets try out the newer compat.c in our BSP

A little better, but we still need to work out the __tagtable_begin and end bits.
Lets do the same thing - check the latest uClinux and see where those are defined.


Ahah, thats over in /home/uClinux-dist/linux-2.4.x/include/asm-armnommu/setup.h

Lets compare.

Seems the only change is to add the #define for_each_tag section.

Lets add that above the #define NR_BANKS 8 in our BSP setup.h

Code: [Select]
#define for_each_tag(t,base) \
for (t = base; t->hdr.size; t = tag_next(t))



April 19, 2011, 08:54:19 am
Lets check the CVS - http://cvs.uclinux.org/cgi-bin/cvsweb.cgi/uClinux-2.4.x/include/asm-armnommu.
Hmm, no Makefile.

Just a thought, where you not looking for:
http://cvs.uclinux.org/cgi-bin/cvsweb.cgi/uClinux-2.4.x/arch/armnommu/Makefile this Makefile?

The latest changelog btw (which is really old) does mention the removal/change for certain things for newer gcc's. On a side note, -mshort-load-bytes, which has been renamed in later gcc versions, is the default and removed from newer gcc versions, so the flag can be deleted actually.

(I'm trying gcc-3.4.6 atm and notice that your slightly older 3.3.6 still does have short-load-bytes? I'm using 3.4.6 as that's the oldest version my cross-tools in gentoo would build normally :)

I however are bumping into other fun asm. errors :)

arm-softfloat-linux-uclibc-gcc -D__KERNEL__ -I/silo/build/openipcam-oliver/linux-2.4.20/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -fno-common -pipe -fno-builtin -D__linux__ -DNO_MM -mapcs-32 -march=armv4 -mtune=arm7tdmi -msoft-float   -nostdinc -iwithprefix include -DKBUILD_BASENAME=exit  -c -o exit.o exit.c
{standard input}: Assembler messages:
{standard input}:149: Error: Rn must not overlap other operands -- `swp r0,r7,[r0]'

for example, so new project, find a uClinux version that builds with 3.4.6 and port the patches to that version! Fun :)

A little better, but we still need to work out the __tagtable_begin and end bits.
Lets do the same thing - check the latest uClinux and see where those are defined.


Ahah, thats over in /home/uClinux-dist/linux-2.4.x/include/asm-armnommu/setup.h

Actually, I found those to be over on: http://cvs.uclinux.org/cgi-bin/cvsweb.cgi/uClinux-2.4.x/arch/armnommu/vmlinux-armv.lds.in

However the last error that remains:
Code: [Select]
/usr/local/arm_tools_3.3.4/bin/arm-elf-ld.real: section .rodata.str1.4 [000000a0 -> 0000dc98] overlaps section .init [00008000 -> 00011fff]
Makes no sense to me what so ever. It's a linker/assembler error but no idea what causes it. I do know however, that it happens on the final link step, when it tries to link together the linux kernel itself.

Edit:
Found it. I grepped through the sources but found no mention whatsoever of str1.4 in the entire tree. I did find a later patch that did add .rodata.str1.4. No clue where it came from or what it does, but http://cvs.uclinux.org/cgi-bin/cvsweb.cgi/uClinux-2.4.x/arch/armnommu/vmlinux-armv.lds.in.diff?r1=1.9;r2=1.10 this patch does add it.

http://schinagl.nl/~oliver/012_gcc_3.3.4_support.diff
« Last Edit: April 20, 2011, 08:21:14 am by oliver »

April 20, 2011, 05:22:20 pm
(I'm trying gcc-3.4.6 atm and notice that your slightly older 3.3.6 still does have short-load-bytes? I'm using 3.4.6 as that's the oldest version my cross-tools in gentoo would build normally :)

I however are bumping into other fun asm. errors :)

arm-softfloat-linux-uclibc-gcc -D__KERNEL__ -I/silo/build/openipcam-oliver/linux-2.4.20/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -fno-common -pipe -fno-builtin -D__linux__ -DNO_MM -mapcs-32 -march=armv4 -mtune=arm7tdmi -msoft-float   -nostdinc -iwithprefix include -DKBUILD_BASENAME=exit  -c -o exit.o exit.c
{standard input}: Assembler messages:
{standard input}:149: Error: Rn must not overlap other operands -- `swp r0,r7,[r0]'

This was fixed with uClinux-2.4.20-uc1 BUT only for asm-arm, not asm-armnommu. Copying those changes makes the build work on 3.4.6!!

http://cvs.uclinux.org/cgi-bin/cvsweb.cgi/uClinux-2.4.x/include/asm-arm/proc-armv/system.h.diff?r1=1.1;r2=1.2