# Understanding sysupgrade vs. mtd

**URL:** <https://forum.openwrt.org/t/understanding-sysupgrade-vs-mtd/59614>\
**Category:** Installing and Using OpenWrt\
**Created:** [April 5, 2020, 2:28pm UTC](https://forum.openwrt.org/t/understanding-sysupgrade-vs-mtd/59614 "2020-04-05T14:28:24Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![mbrijun](https://forum.openwrt.org/letter_avatar/mbrijun/32/5_5575768a8748004e209b776fc1b2916d.png) [@mbrijun](https://forum.openwrt.org/u/mbrijun)\
**Post date:** [April 5, 2020, 2:28pm UTC](https://forum.openwrt.org/t/understanding-sysupgrade-vs-mtd/59614/1 "2020-04-05T14:28:24Z")

</div>

Hi, on my TL-WR1043ND I have always used the "mtd" command to re-flash the router.

`mtd -r write /tmp/openwrt-18.06.4-ar71xx-generic-tl-wr1043nd-v1-squashfs-factory.bin firmware`

That worked nicely and reliably. On my new Linksys EA8500 router the MTD "partitions" (?) are set differently, and I can see neither "firmware" nor "linux". That leaves me with several questions:

1. What is the "mtd" way of flashing a Linksys EA8500?
2. If "sysupgrade" was to be used in this case, which "partition" would it flash?
3. Does "sysupgrade" rely on mtd at all? I was looking at that shell script, but could not find any references to "mtd".

Thank you.

```
root@OpenWrt:~# cat /proc/mtd
dev: size erasesize name
mtd0: 00040000 00020000 "SBL1"
mtd1: 00140000 00020000 "MIBIB"
mtd2: 00140000 00020000 "SBL2"
mtd3: 00280000 00020000 "SBL3"
mtd4: 00120000 00020000 "DDRCONFIG"
mtd5: 00120000 00020000 "SSD"
mtd6: 00280000 00020000 "TZ"
mtd7: 00280000 00020000 "RPM"
mtd8: 00140000 00020000 "art"
mtd9: 00100000 00020000 "APPSBL"
mtd10: 00040000 00020000 "u_env"
mtd11: 00040000 00020000 "s_env"
mtd12: 00040000 00020000 "devinfo"
mtd13: 02800000 00020000 "kernel1"
mtd14: 02500000 00020000 "rootfs1"
mtd15: 02800000 00020000 "kernel2"
mtd16: 02500000 00020000 "rootfs2"
mtd17: 02080000 00020000 "syscfg"

```

---

<div class="post-metadata">

**Author:** ![hnyman](https://forum.openwrt.org/user_avatar/forum.openwrt.org/hnyman/32/19_2.png) [@hnyman](https://forum.openwrt.org/u/hnyman)\
**Post date:** [April 5, 2020, 2:44pm UTC](https://forum.openwrt.org/t/understanding-sysupgrade-vs-mtd/59614/2 "2020-04-05T14:44:28Z")

</div>

mtd is a low-level flashing tool that could be directly used with the simplest old routers (like 1043) that had simple strucutre and unified kernel+rootfs image and no dual-booting.

With newer routers, with more complex flash structure, possibly dual-firmware features, and possible flashing kernel separately from the rootfs, using mtd directly is not possible.

> [@mbrijun](#):
>
> What is the "mtd" way of flashing a Linksys EA8500?

There is none.  
(or maybe: investigate the EA8500 sysupgrade steps, mimic them, and use mtd for those steps that it can do. And then do the other steps with other tools)

> [@mbrijun](#):
>
> If "sysupgrade" was to be used in this case, which "partition" would it flash?

(kernel1 and rootfs1) or (kernel2 and rootfs2), depending which partition is active (1 or 2). And then it would toggle the active partition marker in u-boot-env etc.

> [@mbrijun](#):
>
> Does "sysupgrade" rely on mtd at all?

For some routers, for the low-level flashing work. Depends on the target.

Summary for you:

- you can't use mtd directly with EA8500
- use sysupgrade

---

<div class="post-metadata">

**Author:** ![mbrijun](https://forum.openwrt.org/letter_avatar/mbrijun/32/5_5575768a8748004e209b776fc1b2916d.png) [@mbrijun](https://forum.openwrt.org/u/mbrijun)\
**Post date:** [April 6, 2020, 6:51pm UTC](https://forum.openwrt.org/t/understanding-sysupgrade-vs-mtd/59614/3 "2020-04-06T18:51:04Z")

</div>

> [@hnyman](#):
>
> There is none.  
> (or maybe: investigate the EA8500 sysupgrade steps, mimic them, and use mtd for those steps that it can do. And then do the other steps with other tools)

I had to bite the bullet and read the code... There is a shell script "/lib/upgrade/linksys.sh" which I think has the answer to my question. It turns out it checks the magic number of the image. If the magic number is "27051956", it performs an mtd flash of either "kernel1" or "kernel2" partition. If the image has the magic number of "73797375", then a more elaborate process takes place.

Any idea what "73797375" magic number represents? A google search returns nothing on this.

Thank you.

---

<div class="post-metadata">

**Author:** ![hnyman](https://forum.openwrt.org/user_avatar/forum.openwrt.org/hnyman/32/19_2.png) [@hnyman](https://forum.openwrt.org/u/hnyman)\
**Post date:** [April 6, 2020, 8:05pm UTC](https://forum.openwrt.org/t/understanding-sysupgrade-vs-mtd/59614/4 "2020-04-06T20:05:57Z")

</div>

> [@mbrijun](#):
>
> Any idea what "73797375" magic number represents?

"sysu" = First 4 letters from the word "sysupgrade"...  
Found at the beginning of the image, evaluated by /lib/upgrade/common.sh. Just a logic to see that it is a sysupgrade image.

If yes, then the nand\_upgrade\_tar routine in /lib/upgrade/nand.sh gets called to perform the actual upgrade (to write kernel and rootfs separately to the correct partitions, etc.). Note that the rootfs is ubifs formatted and needs to be written with ubifs tools.

---

<div class="post-metadata">

**Author:** ![mbrijun](https://forum.openwrt.org/letter_avatar/mbrijun/32/5_5575768a8748004e209b776fc1b2916d.png) [@mbrijun](https://forum.openwrt.org/u/mbrijun)\
**Post date:** [April 12, 2020, 9:52am UTC](https://forum.openwrt.org/t/understanding-sysupgrade-vs-mtd/59614/5 "2020-04-12T09:52:50Z")

</div>

Looking at the below function from linksys.sh, one part looks a little suspicious. "cur\_boot\_part" gets assigned a value, and that value is validated in the "if" statement. However, after the "if" statement, the value is reassigned again, this time without any checks. I am no shell scripting guru, but this does not look quite right to me.

```
linksys_get_target_firmware() {

	local cur_boot_part mtd_ubi0

	cur_boot_part=$(/usr/sbin/fw_printenv -n boot_part)
	if [-z "${cur_boot_part}"] ; then
		mtd_ubi0=$(cat /sys/devices/virtual/ubi/ubi0/mtd_num)
		case $(egrep ^mtd${mtd_ubi0}: /proc/mtd | cut -d '"' -f 2) in
		kernel1|rootfs1)
			cur_boot_part=1
			;;
		kernel2|rootfs2)
			cur_boot_part=2
			;;
		esac
		>&2 printf "Current boot_part='%s' selected from ubi0/mtd_num='%s'" \
			"${cur_boot_part}" "${mtd_ubi0}"
	fi

	cur_boot_part=`/usr/sbin/fw_printenv -n boot_part`

	case $cur_boot_part in
	1)
		fw_setenv -s - <<-EOF
			boot_part 2
			auto_recovery yes
		EOF
		printf "kernel2"
		return
		;;
	2)
		fw_setenv -s - <<-EOF
			boot_part 1
			auto_recovery yes
		EOF
		printf "kernel1"
		return
		;;
	*)
		return
		;;
	esac
}

```
