Skip to content

ramips: Fix root volume for tplink-er605-v2 #11715

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

mar-kolya
Copy link
Contributor

This device has two sets of volumes: main ones (kernel, rootfs, etc) and 'backup' (kernel.b, rootfs.b, etc). Bootloader tries to determine which set of volumes to use by looking at contens of extra-para and extra-para.b volumes. These volumes contain JSON that looks like this:

{
	"dbootFlag": "1",
	"integerFlag": "1",
	"fwFlag": "GOOD",
	"score":1
}

It looks like the bootloader looks for "fwFlag": "GOOD" (as opposed to BAD) then it compares score field - whichever 'good' volume has bigger score wins. This determines which set of volumes to use to boot.

So for example if extra-para is good and has bigger score then kernel, rootfs, etc volumes are used. This means bootloader needs to explain to the kernel which volume to use for the rootfs. After looking at bootloader code with disassembler I think it contains a bug. Relevant part of code looks something like this:

  if (image_id == 0) {
    rootfs_volume_id = 8;
    rootfs_volume_name = "rootfs";
  }
  else {
    rootfs_volume_id = 0xf;
    rootfs_volume_name = "rootfs.b";
  }
  sprintf(
    &buffer,
    0x800,
    "console=ttyS0,115200 noinitrd ubi.mtd=3,2048 ubi.block=0,%s
    root=/dev/ubiblock0_%d DKMGT_IMAGE_ID=%d DKMGT_IMAGE_TYPE=ubi",
    rootfs_volume_name,
    rootfs_volume_id,
    image_id
    );

Where image_id == 0 if 'normal' (not '*.b' set of volumes is used). However from device dumps we know that from the factory rootfs.b has id 8 and rootfs has id 15.

So from above we can see that ids and names of rootfs volumes do not match. More over - they are hardcoded in the bootloader.

Both things are problematic for OpwnWRT which completely removes volumes on update meaning that volume ids may actually change.

So instead of relying on bootloader to provide the kernel with root device this patch forces kernel to determine root automatically - and it defaults to rootfs volume which is correct for our purposes.

Overall this makes image boot fine from flash after sysupgrade from inirams. assuming extra-para* volumes make bootloader use non-'*.b' set of volumes.

Signed-off-by: Nikolay Martynov mar.kolya@gmail.com

@github-actions github-actions bot added the target/ramips pull request/issue for ramips target label Jan 7, 2023
@mar-kolya mar-kolya force-pushed the tp-link-er605-v2-fix-root-volume branch from 83a4c61 to 25121e9 Compare January 7, 2023 05:38
bootargs = "console=ttyS0,115200 noinitrd";
// Override bootargs because u-boot passes wrong root parameter.
// Instead allow kernel determine root automatically by looking for rootfs volume
bootargs-override = "console=ttyS0,115200 noinitrd ubi.mtd=3,2048";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also keep bootargs to override the default value in the mt7621.dtsi. 6361a95

bootargs = "console=ttyS0,57600";

bootargs-override = "console=ttyS0,115200 noinitrd ubi.mtd=3,2048";

Although this will not pass to the kernel, it can make the device tree more robust.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, thanks!

@mar-kolya mar-kolya force-pushed the tp-link-er605-v2-fix-root-volume branch from 25121e9 to 3b227da Compare January 7, 2023 15:31
@mar-kolya mar-kolya changed the title [ramips] Fix root volume for tplink-er605-v2 ramips: Fix root volume for tplink-er605-v2 Jan 9, 2023
@mar-kolya
Copy link
Contributor Author

@DragonBluep just a kind ping on this. Anything else that is missing here?

@@ -12,6 +12,9 @@

chosen {
bootargs = "console=ttyS0,115200 noinitrd";
// Override bootargs because u-boot passes wrong root parameter.
// Instead allow kernel determine root automatically by looking for rootfs volume
bootargs-override = "console=ttyS0,115200 noinitrd ubi.mtd=3,2048";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does the 2048 in ubi.mtd=3,2048" do?
Sorry I am not very familiar with this part of the kernel.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stock FW has this, as well as u-boot.
I think this the ubi header offset on the device. http://www.linux-mtd.infradead.org/faq/ubi.html has some information on this.

This device has two sets of volumes: main ones (`kernel`, `rootfs`, etc) and
'backup' (`kernel.b`, `rootfs.b`, etc). Bootloader tries to determine which set of
volumes to use by looking at contens of `extra-para` and `extra-para.b` volumes.
These volumes contain JSON that looks like this:

```
{
	"dbootFlag": "1",
	"integerFlag": "1",
	"fwFlag": "GOOD",
	"score":1
}
```

It looks like the bootloader looks for `"fwFlag": "GOOD"` (as opposed to `BAD`)
then it compares `score` field - whichever 'good' volume has bigger score wins.
This determines which set of volumes to use to boot.

So for example if `extra-para` is good and has bigger score then `kernel`,
`rootfs`, etc volumes are used. This means bootloader needs to explain to the
kernel which volume to use for the rootfs. After looking at bootloader code with
disassembler I think it contains a bug. Relevant part of code looks something
like this:

```
  if (image_id == 0) {
    rootfs_volume_id = 8;
    rootfs_volume_name = "rootfs";
  }
  else {
    rootfs_volume_id = 0xf;
    rootfs_volume_name = "rootfs.b";
  }
  sprintf(
    &buffer,
    0x800,
    "console=ttyS0,115200 noinitrd ubi.mtd=3,2048 ubi.block=0,%s
    root=/dev/ubiblock0_%d DKMGT_IMAGE_ID=%d DKMGT_IMAGE_TYPE=ubi",
    rootfs_volume_name,
    rootfs_volume_id,
    image_id
    );
```

Where `image_id == 0` if 'normal' (not '*.b' set of volumes is used).
However from device dumps we know that from the factory `rootfs.b` has id 8 and
`rootfs` has id 15.

So from above we can see that ids and names of rootfs volumes do not match. More
over - they are hardcoded in the bootloader.

Both things are problematic for OpwnWRT which completely removes volumes on
update meaning that volume ids may actually change.

So instead of relying on bootloader to provide the kernel with root device this
patch forces kernel to determine root automatically - and it defaults to
`rootfs` volume which is correct for our purposes.

Overall this makes image boot fine from flash after sysupgrade from inirams.
assuming `extra-para*` volumes make bootloader use non-'*.b' set of volumes.

Signed-off-by: Nikolay Martynov <mar.kolya@gmail.com>
@hauke hauke force-pushed the tp-link-er605-v2-fix-root-volume branch from 3b227da to 62dbcb8 Compare January 22, 2023 13:39
@openwrt-bot openwrt-bot merged commit 62dbcb8 into openwrt:master Jan 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
target/ramips pull request/issue for ramips target
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants