Designing OpenWrt device from the (nearly) ground up

This isn't going to be a normal "Help with xxxxx device" threads..

The tl;dr: I've got hardware that needs to be reconfigured from the ground up as a proper OpenWrt device.

Backstory:
I jumped in on the Kickstarter for an Itus Networks iGuardian (then renamed Shield). I received it in 2015 and then promptly lost it. I found the box in 2019.

Found out Itus Networks went under in 2016. The OEM box was running a one-off OpenWrt.

Device Specs:
dual core OcteonIII CN7020 1.2 (1ghz), 1GB RAM, 4GB mmc storage (currently divided into 4 paritions.. 1 fat, 3 ext3). The device also has a SD card slot. 3 1000BaseT ethernet adapters and a RJ45 console port. The device runs uboot and is a 3 stage boot process.

I can get OpenWrt to run.. It runs VERY well.. But, the way Itus Networks seems to have shipped the device, and the way I copied in trying to fumble my way through this, doesn't seem viable to support.

From what I can tell:

octboot2.bin
u-boot-octeon_rhino_itus7x.bin

are my uboot files. The device has a 3 position GPIO switch on the front panel to select from three "modes"/images (Router/Gateway/Bridgfe) to load..

/dev/mmcblk1 <-- Main mmc
/dev/mmcblk1p1 <- FAT partition holding the bin files, including Openwrt's
These are ext3 extroot for the images..
/dev/mmcblk1p2 <- Router
/dev/mmcblk1p3 <- Gateway
/dev/mmcblk1p4 <- Bridge

The image OpenWrt creates is openwrt-octeon-itusrouter-initramfs-kernel.bin, which gets renamed to ItusrouterImage, etc before being loaded on /dev/mmcblk1p1

file output for image:

bin/targets/octeon/generic/openwrt-octeon-itusrouter-initramfs-kernel.bin: ELF 64-bit MSB executable, MIPS, MIPS64 rel2 version 1 (SYSV), statically linked, stripped

The image gets loaded and the init then pivots to the extroot

The custom init I had to put in target/linux/generic/other-files/

#!/bin/sh
# Copyright (C) 2006 OpenWrt.org
mount -t proc proc /proc
mount -t sysfs sys /sys
mount -t tmpfs dev /dev
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts

# Figure out what mode the Shield is in
# We need to determine what Mode the Shield is in - Time to query the GPIOs
GPIO=99
GPIO16=99
GPIO17=99

GPIO=16
echo ${GPIO} > /sys/class/gpio/export
echo in > /sys/class/gpio/gpio$GPIO/direction
GPIO16=$(cat /sys/class/gpio/gpio${GPIO}/value)
echo $GPIO > /sys/class/gpio/unexport

GPIO=17
echo $GPIO > /sys/class/gpio/export
echo in > /sys/class/gpio/gpio$GPIO/direction
GPIO17=$(cat /sys/class/gpio/gpio${GPIO}/value)
echo $GPIO > /sys/class/gpio/unexport

if [ $GPIO16 -eq 0 ]; then
   # Gateway Mode
   export SHIELD_MODE="Gateway"
   sys_ext=/sys/block/mmcblk1/mmcblk1p3
   dev_ext=/dev/mmcblk1p3
   dev_ext_major=179
   dev_ext_minor=3
else
   if [ $GPIO17 -eq 0 ]; then
      # Bridge Mode
      export SHIELD_MODE="Bridge"
      sys_ext=/sys/block/mmcblk1/mmcblk1p4
      dev_ext=/dev/mmcblk1p4
      dev_ext_major=179
      dev_ext_minor=4
   else
      # Router Mode
      export SHIELD_MODE="Router"
      sys_ext=/sys/block/mmcblk1/mmcblk1p2
      dev_ext=/dev/mmcblk1p2
      dev_ext_major=179
      dev_ext_minor=2
   fi
fi

extroot_dir=/extroot
count=0

while true
do
    if [[ ${count} -eq 25 ]]
    then
        echo "Timed out."; break
    fi

    if [ -d ${sys_ext} ]
    then
        echo "Found ${sys_ext} : ${count}"; break
    fi

    i=0
    marks='/ - \ |'
    if [ $# -lt 4 ]; then
      set -- "$@" $marks
    fi
      shift $(( (i+1) % $# ))
      printf 'Waiting for external root to mount: %s\r' "$1"
      sleep 1

    count=$((count+1))
done

if [ ! -b ${dev_ext} ]
then
    echo "Creating ${dev_ext}"; mknod ${dev_ext} b ${dev_ext_major} ${dev_ext_minor}
fi

mkdir ${extroot_dir}
mount ${dev_ext} ${extroot_dir} -o noatime

umount /sys
umount /proc
umount /dev/pts
umount /dev

count=0
while true
do
    if [ -e ${extroot_dir}/init ]
    then
	# Found an init, but is it ours?
	if [ -e ${extroot_dir}/.norwits ]
	then
	   echo ${SHIELD_MODE} > ${extroot_dir}/.mode
	   exec switch_root ${extroot_dir} /sbin/init
	else
	# Not our external rootfs!  Time to go bubye.
	# Remove everything, then wait for the next loop to populate with our stuff.
	   rm -rf ${extroot_dir}/*
        fi
    else
        # No init found - Setting up the extroot block
        echo "${extroot_dir}/init not found!  Setting up block device for initial boot."
	#Set up the call for firstboot.
	firstboot=1

        cp -a -f bin dev etc init lib lib64 mnt overlay proc rom root sbin sys tmp usr var www ${extroot_dir}
	sleep 5
        echo "# Empty File to validate correct block setup - DO NOT REMOVE" > ${extroot_dir}/.norwits
    fi

    i=0
    marks='/ - \ |'
    if [ $# -lt 4 ]; then
      set -- "$@" $marks
    fi
      shift $(( (i+1) % $# ))
      printf 'Waiting for external root to mount: %s\r' "$1"
      sleep 1


    count=$((count+1))

    if [[ ${count} -eq 5 ]]
    then
        echo "Timed out."; break
    fi
done

export INITRAMFS=1
exec /sbin/init

This essentially seems to treat the device as a Embedded LIVE CD. In this way, I can't update the kernel without replacing the BIN image, and trying to ensure everything that needs to be updates lib and dep wise on the extroot also get's copied.

I'm looking for ideas.. I'm looking for advice on how it should be done. The hardware is open.

So, for the really tech enthusists out there, what would you do? I know i can get it to work.. I have it working. I don't know enough to know if it's done properly or not.. Just that this is how Itus did it before they went bubye..

1 Like

While the goal is to emulate OEM operations closely, with setups that are non-common... or otherwise overly complex... one needs to question the payoff vs effort vs divergence ratios...

Personally, I'm not seeing the benefit of 3 rootfs parts... ( wonder if it has/had three kernels too... )...

I'd personally ignore the last two rootfs parts... then if you want to use the "toggle mode"... you could try this within init.d or similar... this would vastly simplify what has to be done at an imagebuilding/upgrade/backup etc. level... and help to ensure consistency.

1 Like

From what I can tell, the three 'modes' are all self-contained in their own ELF images, so yes they had their own kernels, libs, etc. Of course, it has it own partition, too. But, I am willing to live with that versus trying to build a new uBoot. If anything, I'm upset at the potentially wasted storage space rather than the potential for complicating the issue. Just think of it as three separate devices.

I initially started this with the same concerns you had @anon50098793. You can see from the init I was working towards a single image with the mode being software selectable

GPIO=17
echo $GPIO > /sys/class/gpio/export
echo in > /sys/class/gpio/gpio$GPIO/direction
GPIO17=$(cat /sys/class/gpio/gpio${GPIO}/value)
echo $GPIO > /sys/class/gpio/unexport

if [ $GPIO16 -eq 0 ]; then
   # Gateway Mode
   export SHIELD_MODE="Gateway"
   sys_ext=/sys/block/mmcblk1/mmcblk1p3
   dev_ext=/dev/mmcblk1p3
   dev_ext_major=179
   dev_ext_minor=3
else
   if [ $GPIO17 -eq 0 ]; then
      # Bridge Mode
      export SHIELD_MODE="Bridge"
      sys_ext=/sys/block/mmcblk1/mmcblk1p4
      dev_ext=/dev/mmcblk1p4
      dev_ext_major=179
      dev_ext_minor=4
   else
      # Router Mode
      export SHIELD_MODE="Router"
      sys_ext=/sys/block/mmcblk1/mmcblk1p2
      dev_ext=/dev/mmcblk1p2
      dev_ext_major=179
      dev_ext_minor=2
   fi
fi

uboot does this check during the stage2 boot in order to know which of the three images (ItusrouterImage, ItusgatewayImage, ItusbridgeImage) to load from the /dev/mmcblk1p1 FAT partition, I just was doing it in software as well.

while true
do
    if [ -e ${extroot_dir}/init ]
    then
	# Found an init, but is it ours?
	if [ -e ${extroot_dir}/.norwits ]
	then
	   echo ${SHIELD_MODE} > ${extroot_dir}/.mode
	   exec switch_root ${extroot_dir} /sbin/init
	else
	# Not our external rootfs!  Time to go bubye.
	# Remove everything, then wait for the next loop to populate with our stuff.
	   rm -rf ${extroot_dir}/*
        fi
    else
        # No init found - Setting up the extroot block
        echo "${extroot_dir}/init not found!  Setting up block device for initial boot."
	#Set up the call for firstboot.
	firstboot=1

        cp -a -f bin dev etc init lib lib64 mnt overlay proc rom root sbin sys tmp usr var www ${extroot_dir}
	sleep 5
        echo "# Empty File to validate correct block setup - DO NOT REMOVE" > ${extroot_dir}/.norwits
    fi

In this (again, probably not the right way), because the image is loaded into RAM during the stage3 boot, everything is memory resident. If I cannot find a keystone file I create (/.norwits), it wipes the partition clean and copies the Image contents over to the eMMC partition and then pivots to that partition.

Maybe I'm just not being selective enough in copying files to the extroot, or I'm not copying all of them?

I'm not set on any of the options or way it's being done, which is why I'm soliciting opinions :slight_smile:

Using it as dual-firmware (similar to the Linksys WRT*/ EA6350/ EA8300 or ZyXEL NBG6617/ NBG6817 devices) setup might be a nice feature, otherwise just ignore the other partitions.

I never understood why Itus tried to do three modes anyway.. Router and Bridge I understand, but Gateway was a stretch..

I guess technically I could put any mips64 ELF binary based OS in that third slot, if nothing else..

Ok.. So.. The question is: is the boot process the way it's supposed to be? Since there is no kernel on the /dev/mmcblk1px partitions, I'm guessing I'm not copying it over? I know there is no vmlinux on found on the partitions themselves..

Can you paste the U-Boot environment content and partition layout? It would reveal a lot about boot process.

I can see two approaches:

  • pick one partition and use it for OpenWrt, preserving triple boot
  • since you're basically dealing with old unmaintained OpenWrt, simply overwrite all three partitions and use them as one big rootfs

I'd go with the second option in this case. I did the same when porting OpenWrt to Fritzbox 7362.

OCTEON eMMC stage 1 bootloader

Partition: 1, start: 0x0000000000000800, size: 0x0000000000200001
Reading 470976 bytes.
................................................................................................................... Done.
Loaded OCTBOOT2BIN, size: 0x0000000000072FC0
Branching to stage 2 at: 0xFFFFFFFF81004000
Board TLV descriptor Read - RHino continues ... 2 board 0x4e26 major 1 minor 0, DDR HERTZ 0 hz
Rhino: early board init, mem_clk 0x29b ..

U-Boot 2013.07 (Development build, svnversion: u-boot:exported, exec:) (Build time: Mar 27 2015 - 10:49:38)

Initializing DRAM
U-Boot is not RAM-resident
Rhino: lookup_ddr_config_structure: cpu_id 890370 board_type 20006 ...
Rhino: cpu_id 0xd9602 board_type 0x4e26 major 0x1 minor 0x0  mask 1 ...
Initializing DDR, clock = 667000000hz, reference = 50000000hz
LMC0_DCLK_CNT: 0xffffffffffffffff
Measured DDR clock 666666652 Hz
Mem size in MBYTES: 1024
RHino: new Ram size 1024MiB (0x40000000)
Ram size 1024MiB (0x40000000)
Clearing memory from 0 to 1048576
Done clearing memory
CUST_PRIVATE_RHINO_ITUS7X board revision major:1, minor:0, serial #: 
OCTEON CN7020-AAP pass 1.2, Core clock: 1000 MHz, IO clock: 600 MHz, DDR clock: 667 MHz (1334 Mhz DDR)
Base DRAM address used by u-boot: 0x4f804000, size: 0x7fc000
DRAM: 1 GiB
Clearing DRAM.....Clearing base address: 0x100000, size: 0xff00000, ub_base: 0x4f804000, ub_size: 0x7fc000
Stack: 0xc03f5c60
Done clearing memory, ub_base: 0x4f804000
.Clearing base address: 0x20000000, size: 0x30000000, ub_base: 0x4f804000, ub_size: 0x7fc000
Stack: 0xc03f5c60
Done clearing memory, ub_base: 0x4f804000
 done
Using default environment

MMC:   Octeon MMC/SD0: 1
Hit any key to stop autoboot:  0 
reading u-boot-octeon_rhino_itus7x.bin
early_board_init: Early board init .................
Importing environment from RAM address 0x1000
RAM environment is 33 bytes

U-Boot 2013.07 (Development build, svnversion: u-boot:exported, exec:) (Build time: May 21 2015 - 11:11:49)

Initializing DRAM
U-Boot is RAM resident
Using DRAM size from environment: 1024 MBytes
DDR clock is 667 MHz
RHino: new Ram size 1024MiB (0x40000000)
Ram size 1024MiB (0x40000000)
Preserving environment in RAM
Done clearing memory
Configuring DLM0 for QSGMII
DLM1: mini-PCIe slots selected
CUST_PRIVATE_RHINO_ITUS7X board revision major:0, minor:1, serial #: 752011191521-36409
OCTEON CN7020-AAP pass 1.2, Core clock: 1000 MHz, IO clock: 600 MHz, DDR clock: 667 MHz (1334 Mhz DDR)
Base DRAM address used by u-boot: 0x4f000000, size: 0x1000000
DRAM: 1 GiB
Clearing DRAM.....Clearing base address: 0x100000, size: 0xff00000, ub_base: 0x4f000000, ub_size: 0x1000000
Stack: 0xc0f71c60
Done clearing memory, ub_base: 0x4f000000
.Clearing base address: 0x20000000, size: 0x30000000, ub_base: 0x4f000000, ub_size: 0x1000000
Stack: 0xc0f71c60
Done clearing memory, ub_base: 0x4f000000
 done
board_fixup_fdt: Found PCIe GPIO2 ..
MMC device not found, initializing
Octeon MMC/SD0: 1
*** Warning - bad CRC, using default environment

PCIe: Link timeout on port 0, probably the slot is empty
PCIe: Port 1 not in PCIe mode, skipping
PCIe: Port 2 not in PCIe mode, skipping
Net:   cvmx_helper_interface: interface 0
cvmx_helper_interface: interface 1
cvmx_helper_interface: interface 4
octeth0, octeth1, octeth2, octeth3
Type the command 'usb start' to scan for USB storage devices.

late_board_init ..
ITUS: SW1 1 Bridge (INNER) 
Hit any key to stop autoboot:  0 
mmc1(part 0) is current device
reading ItusbridgeImage
35862152 bytes read in 3450 ms (9.9 MiB/s)
argv[2]: mem=0
argv[3]: numcores=2
Allocating memory for ELF segment: addr: 0xffffffff80100000 (adjusted to: 0x100000), size 0x23b1e90
## Loading big-endian Linux kernel with entry point: 0xffffffff80696500 ...
Bootloader: Done loading app on coremask: 0x3
Starting cores:
 0x3

At this point, you can see it loads the ItusxxxxxxImage based on the Switch position, into RAM

Is there a way to let the .BIN image just live as a LiveCD RAM image and store the packages on the /dev/mmcblk1px so that when the BIN gets updated, it'll not kernel-panic because the libraries/files kept on the /dev/mmcblk1px are older than the kernel (in RAM) and blow up..

Can you type printenv in U-Boot console and paste the output?

1 Like

Stage 1

Octeon cust_private_rhino_itus7x# printenv
do_env_print ......
baudrate=115200
boardname=cust_private_rhino_itus7x
bootcmd=bootstage3
bootdelay=3
loadaddr=0x20000000
numcores=2
octeon_failsafe_mode=0
octeon_ram_mode=0
octeon_stage3_bootloader=u-boot-octeon_rhino_itus7x.bin
stderr=serial
stdin=serial
stdout=serial
ver=U-Boot 2013.07 (Development build, svnversion: u-boot:exported, exec:) (Build time: Mar 27 2015 - 10:49:38)

Environment size: 391/8188 bytes

Stage 2

Octeon cust_private_rhino_itus7x(ram)# printenv
do_env_print ......
autoload=n
baudrate=115200
bf=bootoct $(flash_unused_addr) forceboot numcores=$(numcores)
boardname=cust_private_rhino_itus7x
bootcmd=run image_run
bootdelay=2
bridge=mmc dev 1;fatload mmc 1 $(loadaddr) brigdeImage;bootoctlinux $(loadaddr) mem=0 numcores=2
burn_app=erase $(flash_unused_addr) +$(filesize);cp.b $(fileaddr) $(flash_unused_addr) $(filesize)
dram_size_mbytes=1024
eth1addr=2c:26:5f:80:04:a5
eth2addr=2c:26:5f:80:04:a6
eth3addr=2c:26:5f:80:04:a7
ethact=octeth0
ethaddr=2c:26:5f:80:04:a4
gateway=mmc dev 1;fatload mmc 1 $(loadaddr) gatewayImage;bootoctlinux $(loadaddr) mem=0 numcores=2
image_run=mmc dev 1;fatload mmc 1 $(loadaddr) ItusgatewayImage;bootoctlinux $(loadaddr) mem=0 numcores=2 serial#=$(serial#)
linux_mmc=fatload mmc 1 $(loadaddr) vmlinux.64;bootoctlinux $(loadaddr) mem=0 numcores=2
loadaddr=0x20000000
ls=fatls mmc 1
numcores=2
octeon_failsafe_mode=0
octeon_ram_mode=1
router=mmc dev 1; fatload mmc 1 $(loadaddr) routerImage;bootoctlinux $(loadaddr) mem=0 numcores=2
serial#=752011191521-36409
stderr=serial
stdin=serial
stdout=serial
ver=U-Boot 2013.07 (Development build, svnversion: u-boot:exported, exec:) (Build time: May 21 2015 - 11:11:49)

Environment size: 1234/8188 bytes

OK, what about: run ls, help bootoct, help bootoctlinux?

Also, is there source for U-Boot bootloaders in both stages?

1 Like

Marvell/Cavium has a uboot source tree on their Github (https://github.com/MarvellEmbeddedProcessors/u-boot-marvell), but that's as far as I've looked into it.

Octeon cust_private_rhino_itus7x(ram)# run ls
            restore/
 35862152   itusbridgeimage 
 17675032   itusgatewayimage 
 23543944   itusrestoreimage 
 102217544   itusrouterimage 
   470976   octboot2.bin 
  1138416   u-boot-octeon_rhino_itus7x.bin 
            updates/
 17810200   itusgatewayimage-working 
 102217544   itusrouter-rescue 

8 file(s), 2 dir(s)

Octeon cust_private_rhino_itus7x(ram)# help bootoct
bootoct - Boot from an Octeon Executive ELF image in memory

Usage:
bootoct  [elf_address [stack=stack_size] [heap=heap_size] [coremask=mask_to_run | numcores=core_cnt_to_run] [forceboot] [debug] [break.
elf_address - address of ELF image to load. defaults to $(loadaddr). If 0, default load address used.
stack       - size of stack in bytes.  Defaults to 1 megabyte
heap        - size of heap in bytes.  Defaults to 3 megabytes
coremask    - mask of cores to run on.  Anded with coremask_override environment
              variable to ensure only working cores are used
numcores    - number of cores to run on.  Runs on specified number of cores, taking into
              account the coremask_override.
skipcores   - only meaningful with numcores.  Skips this many cores (starting from 0) when
              loading the numcores cores. For example, setting skipcores to 1 will skip core 0
              and load the application starting at the next available core.
debug       - if present, bootloader passes debug flag to application which will cause
              the application to stop at a breakpoint on startup
break       - if present, exit program when control-c is received on the console
forceboot   - if set, boots application even if core 0 is not in mask
endbootargs - if set, bootloader does not process any further arguments and only passes
              the arguments that follow to the application.  If not set, the application
              gets the entire commnad line as arguments.
app name    - U-boot has no way of knowing the name of the application so this must be the first argument.


Octeon cust_private_rhino_itus7x(ram)# help bootoctlinux
bootoctlinux - Boot from a linux ELF image in memory

Usage:
bootoctlinux elf_address [coremask=mask_to_run | numcores=core_cnt_to_run] [forceboot] [skipcores=core_cnt_to_skip] [namedblock=name] ]
elf_address - address of ELF image to load. If 0, default load address
              is  used.
coremask    - mask of cores to run on.  Anded with coremask_override
              environment variable to ensure only working cores are used
numcores    - number of cores to run on.  Runs on specified number of cores,
              taking into account the coremask_override.
skipcores   - only meaningful with numcores.  Skips this many cores
              (starting from 0) when loading the numcores cores.
              For example, setting skipcores to 1 will skip core 0
              and load the application starting at the next available core.
forceboot   - if set, boots application even if core 0 is not in mask
namedblock      - specifies a named block to load the kernel
endbootargs - if set, bootloader does not process any further arguments and
              only passes the arguments that follow to the kernel.
              If not set, the kernel gets the entire commnad line as
              arguments.


Octeon cust_private_rhino_itus7x(ram)#
   470976   octboot2.bin 
  1138416   u-boot-octeon_rhino_itus7x.bin 

These the bootloaders..
the ItusxxxxxImage are the ELF-BIN self-contained images.

bin/targets/octeon/generic/openwrt-octeon-itusrouter-initramfs-kernel.bin gets SCP'd/TFTP'd to /dev/mmc1blk1 (which is what the run ls command showed) as one of the three filenames you see: ItusrouterImage ItusgatewayImage ItusbridgeImage, which is then selected depending on the front-panel GPIO switch

Thanks, I have the full picture of the boot process now.

If I understood correctly from the first post, you can build vanilla OpenWrt and it works fine? You just have a problem with fitting the boot process and sysupgrade into OpenWrt?

Yes, I think so. I can build out an master branch build and I've pieced together whatever Itus Networks did originally without really knowing exactly what I'm doing. I had to hack apart the target/linux/generic/other-files/init for a custom init to issue the switch_root. This is how Itus did it, so I copied it and cleaned it up some, but it's only there because that's how they did it back originally. If there is a better way, please show me how.

This device has less than 500 units ever made, I would suspect, so going for "Official" status isn't a priority. I do, however, want to get it working as best I can. I've just recently been able to get opkg working by building out with CONFIG_ALL and then putting the resulting bin/ tree on Github (https://github.com/Grommish/shield_opkgs) so I can pull it.

I'm hoping this makes sense to someone who is outside the chaos I've been swirling around with this build. But, again, please let me re-iterate: Whatever is going on with the build happened because something Itus did put it that way. I do not know if its correct, proper, or the best way to do it, so I came here with this rather ludicrous of trying to prep a device for OpenWrt rather than the other way around :rofl:

I appreciate all everyone has been able to do to help me, and by extension, the users who are going to be using it!

OK, here the thing: with the environment and the commands executed I can see that it's structured similar to RPi (its bootloader also needs kernel on first FAT partition on mmc).
I can explain what you can do to boot new OpenWrt, but I need to know what exactly is the "mmc" on this board? Is it embedded eMMC flash or a removable SD card with standard MBR partition table?

It is embedded eMMC, although it does have an SD Card slot for external loads I suppose, and a Console port (rollover RJ45) so I have kermit, and of course TFTP built into the U-Boot itself. Althought with the three mode slots, I can boot the device enough to get SCP abilities pretty much no matter what.

Here is the form-factor:

Can you try following: remove that patch, write kernel to the first (FAT32) partition with the same name as one of the stock kernels and write rootfs image to partition 2. Then add root=/dev/mmcblk0p2 to the kernel command line and try booting it from flash that way. Create ext4 image and dd it to partition 2, it will be easier that way for now.

I'm not sure what you are asking me to do :flushed:

This is what I get in my bin/target/octeon/generic directory:

total 29580
drwxr-xr-x 3 grommish grommish     4096 Jun 21 12:33 .
drwxr-xr-x 3 grommish grommish     4096 Jun 21 08:40 ..
-rw-r--r-- 1 grommish grommish     2197 Jun 21 15:13 config.buildinfo
-rw-r--r-- 1 grommish grommish      263 Jun 21 15:13 feeds.buildinfo
-rwxr-xr-x 1 grommish grommish 18281240 Jun 21 15:36 openwrt-octeon-itusrouter-initramfs-kernel.bin
-rw-r--r-- 1 grommish grommish     3814 Jun 21 15:36 openwrt-octeon-itusrouter.manifest
-rw-r--r-- 1 grommish grommish 11898880 Jun 21 15:36 openwrt-octeon-itusrouter-squashfs-sysupgrade.tar
drwxr-xr-x 2 grommish grommish    73728 Jun 21 15:35 packages
-rw-r--r-- 1 grommish grommish      579 Jun 21 15:38 sha256sums
-rw-r--r-- 1 grommish grommish       20 Jun 21 15:13 version.buildinfo

The openwrt-octeon-itusrouter-initramfs-kernel.bin file is what gets renamed to ItusxxxxxxImage and loaded onto the FAT partition /dev/mmcblk1p1. There is no separate kernel images, unless you are talking about what is inside the openwrt-octeon-itusrouter-squashfs-sysupgrade.tar

As far as the command line change, I currently have in my target/linux/octeon/image/Makefile:

ITUS_CMDLINE:=console=ttyS0,115200, rootfstype=squashfs,ext4 rootwait

So, I should change it to

ITUS_CMDLINE:=console=ttyS0,115200, rootfstype=squashfs,ext4 rootwait root=/dev/mmcblk1p2

Is this right?

  • Go to menuconfig and in Target Images enable ext4.
  • In target/linux/octeon/image/Makefile set rootfstype to ext4 only.
  • Build new image with make.
  • Extract sysupgrade.tar, there should be two files: non-initramfs kernel and rootfs image.
  • Replace one of ItusxxxxxxImage files with this kernel. Then scp rootfs image to the device and from the console on the device execute this: dd if=/path/to/rootfs.image of=/dev/mmcblk1p2; sync and reboot, don't forget to set the appropriate boot mode.

You should now have a working OpenWrt image on the device.

P.S. Replace the kernel image that actually uses p2 for the rootfs (so you can still use factory images which use other partitions), it should be the "Router" mode according to your first post, and write the rootfs from another boot mode (gateway or switch).

Fantastic! It works. Now I just need to figure out the upgrade system.

It seems instead of passing the root=/dev/mmcblk1px, they were delaying the init until the mmcblk1 came online and then did the switch_root.

This is certainly a much cleaner solution, especially from an upgrade stand point. With a "self-contained" kernel image, I don't have to worry about kmod/lib version mismatches.

What they did, I assume, is that they used kernel with initramfs and then they switch_root into the one on separate partition. This is not very OpenWrt-ish for production image, undo that patch in your tree if you haven't already, take a look at how the RPi is configured and do the same for your board (because RPi also uses MMC, FAT32 partition 1 for kernel and ext4 partition 2 for rootfs).

There might also be someone here who already worked on RPi or another MMC target who could give you more clues, I have worked only with "classical" flash-based OpenWrt boards.