August 28, 2004

Building the Belkin F5D7230-4 GPL firmware

I did this with GPL-4-00-03.tgz. This are just the steps I took. You should read the whole thing to see if I was successful or if I destroyed my router. I do not recommend you use these steps! Proceed at your own risk! I am not liable for any damages to your router, your PC, your mind, the space-time fabric surrounding your residence or place of work, or anything else you can think of!

Unpacked the Belkin firmware tarball. cd GPL-4/src/linux; tar -jcf belkin-kernel-headers.tar.bz2 linux/include. This is your kernel header tarball, used in making the toolchain.

Also, before we get too far, let me plug ccache again. I’ve screwed this up a few times and had to rebuild everything. ccache has saved a lot of time. The uClibc toolchain building stuff will automatically build ccache and set up the default compiler(s) in bin to use it.

Checked out Edited the make/ file to use the snapshot instead of the latest release (0.9.26, which the same file warns against using). Edited make/, changed VERSION, PATCHLEVEL, and SUBLEVEL to match what’s in the Belkin firmware’s kernel sources; also changed LINUX_SOURCE to the tarball of kernel headers we created above from the Belkin kernel sources. Edited make/ and changed references to things like $(STAGING_DIR)/usr/lib/gcc-lib/$(REAL_GNU_TARGET_NAME)/$(GCC_VERSION)/specs to elide the /usr portion of that path; I think there are four of these changes. (Sorry if that’s vague; you can try building and you’ll get the staging dir specs file is missing, then poke around a bit and find out where the staging files really are.) mkdir -p sources/dl and copy the belkin-kernel-headers.tar.bz2 file into sources/dl. One more note: I think I disabled C++ somewhere. Generally poke through the top level Makefile for settings you might want to change. Build the toolchain with make. It ended up in /home/darkness/tmp/toolchain/gcc-3.3.x/toolchain_mipsel_nofpu.

cd GPL-4/src and edited the definition for PATH in Makefile to include the toolchain (as above). ln -s router router_belkin. Edited router/Makefile to change export CROSS_COMPILE := mipsel-uclibc- to mipsel-linux-uclibc- since that’s what the uClibc toolchain scripts built. Back in the src directory, I cp linux/linux/{default_belkin,.config} in hopes of using the default_belkin kernel configuration. Copy libc.a from the mipsel cross toolchain you built into router/lib/mipsel/. Now, make belkin. I got an error like:

mipsel-linux-uclibc-gcc -D_linux_=1 -DHAVE_PATHS_H -DHAVE_MMAP 
-I. -I../pppd -O2 -pipe -Wall -I/home/darkness/tmp/GPL-4/src/include 
-c -o pppoe.o pppoe.c
pppoe.c:136:28: missing terminating " character
pppoe.c:137:52: missing terminating " character

I find a string broken across two lines in router/ppp/pppoecd/pppoe.c. Join the two lines and restart make belkin. Then I get another error in router/vlan/vconfig.c of the same nature. Find something like and decide that multi-line literals are gone. Also see which tells us to stick n at the end of the lines inside the string. So I do this and restart make belkin again.

When it gets to the kernel compile you’ll probably get something like cc1: error: invalid option `cpu=r4600'. Reading we get the impression that -mcpu is no longer valid. So we need to find the section for CONFIG_CPU_MIPS32 in arch/mips/Makefile and remove -mcpu=r4600 from GCCFLAGS. Time for make belkin again. Later you’ll have this same problem with pmon, so make roughly the same change in pmon/GNUmakefile.

You might get an error like /home/darkness/tmp/GPL-4/src/include/bcmnvram.h:21:1: "INLINE" redefined. I chose to comment out the INLINE definition in this file. I also got a few errors like /home/darkness/tmp/GPL-4/src/cfe/cfe/arch/mips/common/src/disasm.c:1791: warning: integer constant is too large for "long" type. For this I went and found the offending constant and jammed ULL (unsigned long long… I hope) on the end. This shut up gcc with -Werror.

Got a few more errors on lines that look like (uint32)sbr &= ~(1 which I changed to sbr = (uint32*) (((uint32)sbr) & ~(1 , these both in shared/sbutils.c. In shared/bcmutils.c I got a bitch about line 635, *tptr = *((ulong *)pdata)++, as warning: use of cast expressions as lvalues is deprecated. I changed this to:

ulong *pdata_ulong = (ulong*)pdata;
*tptr = *pdata_ulong++;

At this point, I am wondering if I really want to use the firmware that will result from this process.

In cfe/cfe/lib/lib_qsort.c I hit the same error. I changed the whole offending section to look like:

    for (i = sizeof(int); i 

I think this makes it more readable, anyway.

In cfe/cfe/include/cfe_bootblock.h look for the constants around BOOT_MAGIC_NUMBER and slap ULL at the end again. Lather, rinse, repeat with warnings in cfe/cfe/ui/ui_examcmds.c. At this point I am once again tempted to remove -Werror from compile flags.

For fun, here's a patch between the original Belkin sources and my modified tree.

... Dear god, there are now what I believe to be firmware images built in GPL-4/image/belkin. I've tried to flash it to my router, though, and the web interface won't accept it. Nor will it accept the two firmwares linked on the F5D7230-4 page. This is the v1444 hardware, which may suck. I also wonder if newer firmwares keep you from flashing homegrown firmware.

What I'll be doing now is making a toolchain from the Linksys WRT54G firmware, then trying to build the Belkin firmware with that. I'm currently rebuilding the toolchain in the WRT54G firmware with the Belkin kernel headers. This is apparently important, since PPPoE is included by default in the Belkin firmware. I'm also installing the tools where they default to, in /opt/brcm.