diff --git a/Readme.md b/Readme.md index 580b580..f011f74 100644 --- a/Readme.md +++ b/Readme.md @@ -1,4 +1,4 @@ -# Porting OpenWRT to a board with a supported SoC +# Porting OpenWrt to a board with a supported SoC ## Intro Recently, some network devices caught my attention both on Aliexpress and Alibaba. Specifically, I found some interesting outdoor equipment for a very low price, ranging between 10-25$. @@ -9,7 +9,7 @@ Recently, some network devices caught my attention both on Aliexpress and Alibab These are 2.4ghz AR9330 based boards, powered via POE (although on a non standard voltage), with two 10/100/1000 ethernet ports, an integrated antenna and a waterproof enclosure. I received the first one from Aliexpress but i plan to get some other to test as well. -[There's a video on YouTube of someone unpacking and reviewing it](https://www.youtube.com/watch?v=i3WUmMOqit0). It also show the OEM web interface. +[There's a video on YouTube of someone unpacking and reviewing it](https://www.youtube.com/watch?v=i3WUmMOqit0). It also shows the OEM web interface. ## Pictures ![Front](https://git.lsd.cat/g/openwrt-cpe46b/raw/master/images/front.jpg) @@ -61,7 +61,7 @@ Interactive mode ``` While upon collecting the user is dropped in a restriced pompt with few commands available, it is possible to inject commands in almost any of it via common shell separators `|;&`. -With the command injection is easy to understand that the device is already running a heavily customized OpenWRT fork, running on `Linux 2.6.31`. +With the command injection is easy to understand that the device is already running a heavily customized OpenWrt fork, running on `Linux 2.6.31`. ``` > iwconfig|uname -a @@ -113,7 +113,7 @@ VCED exceptions : not available VCEI exceptions : not available ``` -By knowing the size of each mtd partition, we get to know that it has a 8M flash chip. This makes sense given that the chip has written on it `25Q64`, where `64` is the size in Megabits. +By knowing the size of each mtd partition, we get to know that it has a 8MiB flash chip. This makes sense given that the chip has written on it `25Q64`, where `64` is the size in Megabits. Using `dd` it is possible to dump each partition, download it and even reasseble the full firmware image simply with `cat` afterwards. @@ -204,7 +204,7 @@ AP_CPU="ar9331" CPU_SPEED="400000000" #it must be xxMB(type) AP_MEMORY="64MB(S29GL064M)" -AP_FLASH="8MB(HY57V561620TP-H)" +AP_FLASH="8MiBB(HY57V561620TP-H)" #max power, dbm AP_MAX_POWER="15" PCB0="SX933146B" @@ -213,7 +213,7 @@ SUPPORT_AC_CURL_MGR="0" AP_SERIALNUMBER=001122334455 ``` -Note that the `64M` RAM value written there is wrong. This one has `32M` but it probably depends on the production batch. +Note that the `64MiB` RAM value written there is wrong. This one has `32MiB` but it probably depends on the production batch. The only thing actually existing, given that as of now the website shows a default page, is [their IANA assignment number](https://oidref.com/1.3.6.1.4.1.37260). @@ -223,6 +223,7 @@ The only thing actually existing, given that as of now the website shows a defau [The following istruction are recycled from this other guide](https://git.lsd.cat/g/thinkpad-coreboot-qubes/src/master/README.md). +_WARNING: The Raspberry VCC will five some power also to the SoC. This means that there might be interference given the unknown state of the SoC while wotking on the flash chip. In my case, that lead to some verifying errors after a write, but the write itself never failed._ ``` ______ @@ -256,6 +257,10 @@ From a root prompt on the Rpi ``` Check that all the checksums do match. In case they don't there's probably something wrong in the clip position or in the wiring. Remember that no pin should left floating even if it's not useful for the operation. /WP and /HOLD should be always connected to something like GND or VCC. +A working alternative is to use a CH341 USB. In this case, an external VCC source is needed. + +For more information about In-System Programming, [visit the flashrom wiki](https://www.flashrom.org/ISP). + ### Serial interface ![Serial](https://git.lsd.cat/g/openwrt-cpe46b/raw/master/images/serial.jpg) @@ -270,26 +275,26 @@ Common softwares for serial communication are `minicom` and `screen`. ## Porting ### Partition layout -The info learnet from `proc/mtd` are extremely useful. +The info learnt from `/proc/mtd` are extremely useful. - * `mtd0 u-boot` is a 64K partition which contains the u-boot bootloader - * `mtd1 u-boot-env` is a 64K partition containing the u-boot configuration + * `mtd0 u-boot` is a 64KiB partition which contains the u-boot bootloader + * `mtd1 u-boot-env` is a 64KiB partition containing the u-boot configuration * `mtd2 rootfs` is a jffs2 partition containing the actual image * `mtd3 uImage` is a squashfs kernel image * `mtd4 rootfs1` is a jffs2 partition containing a secondary image, probably used for recovery - * `mtd5 NVRAM` is a 64K partition which contains a `tgz` for OEM system configuration files - * `mtd6 ART` is a 64K partition [that contains calibration data for the radio chip](https://github.com/pepe2k/ar9300_eeprom) + * `mtd5 NVRAM` is a 64KiB partition which contains a `tgz` for OEM system configuration files + * `mtd6 ART` is a 64KiB partition [that contains calibration data for the radio chip](https://github.com/pepe2k/ar9300_eeprom) -The total size is of course 8192K. The partitions are not partitions in an EXT or NTFS sense. The data is just contiguos on the flash but the bootloader and the kernel are responsible for considering the different regions separate. +The total size is of course 8192KiB. The partitions are not partitions in an EXT or NTFS sense. The data is just contiguos on the flash but the bootloader and the kernel are responsible for considering the different regions separate. That's the reason because `cat` works and it is so simple to work with them. -Since for vanilla OpenWRT a custom partition for configuration is not needed, and two rootfs aren't useful and everything can be packed in a single partition with more space for packages and user data our target could be: +Since for vanilla OpenWrt a custom partition for configuration is not needed, and two rootfs aren't useful and everything can be packed in a single partition with more space for packages and user data our target could be: * `mtd0 u-boot` oeiginal image * `mtd1 u-boot-env` some values here needs to be modified - * `mtd2 firmware` 8000K OpenWRT partition (`firmware` is the standard OpenWRT naming) + * `mtd2 firmware` 8000K OpenWrt partition (`firmware` is the standard OpenWrt naming) * `mtd3 ART` original image @@ -357,8 +362,9 @@ CPE46B login: ``` -This confirms most of what we have got to know from the OEM firmware, 8M flash, 32M RAM, AR9330 SoC. Hornet is the codename for a [specific ALFA board](https://openwrt.org/toh/alfa_network/hornet-ub), and probably its target has been recycled for this U-Boot build. -U-Boot has the possibility to drop the user to an interactive command prompt if a key is hit on the early boot phase: +This confirms most of what we have got to know from the OEM firmware, 8MiB flash, 32MiB RAM, AR9330 SoC. Hornet is the codename for a [specific ALFA board](https://openwrt.org/toh/alfa_network/hornet-ub), and probably its target has been recycled for this U-Boot build. + +U-Boot has the possibility to drop the user to an interactive command prompt if a key is pressed on the early boot phase: ``` U-Boot 1.1.413 (Aug 29 2012 - 10:36:47) @@ -407,4 +413,70 @@ wd - check and set watchdog ar7240> ``` -_Note: `ar7240>` is probably there just because someone forgot to edit the prompt to the correct chipset name. It's just a static name and it is irrelevant. \ No newline at end of file +_Note: `ar7240>` is probably there just because someone forgot to edit the prompt to the correct chipset name. It's just a static name and it is irrelevant._ + + +The `printenv` prints out the current u-boot environment: + +``` +ar7240> printenv +bootargs0=console=ttyS0,115200 root=31:02 rootfstype=squashfs,jffs2 init=/bin/init mtdparts=ar7240-nor0:64k(u-boot),64k(u-boot-env),3456k(rootfs),1024K(uImage),3456k(rootfs1),64k(NVRAM),64k(ART) +bootcmd0=bootm 0x9f380000 +bootargs1=console=ttyS0,115200 root=31:04 rootfstype=squashfs,jffs2 init=/bin/init mtdparts=ar7240-nor0:64k(u-boot),64k(u-boot-env),3456k(rootfs),1024K(uImage),3456k(rootfs1),64k(NVRAM),64k(ART) +bootcmd1=bootm 0x9f380000 +baudrate=115200 +ethaddr=0x00:0xaa:0xbb:0xcc:0xdd:0xee +ethact=eth0 +filesize=27d000 +fileaddr=80060000 +ipaddr=192.168.0.144 +serverip=192.168.0.141 +bootparam=0 +bootdelay=4 +runver1=AWS-SX9331027-4.3.3 +runver0=OEM-SX933146B-4.3.7 +LANG=en +stdin=serial +stdout=serial +stderr=serial +ver=U-Boot 1.1.413 (Aug 29 2012 - 10:36:47) +bootargs=console=ttyS0,115200 root=31:02 rootfstype=squashfs,jffs2 init=/bin/init mtdparts=ar7240-nor0:64k(u-boot),64k(u-boot-env),3456k(rootfs),1024K(uImage),3456k(rootfs1),64k(NVRAM),64k(ART) +bootcmd=bootm 0x9f380000 + +Environment size: 978/65532 bytes +``` + +The same information can be obtained by running `strings` on the `mtd1` partition image. + +As seen above, the `bootargs` variable contains the serial console information, the partition scheme and the init information. So any change in the partition scheme must be reflected in this variable. +The other important value is `bootcmd`: it cointains the actual boot command. The address there is the starting address of the partition that contains the kernel image (with a `0x9f` prefix). + +So, given 0x0038000 which is `3670016/1024=3584KiB`. So by summing up the size of `mtd0`, `mtd1`, and `mtd2` the total should be the `mtd3` startign address: `64+64+3456=3584KiB`. + +So while we don't have our OpenWrt image yet, let's try to write the new variables for the new partition scheme described in the previous section: + +``` +bootargs=console=ttyS0,115200 root=31:02 rootfstype=squashfs,jffs2 init=/bin/init mtdparts=ar7240-nor0:64k(u-boot),64k(u-boot-env),8000k(firmware),64k(ART) +bootcmd=bootm 0x9f020000 +``` + +Where, `root=31:02` stands for the `mtd2` partition which is labelled `firmware`. The `boocmd` address is `0x0002000` which is 128KiB. `8000k` is the OpenWrt partition size. + +## Building OpenWrt +Adding a device target for an already supported SoC shouldn't be a difficult task. The OpenWrt wiki has some pages that help understand the process: + + * https://openwrt.org/docs/guide-developer/add.new.device + * https://openwrt.org/docs/guide-developer/defining-firmware-partitions + + + +## Acknowledgements + +`#openwrt-devel` on `irc.freenode.net` has been very helpful. The channel is well populated and people try to do their best to answer technical questions. + +A special thanks to _Paul Fertser_, (`PaulFertser` on `irc.freenode.net`) + +## Notes + +#### On the 0x9f bootcmd prefix +MIPS has different areas, called "kseg", some are cached, some are uncached and some are mapped somewhere, some are not. In this SoC there's a special integrated peripheral that knows how to read from SPI NOR memory and it provides the results in a memory-mapped way, that is, CPU can execute from it directly. I think 0x9f is one of the regions where it's mapped to (another common region is 0xbf). \ No newline at end of file