[Letux-kernel] X1600 / LX16 support - here: fw_getenv() issue - solved

H. Nikolaus Schaller hns at goldelico.com
Wed Feb 7 19:28:03 CET 2024



> Am 07.02.2024 um 16:55 schrieb H. Nikolaus Schaller <hns at goldelico.com>:
> 
> So it already gets damaged inside U-Boot before (*theKernel)()
> is called...

I think I have solved it.

The env pointers were ok right after boot_prep_linux() but damaged before boot_jump_linux().

Next, I recognised that do_bootm_linux() is called twice. Once with BOOTM_STATE_OS_PREP flag
and once with BOOTM_STATE_OS_GO:

https://git.goldelico.com/?p=letux-uboot.git;a=blob;f=arch/mips/lib/bootm.c;h=2c4233b77a5cbf3e3c9054fddd1b04517337dd79;hb=refs/heads/ingenic-x1600#l155

This is the issue (a real bug in this U-Boot version):

boot_prep_linux() calls linux_params_init() which copies the command line args to the argv array and starts the env array right behind the arg array.
boot_jump_linux() has code if CONFIG_BOOTARGS_AUTO_MODIFY == 1 which does another linux_cmdline_set()
linux_cmdline_set() appends one entry to the argv array which overwrites the env

We have several options to disable this:
a) remove CONFIG_BOOTARGS_AUTO_MODIFY (which must have been enabled somewhere)
b) disable the CONFIG_BOOTARGS_MEM_* macros (if disabled there is no call to linux_cmdline_set)
c) disable GD_FLG_ENV_DEFAULT
d) something else

First of all I had to understand what these macros are doing and if we should keep them.

It looks like a vendor hack to automatically pass memory size (based on (ulong)gd->ram_size) to the kernel command line (since FTD is likely not modified).
So we better should keep this mechanism to automatically handle x1600 vs. x1600e and other variants.

We should just fix overwriting the linux_env pointers. By leaving some room for it.

Or even better: move this code to linux_params_init() between creating the argv and before setting up an empty env.

I gave it a try and it seems to solve the basic issue! But opens a new one:

start_kernel: fw_arg1[0] 00000000
start_kernel: fw_arg1[1] a1f64400
start_kernel: fw_arg1[2] a1f64417
start_kernel: fw_arg1[3] a1f64418
start_kernel: fw_arg2[0] a1f64840
start_kernel: fw_arg2[1] a1f6484b
start_kernel: fw_arg2[2] a1f64863
start_kernel: fw_arg2[3] a1f64873
start_kernel: start
[    0.000000] Linux version 5.10.209-letux-lx16+ (hns at iMac.local) (mipsel-linux-gnu-gcc (GCC) 4.9.2, GNU ld (GNU Binutils) 2.25) #16449 PREEMPT Tue Feb 6 22:22:44 CET 2024
[    0.000000] printk: bootconsole [early0] enabled
[    0.000000] CPU0 revision is: 00d00000 (Ingenic XBurst)
[    0.000000] FPU revision is: 00b70000
[    0.000000] OF: fdt: No chosen node found, continuing without
[    0.000000] MIPS: machine is Letux LX16
[    0.000000] Reserved memory: created DMA memory pool at 0x02000000, size 32 MiB
[    0.000000] OF: reserved mem: initialized node reserved_mem at 0x2000000, compatible id shared-dma-pool
[    0.000000] Kernel sections are not in the memory maps
[    0.000000] Reserved memory: created DMA memory pool at 0x02000000, size 32 MiB
[    0.000000] OF: reserved mem: initialized node reserved_mem at 0x2000000, compatible id shared-dma-pool
[    0.000000] Wasting 512 bytes for tracking 16 unused pages
[    0.000000] Kernel panic - not syncing: early_init_dt_alloc_memory_arch: Failed to allocate 14491 bytes align=0x40

Well, it turned out that there was a real bug in linux_cmdline_set(). It did not write a new NULL pointer at the end and increment the pointers.

Now it works with 5.10 kernel:

[    0.000000] Linux version 5.10.209-letux-lx16+ (hns at iMac.local) (mipsel-linux-gnu-gcc (GCC) 4.9.2, GNU ld (GNU Binutils) 2.25) #16449 PREEMPT Tue Feb 6 22:22:44 CET 2024
[    0.000000] Kernel command line: console=ttyS2,115200n8  rootfstype=ext4 root=/dev/mmcblk0p2 rw mem=32M at 0x0

and 6.8-rc3:

U-Boot 2013.07-00325-g83d5c86f6f-dirty (Feb 07 2024 - 18:27:21)
...
[    0.000000] Linux version 6.8.0-rc3-letux-lx16+ (hns at iMac.local) (mipsel-linux-gnu-gcc (GCC) 6.3.0, GNU ld (GNU Binutils) 2.28.1) #16452 PREEMPT Wed Feb  7 14:17:22 CET 2024
[    0.000000] Kernel command line: console=ttyS2,115200n8  rootfstype=ext4 root=/dev/mmcblk0p2 rw mem=32M at 0x0 earlycon console=ttyS2,115200 clk_ignore_unused ignore_loglevel

And we can see that mem=32M at 0x0 is passed.

So I have pushed the code: https://git.goldelico.com/?p=letux-uboot.git;a=shortlog;h=refs/heads/ingenic-x1600
And pushed a new U-Boot binary: https://download.goldelico.com/letux-u-boot/Letux-X16/2024-02-07
Kenrel with reverted workaround: https://git.goldelico.com/?p=letux-kernel.git;a=shortlog;h=refs/heads/work-x1600-v2 

To install:
1. download the binary: wget / curl https://download.goldelico.com/letux-u-boot/Letux-X16/2024-02-07/u-boot-with-spl.bin
2. dd of=/dev/sdb seek=1 <u-boot-with-spl.bin  # specify the raw device and not the boot partition!

To restore old U-Boot replace 2024-02-07 by 2023-07-15.

BR,
Nikolaus



More information about the Letux-kernel mailing list