OpenWrt kernel loader for AR7XXX/AR9XXX

on PB44 type board with 16MB flash, I'm trying to use lzma compressed kernel but the redboot knows only gzip so I made a kernel using the lzma-loader but it fails with

OpenWrt kernel loader for AR7XXX/AR9XXX
Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
Looking for OpenWrt image... not found!

System halted!

the flash layout is like this

RedBoot> fis list
Name              FLASH addr  Mem addr    Length      Entry point
RedBoot           0xBF000000  0xBF000000  0x00040000  0x00000000
BootConfig        0xBF040000  0x80500000  0x00040000  0x00000000
BootConfigSave    0xBF080000  0x80500000  0x00040000  0x00000000
KernelA           0xBF0C0000  0x80060000  0x00200000  0x80060000
RootFsA           0xBF2C0000  0x80500000  0x004C0000  0x00000000
KernelB           0xBF780000  0x80060000  0x00180000  0x80070000
RootFsB           0xBF900000  0x80500000  0x00300000  0x00000000
rootfs_data       0xBFC00000  0x80500000  0x00340000  0x00000000
Test              0xBFF40000  0x80500000  0x00040000  0x00000000
FIS directory     0xBFF80000  0xBFF80000  0x0003F000  0x00000000
RedBoot config    0xBFFBF000  0xBFFBF000  0x00001000  0x00000000
Board data        0xBFFC0000  0xBFFC0000  0x00040000  0x00000000

in loader.c there is

#define AR71XX_FLASH_START      0x1f000000
#define AR71XX_FLASH_END        0x1fe00000

#define KSEG0                   0x80000000
#define KSEG1                   0xa0000000

the image creation

define Device/u4ea-fusion70
  ATH_SOC := ar7161
  DEVICE_TITLE := U4EA FUSION 70
  LOADER_FLASH_OFFS := 0x22000
  LOADER_TYPE := gz
  COMPILE := loader-$(1).gz
  COMPILE/loader-$(1).gz := loader-okli-compile
#  KERNEL := kernel-bin | append-dtb | gzip
  KERNEL := kernel-bin | append-dtb | lzma | uImage lzma -M 0x4f4b4c49 | loader-okli $(1) 15288
  KERNEL_INITRAMFS := kernel-bin | append-dtb | gzip
#  IMAGES := sysupgrade.bin
#  IMAGE/sysupgrade.bin := append-rootfs | append-metadata
  DEVICE_PACKAGES := vsc7385-ucode-pb44 vsc7395-ucode-pb44
  SUPPORTED_DEVICES += u4ea,fusion70
endef
TARGET_DEVICES += u4ea-fusion70

should it help if I change the AR71XX_FLASH_START and AR71XX_FLASH_END to BF000000 and BFC00000 ? I'm using the KernelB region. I could resize the partition and use the gzipped kernel but I would like to use the lzma one if possible

Does replacing "fis load -d" with "fis load -l" as described on the PB44 wiki page not work?

nope, the bootloader is crippled, only gzip is supported

AR71XX_FLASH_START and AR71XX_FLASH_END are KSEG1 addresses, by the way. What does the FIS map look like after "fis init" is done?

Sorry for necropost.

@lucize, did you solve your Looking for OpenWrt image... not found! problem?

If not, I could talk about what I learned when I played with the D-Link DIR-860L.

Hi @xabolcs I didn't, I saw your post in the mailing list and thinked about it.
atm the ap is in use, lucky it had enough flash space to use an uncompressed kernel, I could change the partitions from redboot but if I get the chance to work again on the ap I'll ask you about it
Thanks!

1 Like

Before I forget! :slight_smile:

Searching for the correct LOADER_FLASH_OFFS, you should do the following

  1. temporarily modify the recipe Build/loader-okli-compile:
    Edit FLASH_MAX=0 to a huge value, e.g. FLASH_MAX=0x0f000000

  2. temporarily edit #define CONFIG_FLASH_STEP 0x1000 in config.h to #define CONFIG_FLASH_STEP 0x1 (or 0x10) not to miss the OKLI signature

  3. optionally decrease your loader-okli $(1) 15288 parameter in KERNEL := to 4096 or 5120 to save some kB flash space.

  4. at first you should try LOADER_FLASH_OFFS := 0x0 and hope it finds the kernel in time! :smiley:
    If that doesn't work, lets keep it at 0x22000 or increase to 0x780000

When it finds an address, try to decompose it as I did on the ML!
For example, let the loader find the kernel image at 0xBF784567:

  • KSEG1ADDR is 0xa0000000
  • AR71XX_FLASH_START is 0x1f000000
  • KernelB region is at 0xBF780000 which is 0x00780000 away from KSEG1ADDR(AR71XX_FLASH_START)

So the remainder is 0x00004567.

Because the original FLASH_MAX=0 the CONFIG_FLASH_STEP's value doesn't matter.
So the LOADER_FLASH_OFFS consists of:

  • 0x00780000 (KernelB offset to KSEG1ADDR(AR71XX_FLASH_START))
  • and the remainder: 0x00004567
LOADER_FLASH_OFFS := 0x00784567

You have control over the remainder with loader-okli's second parameter: it just a pad-to.

For example, for D-Link DIR-860L, I have:

$ ls -l build_dir/target-mipsel_24kc_musl/linux-ramips_mt7621/loader-dlink_dir-860l-b1.*
-rwxr-xr-x 1 localuser localuser 5932 May  3 22:41 build_dir/target-mipsel_24kc_musl/linux-ramips_mt7621/loader-dlink_dir-860l-b1.bin
-rw-r--r-- 1 localuser localuser 3489 May  3 22:41 build_dir/target-mipsel_24kc_musl/linux-ramips_mt7621/loader-dlink_dir-860l-b1.lzma

DIR-860L accepts only lzma kernel, so I was able to use loader-okli $(1) 4096 for the lzma compressed loader.

But for TP-Link TL-1043ND v1 uses gzip compressed kernel, and:

$ ls -l build_dir/target-mips_24kc_musl/linux-ath79_generic/loader-tplink_tl-wr1043nd-v1.*
-rw-r--r-- 1 localuser localuser 4399 May  7 10:44 build_dir/target-mips_24kc_musl/linux-ath79_generic/loader-tplink_tl-wr1043nd-v1.gz

loader-okli $(1) 4096 would cause a 8192 offset because of the 4096 padding.
loader-okli offset have to be bigger than the compressed loader's size!
For example for this case, loader-okli $(1) 5120 would do the trick. (It's 7680 in Device/tplink-nolzma.)

Sadly there is no checking about this sizing, which (with FLASH_MAX=0) could lead to soft-bricking devices when the used loader image (.gz, .bin, etc ) size goes beyond that offset.

Once you have successfully flashed your router with an OKLI enabled image, boot it (for example with initramfs) and examine the flash, and search for the signature!
For that 1043nd:

[    0.371345] m25p80 spi0.0: s25sl064p (8192 Kbytes)
[    0.376224] 3 fixed-partitions partitions found on MTD device spi0.0
[    0.382698] Creating 3 MTD partitions on "spi0.0":
[    0.387547] 0x000000000000-0x000000020000 : "u-boot"
[    0.393713] 0x000000020000-0x0000007f0000 : "firmware"
[    0.403530] 2 tplink-fw partitions found on MTD device firmware
[    0.409569] Creating 2 MTD partitions on "firmware":
[    0.414579] 0x000000000000-0x0000001d2171 : "kernel"
[    0.420803] 0x0000001d2174-0x0000007d0000 : "rootfs"
[    0.426898] mtd: device 3 (rootfs) set to be root filesystem
[    0.434555] 1 squashfs-split partitions found on MTD device rootfs
[    0.440861] 0x000000400000-0x0000007d0000 : "rootfs_data"
[    0.447502] 0x0000007f0000-0x000000800000 : "art"

The firmware is at 0x000000020000, and the signature is at 0x00002000 inside that partition:

root@TL-WR1043ND-V1-57DC ~ $ hexdump -C /dev/mtd2|grep OKLI
00002000  4f 4b 4c 49 2d b5 0f ab  5e 5e dc 5f 00 1d 01 31  |OKLI-...^^._...1|
^C

That's why LOADER_FLASH_OFFS := 0x22000 in Device/tplink-nolzma.

Ahh, I had to delete those loaders at build_dir/target-*/linux-*/loader-* between rebuilds!

$ rm -v build_dir/target-*/linux-*/loader-*
removed 'build_dir/target-mips_24kc_musl/linux-ath79_generic/loader-tplink_tl-wr1043nd-v1.gz'
removed 'build_dir/target-mipsel_24kc_musl/linux-ramips_mt7621/loader-dlink_dir-860l-b1.bin'
removed 'build_dir/target-mipsel_24kc_musl/linux-ramips_mt7621/loader-dlink_dir-860l-b1.lzma'

Hope this helps. :+1:

2 Likes