Friday, January 24, 2014

USBBooting Belkin F7D7301 (incomplete)

===================================
Warning: Please note that this is something I started documenting almost a year back, and then lost interest to make it complete for properly publishing to be usable for most. Whatever I documented are still applicable, and I have a working USB boot. But I do not plan to make the missing pieces of links complete on this topic. Publishing this as it is, in hope that it could be usable for somebody who is thinking in the same terms.

Warning: Not for non-tech users.
===================================


I have published earlier how to apply some custom patches and get OpenWrt working for Belkin F7D7301. I found a lot of interest from folks in updating the firmware, and due to the specific custom headers required for these TRX files, I believe it is a good idea to not update these TRXs often, if you are a guy experimenting with different kernels and versions. If you dont touch the trx, and only worry about the raw linux for the updates, you also dont need most of the custom patches addressing the trx stuff, and as long as you have got the networking drivers compiled, you got your router alive. F7D7301 on the heart is anyway a mips, so if you handle the drivers, you open the world for a lot of experimentation via USB and NFS or NBD roots.

Another big advantage for the folks who like to live on the edge are, in the case of a wrong kernel or firware update, going back is as simple as taking your usb drive out and changing the boot file.

Please note that most of the concepts mentioned here can be applied to other embedded devices or routers as well.

We have three options for getting the usb boot working.

a) Use a modified CFE to allow usbfs boot.
     Advantage: Uses least amount of flash/mtd, so if you are going to use USB loading, you dont depend on anything else in the flash other than CFE. You could still leave your stock firmware in flash or even have Tomoto/DDWrt in flash.
      Disadvantage: You mess up CFE, you brick the router really bad.

b) Use a second level boot loader using methods like kexec. Load this second level boot loader from CFE.  This options stands exactly between a and b. Uses and depends a bit more on flash than a custom CFE, but a lot less than a full OpenWrt Image on flash. You could still have stock firmware in flash, but might need some customizations.

c) Have a regular root squashfs image in flash and use a custom /etc/preinit script, to do the kexec loading.
     Advantage: Least risky for a regular user. Even in case of usb boot failure, you could boot the regular openwrt image from flash and business will be as before any usb booting.
    Disadvantage: You still depend on your squashfs image. So a flash corruption in this area still could break the USB boot. Also you read a full linux image from flash and mounts a full squashfs image from flash. Which means a lot of dependability on the flash, even though eventually you are keeping your experimental boot images in USB drive. But this is probably OK for most users.

I have tried all the above 3 methods, but found that option c is the least risky one and will be the most transparent one for any openwrt user.


The custom preinit script in squashfs.

If you are familiar with the openwrt boot process, you know the importance of /etc/preinit. This is the first script runs after mounting squashfs. I moved the /etc/preinit from squashfs to /etc/preinit.00, and put a custom init script in that place, so that I can do the USB booting or Network booting ealiest possible stage.  Here are the steps done by custom preinit.

1. Loads the required modules for USB and basic Networking.
2. mount tmpfs for all the work.
3. Initialize IP and try getting a boot script from an http server on LAN side.
4. If that succeds execute that init script (will get to the details of this init below)
5. If no network boot script try mounting USB read only using vfat or ext4.
6. See whether  USB has the boot init script at location /boot/
7. If it finds the boot script in USB, copy that over to tmpfs
8. unmount USB and execute that boot script (will get to details f this in below)
9. If no boot script was found from network or usb, then go proceed with squashfs preinit.
10. boot the openwrt in regular way via squshfs+jffs2.

Please note that you cannot modify the custom preinit script, since it is in squashfs filesystem, which is read only. But since you are loading your main boot script from either network or from USB you could modify them and experiment all you want without breaking the router.

Boot scripts for USB boot and Network boot

Note that you are not just looking to have your root file system in USB or Network, you also want your kernel to be in USB or Network.That way you dont depend on the version of kernel you have in your MTD/Flash of the router. The boot script is the one achiving this, and below are the functions.

1. Mount your USB or Network block device.
2. use kexec to load your new custom kernel from USB or network mount. (details of the customizations needed in kernel are explained below).
3. umount your USB or network device.
4. execute the custom kernel.

Now your custom kernel will take care of other stuff.

The custom Kernel Image for USB boot and Network boot

The custome Kernel Image does use a bigger initramfs. So the image is bigger. But it doesnt steal much memory, once you mount your root file system from USB, since the switch_root function does a good job of cleaning the initramfs from memory. Below are the functions of custom initramfs.

1. Initiramfs has a static busybox for doing all the required functions it need to do.
2. Load All the required modules for mouting your rootfs. For network root it will be the network drivers and nbd or nfs drivers. For USB root it will be your usb drivers. Also you need file system driversto be loaded. It could be vfat ext4 etc. You may also want loop driver.
3. Mount USB or NBD block device. If you keep the root files in a loopimage, mount that as well.
4. Now since the root is mounted, SwitchRoot to your root, and thereby cleaning up the memory used by initiramfs.

The customizations of preinit in USB root image.

I added some customizations in the USB/NBD root image preinit, so that I wont corrupt the jffs2 in flash. Also I chose to not use an overlay, since the USB root image is writable. So I commented out the boot hooks for jffs2 check and mount.

Your options.

1. You can just not use any of it and do something more useful :)
2. You can just flash the trx I compiled and have a regular openwrt image.
3. Following step 2, copy the usb-kernel and usb-root I compiled to your USB and have a USB boot.
4. Follow step 2 and 3. And then compile your own usb-kernel and usb-root.

Enough talk... Show me the example of USB Boot.

 1. Follow the steps here and flash the trx image.
 2. Format your USB drive to ext4/ext3/ext2 or vfat.
 3. Create a directory boot in your USB drive.
 4. Download and copy the below files to /boot/ of USB drive.
       a) Customized Kernel elf
       b) Cutomized root loop image
       c) USB boot script
 5. Unmount your USB drive from computer, and attach it to your F7D7301 router.
 6. You should be able to boot to USB loop image when you power cycle the router.

Friday, February 1, 2013

Update2 : OpenWrt on a Belkin Share Max N300 (F7D3301 or F7D7301)

Please refer to my old blog post for the details on the modifications. This is just an update from the earlier patches, and some of the content in earlier blog apply here as well.

As of rev@34995 (Jan 2013), the bgmac driver is officially supported in OpenWrt. This means now we dont have to apply George's patches to get the bgmac support anymore.

We still need the patches for
1. LZMA loader
2. Belkin custom TRX magic
3. Diag
4. Netconfig scripts.

I am posting a cleaner updated patch below, which applied perfectly on top of rev@35445. It should work without much pain on most other recent trunk versions as well.


Below are the exact steps to produce a trx file, which can be flashed via CFE.
1. Checkout openwrt (a specific version)
svn checkout --revision=35445 svn://svn.openwrt.org/openwrt/trunk
Other versions may work, but I have not tested any other version for these patches.

2.  Apply My custom patches
    Download from here: belkin.7301.r35445.patch
    cd trunk   
    patch -p1< belkin.7301.r35445.patch

3. make menuconfig    
    select Target System Broadcom BCM947xx/953xx
    select Target Profile Broadcom SoC, bgmac Ethernet, BCM43xx Wifi wl
    make

You will have the trx in the usual place after a successful compile.
Look for the file: bin/brcm47xx/openwrt-brcm47xx-f7d3301-squashfs.trx


Please note the below points if you flash the above trx.
1. default IP address at LAN side is 192.168.2.1
2. telnet can be accessed at default IP,



--------------------------------
Please note that I am trying to submit this patch to openwrt officially and get it supported. But it seems like there might be some work to clean it up for the likings of openwrt. Any of you folks are familiar with the process, please feel free to take the patch and submit it.
--------------------------------

Thursday, October 18, 2012

Update : OpenWrt on a Belkin Share Max N300 (F7D3301 or F7D7301)

Please refer to my old blog post for the details on the modifications. This is just an update from the earlier patches, and some of the content in earlier blog apply here as well.

Below are the exact steps to produce a trx file, which can be flashed via CFE.
1. Checkout openwrt (a specific version)
svn checkout --revision=33760 svn://svn.openwrt.org/openwrt/trunk
Other versions may work, but I have not tested any other version for these patches.

2.  Apply My custom patches and George's patches
    Download from here: 
000-openwrt4716-TARGET_brcm4716-clone-brcm47xx.patch
001-openwrt4716-TARGET_brcm4716.patch
002-openwrt4716-TARGET_brcm4716-deps.patch
004-f7d7301.r33760.patch


    patch -p1 < 000-openwrt4716-TARGET_brcm4716-clone-brcm47xx.patch
    patch -p1 < 001-openwrt4716-TARGET_brcm4716.patch
    patch -p1 < 002-openwrt4716-TARGET_brcm4716-deps.patch
    patch -p1 < 004-f7d7301.r33760.patch

3. make menuconfig     select Target System -> Broadcom BCM94716
     select Target Profile -> Belkin PlayMax F7D4301
     make

You will have the trx in the usual place after a successful compile.
Look for the file: bin/brcm4716/openwrt-brcm4716-f7d3301-squashfs.trx

For reference one trx I compiled is here : openwrt-brcm4716-f7d7301-squashfs-r33760.trx

Please note the below points if you flash the above trx.
1. default IP address at LAN side is 192.168.2.1
2. telnet can be accessed at default IP,
3. I have added a custom pre-init script to enable me do USB Booting. But it should not affect anything, if you dont do USB boot, except for a few more seconds boot time. I will add the details on how to do USB booting and publish the USB kernel modifications in another section.
For reference the custom preinit is here: /etc/preinit
4. For additional reference, the contents of the root file system : root-brcm4716.tar.gz

Suggestions are welcome, and I will try to learn from your suggestions. But please note that I dont have much time to spend on keeping the trx upto date with openwrt releases, or to add/delete packages or modules.


Wednesday, August 22, 2012

Yate-4.2 on Openwrt with Google Voice support

==================================
Update: August 22, 2012
Yate 4.2 is already out and so I updated the below instructions and updated the makefile. This time I also took some time to find the exact dependancies and added that in the makefile.


1. Goto your openwrt compile environment base directory.
2. mkdir package/yate4
3. Download Makefile.yate4.2 to package/yate4/Makefile
----
Note: if you dont have compiled openwrt in this directory, you might have to build the toolchain before the next step.
make tools/install
make toolchain/install
----
4. make package/yate4/compile
5. make package/yate4/install

==================================

Saturday, June 2, 2012

Yate-4.1 on Openwrt with Google Voice support

==================================

Update: August 22, 2012
Yate 4.2 is already out and so I updated the below instructions and adde a new Makefile. See the related blog on Yate 4.2 at the link below:

Yate-4.2 on Openwrt with Google Voice support


==================================
Puiblished: June 2, 2012

I had been using Yate4 for sometime and it is an excellent telephony application. As of this writing openwrt trunk only includes yate-3.2 and this limits some of the advancements in the application. I like a lot of things about yate, even though it may not be categorized as a replacement for asterisk. For a lot of folks, the excellent Google Voice support in yate, makes it a must have item in their embedded device running openwrt.

I will explain how to make yate 4.1working in openwrt. There are help pages available in openwrt for
1. how to create custom feeds
2. how to create a package
And they both explain a lot of detail on how you can achive getting custom feeds in clean way. So I am not planning to put a lot of effort on explaining those, and will focus on the core part, the makefile.

Also I will show you how to create an ipk file which you can install on your openwrt platform. The cleaner way of doing is create a custom feed and put yate4 package with the makefile in the custom feed.

Here is the makefile you can use for this purpose.
Makefile.yate

The steps to compile your own ipk is below. The pre-requisite for this is that you already have setup your openwrt compile environment, and know how to compile openwrt from source.

1. Goto your openwrt compile environment base directory.
2. mkdir package/yate
3. Download Makefile.yate to package/yate/Makefile
----
Note: if you dont have compiled openwrt in this directory, you might have to build the toolchain before the next step.
make tools/install
make toolchain/install
----
4. make package/yate/compile
5. make package/yate/install

You will have the yate4 ipk file under bin/packages
Now you can use opkg install yate4.ipk to install this package to your openwrt platform.

How to make google voice working. I was going to explain this detail here, and was documenting how I made it working. But I realized that now there is an excellent documenation in the official yate webpage.
Here is the link:  Yate4-ConnectingToGoogleVoice

Follow that link to make google voice working.

Note: For a handful of folks, who dont have an openwrt compile environment, and want to have an ipk, please post a comment with the exact router model you have (to know the cpu) and your kernel version. If I already have an ipk compatable for the model, I will share it with you. (please dont expect a reply if I dont have the ipk for you.)

Wednesday, May 16, 2012

OpenWrt on a Belkin Share Max N300 (F7D3301 or F7D7301)


Please see the update on thistopic at below link:
=====================================

=====================================


OpenWrt on a Belkin Share Max N300 (F7D3301 or F7D7301)

It was not a difficult job. Had to write a couple of patches to get it working. But a lot of work had been done by "George Kashperko" for Asus-RT-N16 . I took his patches, and applied some Belkin Specific patches.

The main modifications I made are:

1. Belkin trx headers: For some reason Belkin chose to use a custom header for trx. So modified the Makefiles to generate trx files with this custom header. Without this custom header Belkin CFE wont allow flashing the trx. And I preferred to not touch the CFE.

2. LZMA loader: Due to above modification, now I had to add some more code in the lzma decompressor and loader, to recognize the belkin headers. Without this the lzma loader will load, but wont boot, since it doest understand the new trx format.

3. Bridge setups. The virtual lan setup files needed some modification because of changes in port connections.

4. Diag and LED/GPIOs. Needed some modification to recognize the correct gpio pins and power/diag/usb leds.

Below are the exact steps to produce a trx file, which can be flashed via CFE.

1. Checkout openwrt (a specific version)
svn checkout --revision=30776 svn://svn.openwrt.org/openwrt/trunk

2.  Apply George's patches
    Download from here: 
000-openwrt4716-TARGET_brcm4716-clone-brcm47xx.patch
001-openwrt4716-TARGET_brcm4716.patch
002-openwrt4716-TARGET_brcm4716-deps.patch

    patch -p1 < 000-openwrt4716-TARGET_brcm4716-clone-brcm47xx.patch
    patch -p1 < 001-openwrt4716-TARGET_brcm4716.patch
    patch -p1 < 002-openwrt4716-TARGET_brcm4716-deps.patch

3. Apply my patch
   Download from here: 003-belkin-f7d3301.patch
   patch -p0 < 003-belkin-f7d3301.patch

4. make menuconfig
     select Target System -> Broadcom BCM94716
     select Target Profile -> Belkin PlayMax F7D4301
     make

You will have the trx in the usual place after a successful compile.
Look for the file: bin/brcm4716/openwrt-brcm4716-f7d3301-squashfs.trx

For reference one trx I compiled is here : openwrt-brcm4716-f7d7301-squashfs.trx
This is for reference ONLY. Even though I can see many users finding this good enough, I suggest you compile your own trx, when you see your needs are different. If you flash the above trx, you will have telnet access at 192.168.1.1 to your router.

You can install packages from openwrt trunk. But for that you have to addthe below lines to /etc/opkg.conf . Please dont install kernel modules from trunk snapshot, that may lead to kernel instability. But other packages should work without much issue. But as always, if something doesnt work from trunk snapshot, try compile that yourself using proper menuconfig.
#-------------
arch all 100
arch brcm4716 200
arch brcm47xx 300
#-------------

For details on opkg look here : opkg reference


Have fun...