Skip to content

Instantly share code, notes, and snippets.

@rikka0w0
Last active December 20, 2024 10:39
Show Gist options
  • Save rikka0w0/4e4d5feb3a50a8b64224750140f859ef to your computer and use it in GitHub Desktop.
Save rikka0w0/4e4d5feb3a50a8b64224750140f859ef to your computer and use it in GitHub Desktop.
Port OpenWrt to CG3100D, a BCM3380-based device
[ 0.000000] Linux version 6.6.50 (rikka@i9-13900ks-wsl) (mips-openwrt-linux-musl-gcc (OpenWrt GCC 13.3.0 r27346-c7ba5574f5) 13.3.0, GNU ld (GNU Binutils) 2.42) #0 SMP Mon Oct 14 09:59:31 2024
[ 0.000000] CPU0 revision is: 0002a070 (Broadcom BMIPS4350)
[ 0.000000] MIPS: machine is Netgear CG3100D
[ 0.000000] 64MB of RAM installed
[ 0.000000] earlycon: bcm63xx_uart0 at MMIO 0x14e00200 (options '115200n8')
[ 0.000000] printk: bootconsole [bcm63xx_uart0] enabled
[ 0.000000] Initrd not found or empty - disabling initrd
[ 0.000000] Reserving 0KB of memory at 4194303KB for kdump
[ 0.000000] Primary instruction cache 64kB, VIPT, 4-way, linesize 16 bytes.
[ 0.000000] Primary data cache 32kB, 2-way, VIPT, cache aliases, linesize 16 bytes
[ 0.000000] Zone ranges:
[ 0.000000] Normal [mem 0x0000000000000000-0x0000000003ffffff]
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000000000000-0x0000000003ffffff]
[ 0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x0000000003ffffff]
[ 0.000000] percpu: Embedded 12 pages/cpu s17824 r8192 d23136 u49152
[ 0.000000] Kernel command line: earlycon
[ 0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes, linear)
[ 0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes, linear)
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 16240
[ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[ 0.000000] Memory: 43308K/65536K available (7814K kernel code, 625K rwdata, 1656K rodata, 11208K init, 216K bss, 22228K reserved, 0K cma-reserved)
[ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[ 0.000000] rcu: Hierarchical RCU implementation.
[ 0.000000] rcu: RCU restricting CPUs from NR_CPUS=2 to nr_cpu_ids=1.
[ 0.000000] Tracing variant of Tasks RCU enabled.
[ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
[ 0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1
[ 0.000000] NR_IRQS: 256
[ 0.000000] irq_bcm6345_l1: registered BCM6345 L1 intc (IRQs: 32)
[ 0.000000] irq_bcm6345_l1: CPU0 (irq = 2)
[ 0.000000] rcu: srcu_init: Setting srcu_struct sizes based on contention.
[ 0.000000] clocksource: MIPS: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 11479041721 ns
[ 0.000097] sched_clock: 32 bits at 167MHz, resolution 6ns, wraps every 12897800188ns
[ 0.021231] Calibrating delay loop... 3.81 BogoMIPS (lpj=19072)
[ 0.178158] pid_max: default: 32768 minimum: 301
[ 3.426684] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 3.438988] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 5.933756] RCU Tasks Trace: Setting shift to 0 and lim to 1 rcu_task_cb_adjust=1.
[ 5.996248] rcu: Hierarchical SRCU implementation.
[ 6.002894] rcu: Max phase no-delay instances is 1000.
[ 6.087436] smp: Bringing up secondary CPUs ...
[ 6.093834] smp: Brought up 1 node, 1 CPU
[ 6.481328] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[ 6.496408] futex hash table entries: 256 (order: 2, 16384 bytes, linear)
[ 8.025479] pinctrl core: initialized pinctrl subsystem
[ 8.580389] NET: Registered PF_NETLINK/PF_ROUTE protocol family
[ 11.467523] clocksource: Switched to clocksource MIPS
[ 14.998563] NET: Registered PF_INET protocol family
[ 15.053989] IP idents hash table entries: 2048 (order: 2, 16384 bytes, linear)
[ 15.233855] tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 4096 bytes, linear)
[ 15.251085] Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear)
[ 15.264278] TCP established hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 15.281537] TCP bind hash table entries: 1024 (order: 2, 16384 bytes, linear)
[ 15.300718] TCP: Hash tables configured (established 1024 bind 1024)
[ 15.324801] UDP hash table entries: 256 (order: 1, 8192 bytes, linear)
[ 15.340689] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes, linear)
[ 15.552395] NET: Registered PF_UNIX/PF_LOCAL protocol family
[ 15.573790] PCI: CLS 0 bytes, default 16
[ 17.151801] workingset: timestamp_bits=14 max_order=14 bucket_order=0
[ 17.690007] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[ 17.700059] jffs2: version 2.2 (NAND) (SUMMARY) (LZMA) (RTIME) (CMODE_PRIORITY) (c) 2001-2006 Red Hat, Inc.
[ 20.079119] 14e00200.serial: ttyS0 at MMIO 0x14e00200 (irq = 8, base_baud = 1500000) is a bcm63xx_uart
[ 20.096950] printk: console [ttyS0] enabled
[ 20.096950] printk: console [ttyS0] enabled
[ 20.109311] printk: bootconsole [bcm63xx_uart0] disabled
[ 20.109311] printk: bootconsole [bcm63xx_uart0] disabled
[ 21.319521] bcm7038-wdt 14e000dc.watchdog: Registered BCM7038 Watchdog
[ 21.748257] NET: Registered PF_INET6 protocol family
[ 22.634542] Segment Routing with IPv6
[ 22.663333] In-situ OAM (IOAM) with IPv6
[ 22.687276] NET: Registered PF_PACKET protocol family
[ 22.824685] 8021q: 802.1Q VLAN Support v1.8
[ 32.219484] clk: Disabling unused clocks
[ 57.398112] Freeing unused kernel image (initmem) memory: 11208K
[ 57.407595] This architecture does not have kernel memory protection.
[ 57.417385] Run /init as init process
[ 113.281875] init: Console is alive
[ 113.311606] init: - watchdog -
[ 115.514109] kmodloader: loading kernel modules from /etc/modules-boot.d/*
[ 117.331510] usbcore: registered new interface driver usbfs
[ 117.354463] usbcore: registered new interface driver hub
[ 117.371099] usbcore: registered new device driver usb
[ 117.880953] gpio_button_hotplug: loading out-of-tree module taints kernel.
[ 120.259649] kmodloader: done loading kernel modules from /etc/modules-boot.d/*
[ 120.447603] init: - preinit -
[ 154.392610] random: crng init done
[ 198.824496] procd: - early -
[ 198.851361] procd: - watchdog -
[ 203.941765] procd: - watchdog -
[ 204.141007] procd: - ubus -
[ 207.050985] procd: - init -
https://github.com/rikka0w0/openwrt-fast3864op/commit/95f3de5f6144de29e7b48f1d1e527159d3e3f0d4
[ 0.000000] Linux version 6.6.50 (rikka@i9-13900ks-wsl) (mips-openwrt-linux-musl-gcc (OpenWrt GCC 13.3.0 r27346-c7ba5574f5) 13.3.0, GNU ld (GNU Binutils) 2.42) #0 SMP Thu Oct 17 14:11:58 2024
[ 0.000000] CPU0 revision is: 0002a070 (Broadcom BMIPS4350)
[ 0.000000] MIPS: machine is Netgear CG3100D
[ 0.000000] 64MB of RAM installed
[ 0.000000] earlycon: bcm63xx_uart0 at MMIO 0x14e00200 (options '115200n8')
[ 0.000000] printk: bootconsole [bcm63xx_uart0] enabled
[ 0.000000] Initrd not found or empty - disabling initrd
[ 0.000000] Reserving 0KB of memory at 4194303KB for kdump
[ 0.000000] Primary instruction cache 64kB, VIPT, 4-way, linesize 16 bytes.
[ 0.000000] Primary data cache 32kB, 2-way, VIPT, cache aliases, linesize 16 bytes
[ 0.000000] Zone ranges:
[ 0.000000] Normal [mem 0x0000000000000000-0x0000000003ffffff]
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000000000000-0x0000000003ffffff]
[ 0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x0000000003ffffff]
[ 0.000000] percpu: Embedded 12 pages/cpu s17824 r8192 d23136 u49152
[ 0.000000] Kernel command line: earlycon
[ 0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes, linear)
[ 0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes, linear)
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 16240
[ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[ 0.000000] Memory: 43308K/65536K available (7814K kernel code, 625K rwdata, 1656K rodata, 11208K init, 216K bss, 22228K reserved, 0K cma-reserved)
[ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[ 0.000000] rcu: Hierarchical RCU implementation.
[ 0.000000] rcu: RCU restricting CPUs from NR_CPUS=2 to nr_cpu_ids=1.
[ 0.000000] Tracing variant of Tasks RCU enabled.
[ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
[ 0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1
[ 0.000000] NR_IRQS: 256
[ 0.000000] irq_bcm6345_l1: registered BCM6345 L1 intc (IRQs: 32)
[ 0.000000] irq_bcm6345_l1: CPU0 (irq = 4)
[ 0.000000] rcu: srcu_init: Setting srcu_struct sizes based on contention.
[ 0.000000] brcm,bcm3380 detected @ 333 MHz
[ 0.000000] clocksource: MIPS: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 11479041721 ns
[ 0.000002] sched_clock: 32 bits at 167MHz, resolution 6ns, wraps every 12897800188ns
[ 0.008283] Calibrating delay loop... 331.77 BogoMIPS (lpj=1658880)
[ 0.074656] pid_max: default: 32768 minimum: 301
[ 0.113091] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 0.120661] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 0.157019] RCU Tasks Trace: Setting shift to 0 and lim to 1 rcu_task_cb_adjust=1.
[ 0.165802] rcu: Hierarchical SRCU implementation.
[ 0.170706] rcu: Max phase no-delay instances is 1000.
[ 0.177507] smp: Bringing up secondary CPUs ...
[ 0.182145] smp: Brought up 1 node, 1 CPU
[ 0.191469] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[ 0.201716] futex hash table entries: 256 (order: 2, 16384 bytes, linear)
[ 0.224446] pinctrl core: initialized pinctrl subsystem
[ 0.235975] NET: Registered PF_NETLINK/PF_ROUTE protocol family
[ 0.276950] clocksource: Switched to clocksource MIPS
[ 0.316963] NET: Registered PF_INET protocol family
[ 0.322567] IP idents hash table entries: 2048 (order: 2, 16384 bytes, linear)
[ 0.332232] tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 4096 bytes, linear)
[ 0.340948] Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear)
[ 0.348951] TCP established hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 0.356847] TCP bind hash table entries: 1024 (order: 2, 16384 bytes, linear)
[ 0.364298] TCP: Hash tables configured (established 1024 bind 1024)
[ 0.371188] UDP hash table entries: 256 (order: 1, 8192 bytes, linear)
[ 0.378035] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes, linear)
[ 0.387439] NET: Registered PF_UNIX/PF_LOCAL protocol family
[ 0.393418] PCI: CLS 0 bytes, default 16
[ 0.427316] workingset: timestamp_bits=14 max_order=14 bucket_order=0
[ 0.439505] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[ 0.445501] jffs2: version 2.2 (NAND) (SUMMARY) (LZMA) (RTIME) (CMODE_PRIORITY) (c) 2001-2006 Red Hat, Inc.
[ 0.513240] 14e00200.serial: ttyS0 at MMIO 0x14e00200 (irq = 8, base_baud = 1500000) is a bcm63xx_uart
[ 0.523009] printk: console [ttyS0] enabled
[ 0.523009] printk: console [ttyS0] enabled
[ 0.530967] printk: bootconsole [bcm63xx_uart0] disabled
[ 0.530967] printk: bootconsole [bcm63xx_uart0] disabled
[ 0.572498] bcm7038-wdt 14e000dc.watchdog: Registered BCM7038 Watchdog
[ 0.583338] NET: Registered PF_INET6 protocol family
[ 0.620065] Segment Routing with IPv6
[ 0.623806] In-situ OAM (IOAM) with IPv6
[ 0.627900] NET: Registered PF_PACKET protocol family
[ 0.647379] 8021q: 802.1Q VLAN Support v1.8
[ 0.797473] clk: Disabling unused clocks
[ 1.149934] Freeing unused kernel image (initmem) memory: 11208K
[ 1.155669] This architecture does not have kernel memory protection.
[ 1.162119] Run /init as init process
[ 1.975558] init: Console is alive
[ 1.979796] init: - watchdog -
[ 2.014777] kmodloader: loading kernel modules from /etc/modules-boot.d/*
[ 2.053499] usbcore: registered new interface driver usbfs
[ 2.059035] usbcore: registered new interface driver hub
[ 2.064387] usbcore: registered new device driver usb
[ 2.077106] gpio_button_hotplug: loading out-of-tree module taints kernel.
[ 2.123838] kmodloader: done loading kernel modules from /etc/modules-boot.d/*
[ 2.141881] init: - preinit -
/bin/board_detect: /etc/board.d/01_leds: line 10: //: Permission denied
[ 5.246993] random: crng init done
/bin/board_detect: /etc/board.d/02_network: line 9: //: Permission denied
Press the [f] key and hit [enter] to enter failsafe mode
Press the [1], [2], [3] or [4] key and hit [enter] to select the debug level
[ 7.923716] procd: - early -
[ 7.927375] procd: - watchdog -
[ 8.516466] procd: - watchdog -
[ 8.521829] procd: - ubus -
[ 8.585200] procd: - init -
Please press Enter to activate this console.
[ 10.078447] kmodloader: loading kernel modules from /etc/modules.d/*
[ 10.387144] PPP generic driver version 2.4.2
[ 10.400700] NET: Registered PF_PPPOX protocol family
[ 10.441582] kmodloader: done loading kernel modules from /etc/modules.d/*
[ 13.887096] urngd: v1.0.2 started.

BCM3380 Product Brief

Netgear Open-Source

TC72XX_LxG1.7.1mp1_OpenSrc

BCM3380 CFE bootloader source

This is for BCM3383, but looks interesting

V5.5.4 of CG3000D / CG3100D / CG3101D / CG3000D-1CHNAS / CG3000D-1CXNAS / CG3100D-1DANDS may be interesting.

BCM3380 Registers

CG3100L_V1.0.4_Linux_src/shared/opensource/include/bcm963xx/3380_map_part.h contains the base address of some peripherals

CG3100L_V1.0.4_Linux_src/shared/broadcom/include/bcm963xx/3380_map.h contains a more complete list of base address, see line 244, 283.

CG3100L_V1.0.4_Linux_src/shared/opensource/include/bcm963xx/bcm_hwdefs.h contains some information about the address space:

/*****************************************************************************/
/* Note that the addresses above are physical addresses and that programs    */
/* have to use converted addresses defined below:                            */
/*****************************************************************************/
#define DRAM_BASE           (0x80000000 | PHYS_DRAM_BASE)   /* cached DRAM */
#define DRAM_BASE_NOCACHE   (0xA0000000 | PHYS_DRAM_BASE)   /* uncached DRAM */

DRAM_BASE_NOCACHE ors uart0: serial@14e00200 in U-boot dts gives #define UART_BASE 0xb4e00200. In the OpenWrt dts, the base addresses are partial.

May be we can contact this guy

Some very old Broadcom material

Note on periph_intc: interrupt-controller

There were examples of BCM6328.dtsi that uses "brcm,bcm3380-l2-intc" and "brcm,bcm6345-l1-intc". I tried "brcm,bcm3380-l2-intc" first but it doesnt work. When the bcm63xx-uart driver requests for an IRQ, the IRQ driver defers indefinitely (returns -EPROBE_DEFER, -517 everytime). I have to switch to "brcm,bcm6345-l1-intc".

By comparing the register definition of BCM6358 and its OpenWrt dtsi, I partially understand the usage of "brcm,bcm6345-l1-intc". Two question remains:

  1. Does the order of the two entries in reg matter? I found some code describes the ISR dispatch, but cannot relate it to my question.
  2. Where are these number come from: interrupts = <2>, <3>;

I found some generic info about MIPS interrupt.

20241019 Update - Interrupt controller now works

The plat_irq_dispatch(void) function in this code provides critical information on how the CPU interrupt lines are connected to the peripheral interrupt mux. Critical parts are:

#if defined(CONFIG_BCM93380)
static struct _int_ctl_ perf[5] =
{
    {&PERF->PeriphIrq[2].iStatus, &PERF->PeriphIrq[2].iMask, INTERNAL_ISR_TABLE_OFFSET},
    {&PERF->IopIrq[0].iStatus, &PERF->IopIrq[0].iMask, ((32 * 1) + INTERNAL_ISR_TABLE_OFFSET)},
    {&PERF->DocsisIrq[2].iStatus, &PERF->DocsisIrq[2].iMask, ((32 * 2) + INTERNAL_ISR_TABLE_OFFSET)},
    {&PERF->PeriphIrq[3].iStatus, &PERF->PeriphIrq[3].iMask, INTERNAL_ISR_TABLE_OFFSET},
    {&PERF->IopIrq[1].iStatus, &PERF->IopIrq[1].iMask, ((32 * 1) + INTERNAL_ISR_TABLE_OFFSET)}
};
#elif
...
#endif

static void irq_dispatch_int(int i) {
...
    pendingIrqs = (*perf[i].pStatus) & (*perf[i].pMask);
...
}

asmlinkage void plat_irq_dispatch(void) {
...
#if defined(CONFIG_BCM93380)
#if defined(CONFIG_BCM_LOT1)
    else if (cause & CAUSEF_IP4)
        irq_dispatch_int(3);
    else if (cause & CAUSEF_IP6)
        irq_dispatch_int(4);
#endif
    else if (cause & CAUSEF_IP3)
        irq_dispatch_int(0);
    else if (cause & CAUSEF_IP5)
        irq_dispatch_int(1);
...
}

We are targeting BCM3380, so CONFIG_BCM93380 must be defined. Looking at the perf array, we know that PERF->PeriphIrq[2] and PERF->PeriphIrq[3] are referenced here. plat_irq_dispatch() further suggests that CAUSEF_IP4 maps to PERF->PeriphIrq[2] and CAUSEF_IP3 maps to PERF->PeriphIrq[3]. The address of PERF->PeriphIrq[x] can be simply found as INTC_BASE + 0x30 + x*sizeof(IntMaskStatus), where:

  1. INTC_BASE is 0x14e00000 or 0xb4e00000
  2. 0x30 is the offset of the first mask-flag combination
  3. IntMaskStatus is a struct representing a mask-flag combination:
// Interrupt Controller mask and status group
typedef struct
{
    uint32  iMask;
    uint32  iStatus;
} IntMaskStatus;

Since we don't know what is CONFIG_BCM_LOT1 (likely identifies each core in the SoC), we have to try both combinations. Here is our final result:

		periph_intc: interrupt-controller@14e00048 {
			#address-cells = <1>;
			compatible = "brcm,bcm6345-l1-intc";
			reg = <0x14e00048 0x08>,
				  <0x14e00040 0x08>;

			interrupt-controller;
			#interrupt-cells = <1>;

			interrupt-parent = <&cpu_intc>;
			interrupts = <4>, <3>;
		};

This dts will produce an OpenWrt image that drops us to a serial shell. If the IRQ is not correctly configured, the bcm63xx-uart's tx interrupt handler wont work, and you wont see Please press Enter to activate this console. in your console. The kernel outputs seem to write to the UART hardware FIFO directly.

We may use this trick to adjust the order of the above mapping: https://github.com/ghostnup/asuswrt-merlin.ng/blob/991f9b4abe1f24f4e24ef2169c28fa4cd39cd7e2/release/src-rt-5.02hnd/cfe/cfe/arch/mips/board/bcm63xx_rom/src/bcm63xx_impl2_rom_boot.S#L96

Related links

Connect to a Netgear CG3100 via the serial port

https://foro.seguridadwireless.net/openwrt/(desarrollo)-openwrt-en-netgear-cg3100dv3/

VOO调制解调器的RCE漏洞挖掘利用研究

VOOdoo - Remotely Compromising VOO Cable Modems

https://github.com/Swyter/netgear-cg3100-config-decoder

https://forum.archive.openwrt.org/viewtopic.php?id=49017

Main Menu:
==========
b) Boot from flash
g) Download and run from RAM
d) Download and save to flash
e) Erase flash sector
m) Set mode
s) Store bootloader parameters to flash
i) Re-init ethernet
r) Read memory
w) Write memory
j) Jump to arbitrary address
z) Reset
TFTP Get Selected
Board TFTP Server IP Address [192.168.1.100]:
Enter filename [openwrt-bmips-bcm3380-netgear_cg3100d-initramfs-kernel.bin]:
Destination: a2f00000
Destination: a2f00000
Starting TFTP of openwrt-bmips-bcm3380-netgear_cg3100d-initramfs-kernel.bin from 192.168.1.100
Getting openwrt-bmips-bcm3380-netgear_cg3100d-initramfs-kernel.bin using octet mode
.......................................................................................................................................................................................................................................................
Link up: 1G full
.........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Tftp complete
Received 5375591 bytes
Image 3 Program Header:
Signature: a0e3
Control: 0000
Major Rev: 0003
Minor Rev: 0000
Build Time: 2024/10/13 15:34:11 Z
File Length: 5375499 bytes
Load Address: 80010000
Filename: openwrt-bmips-bcm3380-netgear_cg3100d-initramfs-kernel.bin
HCS: 73c7
CRC: 353ff1f0
Store parameters to flash? [n]
Performing CRC on Image 3...
CRC time = 84953675
Loading non-compressed image 3...
Target Address: 0x80010000
Length: 5375499
Executing Image 3...
OpenWrt kernel loader for BMIPS
Copyright (C) 2011 Gabor Juhos <[email protected]>
Copyright (C) 2014 Jonas Gorski <[email protected]>
Copyright (C) 2020 Alvaro Fernandez Rojas <[email protected]>
kernel_la = 0x80010000
Decompressing kernel... done!
blasting from 0x80010000 to 0x013cc0b7 (0x80010000 - 0x813dc0c0)
Starting kernel at 80010000...
[ 0.000000] Linux version 6.6.50 (rikka@wsl) (mips-openwrt-linux-musl-gcc (OpenWrt GCC 13.3.0 r27346-c7ba5574f5) 13.3.0, GNU ld (GNU Binutils) 2.42) #0 SMP Sun Oct 13 15:34:11 2024
[ 0.000000] CPU0 revision is: 0002a070 (Broadcom BMIPS4350)
[ 0.000000] MIPS: machine is Netgear CG3100D
[ 0.000000] earlycon: bcm63xx_uart0 at MMIO 0x14e00200 (options '115200n8')
[ 0.000000] printk: bootconsole [bcm63xx_uart0] enabled
[ 0.000000] Kernel sections are not in the memory maps
[ 0.000000] Wasting 576 bytes for tracking 16 unused pages
[ 0.000000] Initrd not found or empty - disabling initrd
[ 0.000000] Reserving 0KB of memory at 4194303KB for kdump
[ 0.000000] Kernel panic - not syncing: early_init_dt_alloc_memory_arch: Failed to allocate 2807 bytes align=0x40
[ 0.000000] Rebooting in 1 seconds..
[ 0.000000] Reboot failed -- System halted
OpenWrt kernel loader for BMIPS
Copyright (C) 2011 Gabor Juhos <[email protected]>
Copyright (C) 2014 Jonas Gorski <[email protected]>
Copyright (C) 2020 Alvaro Fernandez Rojas <[email protected]>
kernel_la = 0x80010000
Decompressing kernel... done!
blasting from 0x80010000 to 0x013cc0b7 (0x80010000 - 0x813dc0c0)
Starting kernel at 80010000...
[ 0.000000] Linux version 6.6.50 (rikka@i9-13900ks-wsl) (mips-openwrt-linux-musl-gcc (OpenWrt GCC 13.3.0 r27346-c7ba5574f5) 13.3.0, GNU ld (GNU Binutils) 2.42) #0 SMP Sun Oct 13 15:56:52 2024
[ 0.000000] CPU0 revision is: 0002a070 (Broadcom BMIPS4350)
[ 0.000000] MIPS: machine is Netgear CG3100D
[ 0.000000] 64MB of RAM installed
[ 0.000000] earlycon: bcm63xx_uart0 at MMIO 0x14e00200 (options '115200n8')
[ 0.000000] printk: bootconsole [bcm63xx_uart0] enabled
[ 0.000000] Initrd not found or empty - disabling initrd
[ 0.000000] Reserving 0KB of memory at 4194303KB for kdump
[ 0.000000] Primary instruction cache 64kB, VIPT, 4-way, linesize 16 bytes.
[ 0.000000] Primary data cache 32kB, 2-way, VIPT, cache aliases, linesize 16 bytes
[ 0.000000] Zone ranges:
[ 0.000000] Normal [mem 0x0000000000000000-0x0000000003ffffff]
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000000000000-0x0000000003ffffff]
[ 0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x0000000003ffffff]
[ 0.000000] percpu: Embedded 12 pages/cpu s17824 r8192 d23136 u49152
[ 0.000000] Kernel command line: earlycon
[ 0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes, linear)
[ 0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes, linear)
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 16240
[ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[ 0.000000] Memory: 43308K/65536K available (7814K kernel code, 625K rwdata, 1656K rodata, 11208K init, 216K bss, 22228K reserved, 0K cma-reserved)
[ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[ 0.000000] rcu: Hierarchical RCU implementation.
[ 0.000000] rcu: RCU restricting CPUs from NR_CPUS=2 to nr_cpu_ids=1.
[ 0.000000] Tracing variant of Tasks RCU enabled.
[ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
[ 0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1
[ 0.000000] NR_IRQS: 256
# This is a helper script that simplifies the kernel loading on the CG3100 device.
# This script assumes:
# 1. The server address and image file name have been stored in the device.
# 2. The RTS of the UART controls the on/off of the CG3100 device. The polarity of RTS depends on the actual USB-UART adapter.
import serial
import time
import threading
def read_from_serial(ser):
"""Function to continuously read from serial port and print to console."""
while True:
if ser.in_waiting > 0:
data = ser.read(ser.in_waiting)
data = data.decode('utf-8')
print(data, end='')
if __name__ == '__main__':
try:
# Open the serial port
with serial.Serial(port='/dev/ttyUSB0', baudrate=115200, bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE) as ser:
# Start the reading thread
read_thread = threading.Thread(target=read_from_serial, args=(ser,))
read_thread.start()
# Clear RTS (de-assert)
ser.setRTS(True)
time.sleep(1) # Wait for 0.5 second
# Set RTS (assert)
ser.setRTS(False)
time.sleep(0.5)
ser.write(b'p\r\r\r\r\r')
time.sleep(1)
ser.write(b'g')
time.sleep(0.5)
ser.write(b'\r')
time.sleep(0.5)
ser.write(b'\r')
time.sleep(15)
ser.write(b'\r')
# Maintain main thread running while read_thread handles the input
while read_thread.is_alive():
time.sleep(1)
except KeyboardInterrupt:
print("\nInterrupted by user, exiting...")
except serial.SerialException as e:
print(f"Error with serial port: {e}")
except Exception as e:
print(f"An unexpected error occurred: {e}")
Tftp complete
Received 5614421 bytes
Image 3 Program Header:
Signature: a0e3
Control: 0005
Major Rev: 0003
Minor Rev: 0000
Build Time: 2024/10/14 10:54:40 Z
File Length: 5614329 bytes
Load Address: 80010000
Filename: /home/rikka/workspace/linux/openwrt/build_dir/t
HCS: 90c9
CRC: 009d923d
Store parameters to flash? [n]
Performing CRC on Image 3...
CRC time = 88727462
Detected LZMA compressed image... decompressing...
Target Address: 0x80010000
decompressSpace is 0x4000000
Elapsed time 1608698429
Decompressed length: 20758759
Executing Image 3...
[ 0.000000] Linux version 6.6.50 (rikka@i9-13900ks-wsl) (mips-openwrt-linux-musl-gcc (OpenWrt GCC 13.3.0 r27346-c7ba5574f5) 13.3.0, GNU ld (GNU Binutils) 2.42) #0 SMP Mon Oct 14 09:59:31 2024
[ 0.000000] CPU0 revision is: 0002a070 (Broadcom BMIPS4350)
[ 0.000000] MIPS: machine is Netgear CG3100D
[ 0.000000] 64MB of RAM installed
[ 0.000000] earlycon: bcm63xx_uart0 at MMIO 0x14e00200 (options '115200n8')
[ 0.000000] printk: bootconsole [bcm63xx_uart0] enabled
[ 0.000000] Initrd not found or empty - disabling initrd
[ 0.000000] Reserving 0KB of memory at 4194303KB for kdump
[ 0.000000] Primary instruction cache 64kB, VIPT, 4-way, linesize 16 bytes.
[ 0.000000] Primary data cache 32kB, 2-way, VIPT, cache aliases, linesize 16 bytes
[ 0.000000] Zone ranges:
[ 0.000000] Normal [mem 0x0000000000000000-0x0000000003ffffff]
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000000000000-0x0000000003ffffff]
[ 0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x0000000003ffffff]
[ 0.000000] percpu: Embedded 12 pages/cpu s17824 r8192 d23136 u49152
[ 0.000000] Kernel command line: earlycon
[ 0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes, linear)
[ 0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes, linear)
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 16240
[ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[ 0.000000] Memory: 43308K/65536K available (7814K kernel code, 625K rwdata, 1656K rodata, 11208K init, 216K bss, 22228K reserved, 0K cma-reserved)
[ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[ 0.000000] rcu: Hierarchical RCU implementation.
[ 0.000000] rcu: RCU restricting CPUs from NR_CPUS=2 to nr_cpu_ids=1.
[ 0.000000] Tracing variant of Tasks RCU enabled.
[ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
[ 0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1
[ 0.000000] NR_IRQS: 256
[ 0.000000] rcu: srcu_init: Setting srcu_struct sizes based on contention.
[ 0.000000] clocksource: MIPS: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 11479041721 ns
[ 0.000097] sched_clock: 32 bits at 167MHz, resolution 6ns, wraps every 12897800188ns
[ 0.021180] Calibrating delay loop... 3.81 BogoMIPS (lpj=19072)
[ 0.178136] pid_max: default: 32768 minimum: 301
[ 3.413301] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 3.425588] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 5.911367] RCU Tasks Trace: Setting shift to 0 and lim to 1 rcu_task_cb_adjust=1.
[ 5.973793] rcu: Hierarchical SRCU implementation.
[ 5.980414] rcu: Max phase no-delay instances is 1000.
[ 6.064753] smp: Bringing up secondary CPUs ...
[ 6.071140] smp: Brought up 1 node, 1 CPU
[ 6.453421] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[ 6.468499] futex hash table entries: 256 (order: 2, 16384 bytes, linear)
[ 7.999246] pinctrl core: initialized pinctrl subsystem
[ 8.552816] NET: Registered PF_NETLINK/PF_ROUTE protocol family
[ 11.511581] clocksource: Switched to clocksource MIPS
[ 15.038434] NET: Registered PF_INET protocol family
[ 15.088273] IP idents hash table entries: 2048 (order: 2, 16384 bytes, linear)
[ 15.268150] tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 4096 bytes, linear)
[ 15.285331] Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear)
[ 15.298511] TCP established hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 15.315770] TCP bind hash table entries: 1024 (order: 2, 16384 bytes, linear)
[ 15.335603] TCP: Hash tables configured (established 1024 bind 1024)
[ 15.360754] UDP hash table entries: 256 (order: 1, 8192 bytes, linear)
[ 15.375293] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes, linear)
[ 15.586498] NET: Registered PF_UNIX/PF_LOCAL protocol family
[ 15.607863] PCI: CLS 0 bytes, default 16
[ 17.196541] workingset: timestamp_bits=14 max_order=14 bucket_order=0
[ 17.730426] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[ 17.740435] jffs2: version 2.2 (NAND) (SUMMARY) (LZMA) (RTIME) (CMODE_PRIORITY) (c) 2001-2006 Red Hat, Inc.
[ 20.836651] bcm7038-wdt 14e000dc.watchdog: Registered BCM7038 Watchdog
[ 21.262422] NET: Registered PF_INET6 protocol family
[ 22.195537] Segment Routing with IPv6
[ 22.218064] In-situ OAM (IOAM) with IPv6
[ 22.246809] NET: Registered PF_PACKET protocol family
[ 22.431651] 8021q: 802.1Q VLAN Support v1.8
[ 31.794649] bcm63xx_uart: probe of 14e00200.serial failed with error -16
[ 31.915961] clk: Disabling unused clocks
[ 54.937434] Warning: unable to open an initial console.
[ 56.728482] Freeing unused kernel image (initmem) memory: 11208K
[ 56.738353] This architecture does not have kernel memory protection.
[ 56.750343] Run /init as init process
[ 112.551507] init: Console is alive
[ 112.585959] init: - watchdog -
[ 114.798720] kmodloader: loading kernel modules from /etc/modules-boot.d/*
[ 116.607705] usbcore: registered new interface driver usbfs
[ 116.625480] usbcore: registered new interface driver hub
[ 116.642441] usbcore: registered new device driver usb
[ 117.164792] gpio_button_hotplug: loading out-of-tree module taints kernel.
[ 119.541497] kmodloader: done loading kernel modules from /etc/modules-boot.d/*
[ 119.728795] init: - preinit -
[ 153.347327] random: crng init done
[ 199.605355] procd: - early -
[ 199.634226] procd: - watchdog -
[ 204.468742] procd: - watchdog -
[ 204.543997] procd: failed to set stdio: No such device
[ 204.637887] procd: - ubus -
[ 207.604386] procd: - init -
[ 302.286044] kmodloader: loading kernel modules from /etc/modules.d/*
[ 317.072505] PPP generic driver version 2.4.2
[ 317.613772] NET: Registered PF_PPPOX protocol family
[ 319.100901] kmodloader: done loading kernel modules from /etc/modules.d/*
@xurubin
Copy link

xurubin commented Oct 17, 2024

Use this to enable the cache.

+	mfc0	t0, CP0_CONFIG
+	li	t1, ~7
+	and	t0, t1
+	ori	t0, 3
+	mtc0	t0, CP0_CONFIG
+	nop
+	mfc0	t0, $22
+	// CP0_BCM_CFG_ICSHEN | CP0_BCM_CFG_DCSHEN
+	li	t1, 0xC0000000
+	or	t0, t1
+	mtc0	t0, $22
+	nop

What are you trying to do? This is an obsolete SoC and you will find very little public information on Broadcom stuff, so bringing up OpenWrt on this platform is really not worth the effort. Trust me I've been there...

@rikka0w0
Copy link
Author

rikka0w0 commented Nov 6, 2024

What are you trying to do? This is an obsolete SoC and you will find very little public information on Broadcom stuff, so bringing up OpenWrt on this platform is really not worth the effort. Trust me I've been there...

There are a lot of second-hand cable modems out there powered by BCM3380 and BCM3384. Each only costs a few dollars. You may even get them for free. Of course, the DOCSIS cable modem part is not going to work, and neither is the WIFI. However, if we can get the ethernet to work, it will still be a good router for running free firmware. Most of those modems come with dual-core CPU and 64/128MB of RAM, which is still good for today's use.

How far did you go with BCM3380? I managed to make the OpenWrt boot on this device and successfully obtained a serial console. Apart from the UART peripheral, only the interrupt controller and reset controller have worked so far. You can find my progress here:
https://github.com/rikka0w0/openwrt-fast3864op/tree/bcm3380-20241014

I'm trying to get the SPI peripheral working so that it will be possible to flash the firmware permanently. I looked at the source code of the stocked firmware. The register layout seems to match BCM6358. I used that in DTS, and it does not work. I used my oscilloscope to probe the SPI interface of the flash; once the kernel boots, there are no more SPI activities, and all SPI data exchange returns 0. Any suggestion on this?

@xurubin
Copy link

xurubin commented Nov 7, 2024

I added you to my private repo on GitHub so you can have a look. Looks like I had some entry for the SPI flash in the device tree so maybe it worked, but It's been a long time so I don't really remember. What I do remember is I got stuck at getting the ethernet controller in SoC to work, and I felt it would require rewriting the unimac driver code which seemed like an impossible task without Broadcom documentation, and that's when I gave up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment