Is it possible to use memmap or equiv to skip bad RAM with LEDE?

Having fun with my trashed router. Finally figured out how to use the bootloader to correctly test RAM and based on its output I have a small amount of bad memory. I am not a linux guru, but from some searching it looks like there is a memmap as a kernel parameter at least in some cases. Will LEDE use this (or anything else equiv) which will have the OS ignore a block of bad RAM?

Why not?

Openwrt and Lede use a default linux kernel and this should work...

memmap= n[KMG]@ start[KMG]
Force the kernel to use a specific memory region. n is the size of the memory location and startis the start location in memory of the range. Units can be kilobytes (K), megabytes (M), or gigabytes (G).

Are you familiar with adding additional params to cmd line?
Which router do you have?

That is a good way to learn about drivers.

Sure you should be able to write your own driver that reserves a physical block of memory and nothing else. Provided the bad block is in free memory to start with. Otherwise you will need to shuffle the kernel around first.
Something like this
https://unix.stackexchange.com/questions/37729/how-can-i-reserve-a-block-of-memory-from-the-linux-kernel

Great thanks for the tips. I haven't gone this far down the rabbit hole, but looks like both of these are good options. I will read up and do some damage.

It a WRT1900AC, which uses UBoot. I think I can add kernel params just in UBoot env config, but will have to school up a little.

Thanks all! I will report back if I "fix" this.

With mvebu being DTS based, you could more or less copy what the r7800 (ipq806x) is doing (for other reasons) to reserve memory:

https://github.com/openwrt/openwrt/blob/master/target/linux/ipq806x/files-4.9/arch/arm/boot/dts/qcom-ipq8065-r7800.dts#L14

1 Like

Thanks everyone. Lots of good options here. Starting with the memmap kernel param as it seems like it is the easiest. To me from here https://www.cyberciti.biz/howto/question/static/linux-kernel-parameters.php. It looks like the "$" variation is what I want from memmap. Basically for the kernel to skip it. Since my bad mem in is the 62nd Meg. I have this append to the kernel parameters via u-boot

memmap=1M$62M

which I think should basically have the kernel skip from meg 62 to meg 63.

.. but I expected to see less memory by a Meg in LEDE but I don't. Entirely possible I am not understanding how this works. Is this what you guys would expect? These are dmesg snippets with kernel command line and some mem setup. /proc/meminfo looks about the same too.

dmesg without the memmap (stock)

[    0.000000] Kernel command line: console=ttyS0,115200 mtdparts=armada-nand:1024K(uboot)ro,256K(u_env),256K(s_env),1m@9m(devinfo),40m@10m(kernel),37m@13m(rootfs),40m@50m(alt_kernel),37m@53m(alt_rootfs),80m@10m(ubifs),-@90m(syscfg) root=/dev/mtdblock5 ro rootfstype=jffs2 init=/sbin/init
[    0.000000] PID hash table entries: 1024 (order: 0, 4096 bytes)
[    0.000000] Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
[    0.000000] Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
[    0.000000] Memory: 253448K/262144K available (4752K kernel code, 189K rwdata, 696K rodata, 268K init, 302K bss, 8696K reserved, 0K cma-reserved, 0K highmem)

dmesg with memmap=1M$62M

[    0.000000] Kernel command line: console=ttyS0,115200 mtdparts=armada-nand:1024K(uboot)ro,256K(u_env),256K(s_env),1m@9m(devinfo),40m@10m(kernel),37m@13m(rootfs),40m@50m(alt_kernel),37m@53m(alt_rootfs),80m@10m(ubifs),-@90m(syscfg) root=/dev/mtdblock5 ro rootfstype=jffs2 init=/sbin/init memmap=1M$62M
[    0.000000] PID hash table entries: 1024 (order: 0, 4096 bytes)
[    0.000000] Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
[    0.000000] Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
[    0.000000] Memory: 253448K/262144K available (4752K kernel code, 189K rwdata, 696K rodata, 268K init, 302K bss, 8696K reserved, 0K cma-reserved, 0K highmem)

If you look at kernel-parameters, it says this specific option with $ requires that this is a cmdline param and acpi support is enabled...

I think there is no acpi support on wrt1900ac...

You should try option with dt from @slh.

Edit: Now i see your cmdline from dmesg output... Think the following answer is helpless...

POSSIBLY HELPLESS ANSWER:

I think the bootargs from bl are ignored from kernel, check cat /proc/cmdline

There are generally three way how one could set the cmdline...

  1. Bootloader
  2. Device Tree
  3. CONFIG_CMDLINE

Possibly there could be also other ways that i don´t know...

Your device has all needed source for your device mainline and i think it is set through device tree...
armada-xp-linksys-mamba.dts
Look at this part choosen { bootargs = "console=ttyS0,115200"; .... }

You could create a patch file that modifies dt or you can enforce your own cmd line if you set CONFIG_CMDLINE and CONFIG_CMDLINE_OVERRIDE in the kernel configuration (make kernel_menuconfig), but you had to set console, mtd parts and possibly others too...

I would choose to modify the device tree, because this would be the easiest one...

Hmm... interesting on the acpi part. I didn't know that. I am not at home now but I will check when I get back. /proc/cmdline does show the memmap, but maybe it is just ignoring it and I will need to move on to DTS and or a driver. I'll keep you guys posted.

Ok. So I got pissed off at this router after it bricked itself again. I think bad enough I will have to reload the bootloader ... again. After a couple months of cool down time. I am going to take another hack at it.

Disclaimers first: I haven't compiled LEDE or even linux before, so there is that. I have done SW dev in the past so have basics of software control, but not with git so I may be missing some details on how to pull the source down.

Plan. I am planning to compile LEDE, hopefully the 17.04.4 version with only a modified DTS file to block off the bad memory as @slh has above. Ideally this will be exactly like the distributed verison of 17.04.4 LEDE with only the reserved memory change, but it will be ok if I have to install other packages after the fact. I pulled the source down using this guide https://openwrt.org/docs/guide-developer/quickstart-build-images. Theoretically I have 17.04.4 since I used that tag.

So first question. Where is armada-xp-linksys-mamba.dts for LEDE? This is the one I am pretty sure should be used for this WRT1900ACv1. I can find it in the linux 4.14 source in the link @juppin has above, however it is not in the 17.04.4 LEDE source as far as I can tell. I only find other linksys MVEBU variant DTS files here. https://github.com/lede-project/source/tree/v17.01.4/target/linux/mvebu/files/arch/arm/boot/dts.

You should take a look at this https://openwrt.org/docs/guide-developer/patches

The dts for your device is already included in mainline kernel source, so there is no need to include it in lede/openwrt source.

If you compile a image for your device then linux source code is downloaded, patched and compiled for your device.
The source code and the compiled stuff is then located in build_dir/target_xxx/linux-xxx/linux-4.14.x.
You could do modifications in this directory and compile again... But if you do a clean the source in build_dir is wiped and your modifications are gone.
Thats why you should get familiar with the above link and create a patch for your dts that is located in target/linux/xxx/patches-4.14/999-mamba-bad-memory-exclude.patch.

Thank you sir! I will go and read up on patches.

For your tests you could first only edit the file inside build_dir and if this work you can create a patch file...
But remember your changes because they are lost on a clean.