NGW100

AVR32 Linux Network Gateway

Introduction

The NGW100 is a small development board for the Atmel AVR32 AP7000 processor. It has two Ethernet ports, a USB device port, an SD/MMC card slot, a serial port, expansion headers, 8 MiB parallel Flash, 8 MiB serial Flash and 32 MiB SDRAM. It's schematic is available and it runs Linux. All in all it's a small, low-power, low-cost computer with open hardware and software.

Here I summarily describe various mods, procedures, experiments and other stuff related the NGW100. All can render the device non-functional and I only claim they work for me, I don't encourage anyone to try them.

Contents

Upgrading the firmware
Moving the serial console
Filesystem slimdown, boot speedup

Upgrading the firmware

Various procedures for upgrading the firmware are described here. The problem is they require you to either boot from a MMC card to write the flash memories, or use the UBoot bootloader to upgrade the root partition. This is cumbersome. Upgrading via UBoot also corrupts the flash (on my board).

I found that you don't need to boot from a separate device to upgrade the flash, you just have to remount the root partition read-only:

mount / -o remount,ro
mount /usr -o remount,ro  #remount the root and usr partitions read-only
cd /tmp
wget http://your-web-server/root.img  #download the root and usr partition images
wget http://your-web-server/usr.img   # from a web server (which you could set up in your LAN)
flash_eraseall /dev/mtd3                      #erase the usr partition
dd if=usr.img of=/dev/mtd3 bs=1056 #write it
flash_eraseall /dev/mtd1     #erase the root partition
# * no root now
dd if=root.img of=/dev/mtd1 bs=1024  #write it
reboot

This works for me and it might not work for you and it might brick your device, especially if you specify the wrong mtd numbers. It might be possible to debrick if the bootloader is left intact. Do at your own risk.

At the * mark, the root filesystem does not have a physical support anymore and you are relying on it being cached. It might be possible that dd and /dev/mtd1 are inaccessible. To prevent this one might:

rm usr.img
cp -r /dev .
mkdir bin
cp /bin/busybox bin
ln -s /bin/busybox bin/sh
cp /sbin/flash_eraseall .
chroot .

before erasing mtd1; you could then access dd as busybox dd from the new root which is a tmpfs:

./flash_eraseall /dev/mtd1
busybox dd if=root.img of=/dev/mtd1 bs=1024

At the moment I have no idea if this is theoretically necessary or theoretically guaranteed to work.

Moving the serial console

The AP7000 has some 4 UARTs, of which one (USART1) is level-translated to the DE-9 connector. You might want to use the level-translated port to connect stuff to, so it's useful to not have the U-Boot and kernel messages there. At the same time it's useful to have a way to rescue the NGW in case you bork the filesystem etc. so it's useful to move the consoles over to USART0, which is located on the J5 expansion row. Then you could connect an external level-translator so you could rescue the board in case you screw up the kernel, sshd etc. (which I had to do). This assumes you lack an expensive JTAG tool.

First you need to modify the kernel.
In arch/avr32/boards/atngw100/setup.c, in setup_board(void), make USART0 ttyS0 and USART1 ttyS1 (USART1 was ttyS0 and USART0 was disabled):
    at32_map_usart(1, 1);    /* USART 1: /dev/ttyS1, DB9 */
    at32_map_usart(0, 0);    /* USART 0: /dev/ttyS0, J5: TXD-12, RXD-11 */
    at32_setup_serial_console(0);
In atngw100_init(void) both USARTs should be registered:
    at32_add_device_usart(0);
    at32_add_device_usart(1);
There. Now build, install and boot the new kernel and verify that it works as intended.

Now you have to update U-Boot. The U-Boot partition is locked and cannot be upgraded from Linux. To do that, you have to (again) recompile the kernel.
In arch/avr32/boards/atngw100/flash.c, in struct mtd_partition flash_parts[], comment the ".mask_flags = MTD_WRITEABLE," line. Now you can flash_eraseall and dd to the mtd0 boot partition just as you can with the mtd1 root partition. As a sidenote, you can do the same to the mtd2 environment partition to allow the fw_setenv tool to modify the U-Boot configuration from Linux.

The U-Boot modifications are as follows:
In include/configs/atngw100.h replace #define CONFIG_USART1 1 with #define CONFIG_USART0 1
Also replace CFG_PROMPT for amusement.
In board/atmel/atngw100/atngw100.c, in board_early_init_f(void):
portmux_enable_usart0(PORTMUX_DRIVE_MIN); instead of usart1.

Copy the resulting u-boot.bin to /tmp on the NGW and write it to flash like so:
flash_eraseall /dev/mtd0
dd if=/tmp/u-boot.bin of=/dev/mtd0 bs=1024
Caution, this can render the board non-functional.
Reboot and enjoy.

For future safety write-protect the mtd0 partition again.

This was done with linux-2.6.27.6 and u-boot-1.3.4 as configured and patched by the december 2008 www.atmel.no buildroot.

Appendix: level converter for the new serial port.

The NGW100 uses 3.3V for I/O and is not 5V-tolerant as far as I know. Therefore you can't use the classic MAX232 level shifter without some additional protection such as a series resistor and 3.3V zener on the RXD pin. The level-shifter on the DE-9 port uses a low-voltage variant of the MAX232 that works on 3.3V, but that can't be easily used as it's intended only for USART1. I used a FPGA board that also uses 3.3V I/O and has a similar converter and DE-9 connector, but is freely configurable. I connected the J5 pins from the NGW100 to some expansion connector on the FPGA board and routed the pins to the serial port. It's Overkill but it worked for a quick small rescue.

Filesystem slimdown, boot speedup

The NGW100 is a powerful, flexible system and it comes with a lot of software in its default configuration to prove the point. Unfortunately this also means it's very slow to boot. The first second is wasted with U-Boot waiting for space. TODO: make U-Boot give the prompt based on the currently unused "boot select" jumper, without waiting for keypresses.
Another piece of waste is mounting mtd3 (the serial flash). By slimming down the filesystem you can do away with that.
Getting an IP also takes unacceptably long; udhcpc seems to be standing around doing nothing for a second or two until it prints "sending discover...", after that it goes fast. TODO: investigate. If you don't want DHCP you can edit /etc/network/interfaces and say so, as well as /etc/resolv.conf.
The FTP and telnet servers are useless IMO.
The Samba server is equally useless IMO and porkly huge.
The only useful things are dnsmasq and the iptables NAT (it is after all a router), but I don't currently use it as a router. The ssh server is also useful, and httpd loads fast enough.
So cleaning up /etc/init.d/ is the first order of business. I dispensed with all the unnecessary daemons as stated above. Note, don't just kill stuff without understanding it first, it might make the board unusable.

Cleaning up the filesystems

Looking into /bin, /sbin, /usr/bin and /usr/sbin one can see many links to busybox and a few stand-alone executables. Delete the executables you don't need. Delete the contents of /www. Delete whatever.

Make a /usr0 directory and copy the directories in /usr to it. Unmount /usr. Move the stuff in /usr0 to /usr. Edit /etc/fstab to mount mtd3 on /media/slowflash or something, then comment the line out. Optionally erase /usr before unmounting it.
Note: you can't umount /usr while it's in use, you have to kill most of the processes. That needs to be done through the serial console because sshd is using /usr.

I managed to get less than 70% usage on /, no serflash mounted, and a 4-5 second load time. A 3 second load time should be possible with the TODOs solved.

Note, I did this all by hand just to see if it was possible, but the proper way is to make it into a buildroot script.