OpenWrt/LEDE Project

  • Status Unconfirmed
  • Percent Complete
    0%
  • Task Type Bug Report
  • Category Kernel
  • Assigned To No-one
  • Operating System All
  • Severity Critical
  • Priority Very Low
  • Reported Version Trunk
  • Due in Version Undecided
  • Due Date Undecided
  • Private
Attached to Project: OpenWrt/LEDE Project
Opened by NotTheEvilOne - 20.04.2018

FS#1511 - Belkin F5D8235 v1 (most likely all rt288x devices) are broken on Linux 4.14

For kernel 4.9 the router boots correctly but on 4.14 the following panic occurs:

[    0.000000] Failed to request intc memory
[    0.000000] Kernel panic - not syncing: Failed to request resources for ralink,rt2880-sysc

Same happens when adding “syscon” to the compatible string.

Complete boot log:

   Image Name:   MIPS OpenWrt Linux-4.14.34
   Created:      2018-04-20   8:36:42 UTC

 System Control Status = 0x02910084
   Image Type:   MIPS Linux Kernel Image (lzma compressed)
   Data Size:    1443112 Bytes =  1.4 MB
   Load Address: 88000000
   Entry Point:  88000000
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK
No initrd
## Transferring control to Linux (at address 88000000) ...
## Giving linux memsize in MB, 32

Starting kernel ...

[    0.000000] Linux version 4.14.34 (fam-wolf@loki) (gcc version 7.3.0 (OpenWrt GCC 7.3.0 r6653-c0bbb9703f)) #0 Fri Apr 20 08:36:42 2018
[    0.000000] SoC Type: Ralink RT2880 id:2 rev:1
[    0.000000] bootconsole [early0] enabled
[    0.000000] CPU0 revision is: 0001906c (MIPS 4KEc)
[    0.000000] MIPS: machine is Belkin F5D8235 v1
[    0.000000] Determined physical RAM map:
[    0.000000]  memory: 02000000 @ 08000000 (usable)
[    0.000000] Wasting 1048576 bytes for tracking 32768 unused pages
[    0.000000] Initrd not found or empty - disabling initrd
[    0.000000] Primary instruction cache 16kB, VIPT, 4-way, linesize 16 bytes.
[    0.000000] Primary data cache 16kB, 4-way, VIPT, no aliases, linesize 16 bytes
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x0000000000000000-0x0000000009ffffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000000000000-0x0000000009ffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x0000000009ffffff]
[    0.000000] random: get_random_bytes called from start_kernel+0x8c/0x474 with crng_init=0
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 40640
[    0.000000] Kernel command line: console=ttyS0,57600 rootfstype=squashfs,jffs2
[    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: 25504K/163840K available (3325K kernel code, 166K rwdata, 804K rodata, 1200K init, 208K bss, 138336K reserved, 0K cma-reserved)
[    0.000000] SLUB: HWalign=16, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] NR_IRQS: 256
[    0.000000] Failed to request intc memory
[    0.000000] Kernel panic - not syncing: Failed to request resources for ralink,rt2880-sysc
[    0.000000] Rebooting in 1 seconds..
[    0.000000] Reboot failed -- System halted
NotTheEvilOne commented on 20.04.2018 17:43

Same happens on vanilla kernel with minimal patches applied btw.

Claudio Leite commented on 21.07.2018 12:13

I did a bisect on this last night and found that it broke when OpenWrt switched from 4.14.20 to 4.14.23. Upstream commit 67a3ba25aa955198196f40b76b329b3ab9ad415a is what caused this. The issue is in arch/mips/kernel/setup.c:

/*
 * Reserve any memory between the start of RAM and PHYS_OFFSET
 */
if (ramstart > PHYS_OFFSET)
	add_memory_region(PHYS_OFFSET, ramstart - PHYS_OFFSET,
			  BOOT_MEM_RESERVED);

Since RT2880's RAM starts at 0x8000000 and PHYS_OFFSET is 0 by default, this causes the kernel to add a phantom region of 0x0 - 0x8000000, hence the "163840K available" that it later reports.

Simply removing this bit of code results in a working system, but this is a hack.

From my naive interpretation it would seem that setting PHYS_OFFSET to 0x8000000 would be necessary, and indeed it does make the kernel boot. However, access to I/O devices like Ethernet and WiFi is then broken. I haven't wrapped my head around the various functions and macros that handle address translation so I don't know what the correct approach is.

I'm out of my depth here, so any advice would be welcome.

NotTheEvilOne commented on 23.07.2018 06:57

Thanks for sharing. Looking at the original upstream change [1] the reservation was moved from another function. Additionally the check was added before any constraints being checked like end ⇒ reserved_end. For me it looks like moving the code right the end of the loop may already make a difference (but this is just a guess):

	for (i = 0; i < boot_mem_map.nr_map; i++) {
		unsigned long start, end;

		if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
			continue;

		start = PFN_UP(boot_mem_map.map[i].addr);
		end = PFN_DOWN(boot_mem_map.map[i].addr
				+ boot_mem_map.map[i].size);

#ifndef CONFIG_HIGHMEM
		/*
		 * Skip highmem here so we get an accurate max_low_pfn if low
		 * memory stops short of high memory.
		 * If the region overlaps HIGHMEM_START, end is clipped so
		 * max_pfn excludes the highmem portion.
		 */
		if (start >= PFN_DOWN(HIGHMEM_START))
			continue;
		if (end > PFN_DOWN(HIGHMEM_START))
			end = PFN_DOWN(HIGHMEM_START);
#endif

		if (end > max_low_pfn)
			max_low_pfn = end;
		if (start < min_low_pfn)
			min_low_pfn = start;
		if (end <= reserved_end)
			continue;
#ifdef CONFIG_BLK_DEV_INITRD
		/* Skip zones before initrd and initrd itself */
		if (initrd_end && end <= (unsigned long)PFN_UP(__pa(initrd_end)))
			continue;
#endif

		ramstart = min(ramstart, boot_mem_map.map[i].addr);

		if (start >= mapstart)
			continue;
		mapstart = max(reserved_end, start);
	}

[1] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/arch/mips/kernel/setup.c?id=67a3ba25aa955198196f40b76b329b3ab9ad415a

NotTheEvilOne commented on 20.08.2018 09:43

After certain tries I got 4.14 to boot again on rt288x. Basically the commit Claudio Leite mentioned drops the prerequisite of a custom memory map to be defined by command line or other ways.

I'm still not sure if PHYS_OFFSET 0x0 is intended or if it should be 0x8000000 but requiring a custom memory map to be present breaks neither code without a custom map nor platforms without custom ones.

A PR [1] has been made.

[1] https://github.com/openwrt/openwrt/pull/1308

Loading...

Available keyboard shortcuts

Tasklist

Task Details

Task Editing