Adding OpenWrt support for ws-ap3825i

i make openwrt with:
Global build settings
[ * ] Compile the kernel with Debug FileSystem enabled
[ * ] Compile the kernel with debug information

and uboot bootargs=console=ttyS0,115200n81 ignore_loglevel

Boot (PRI)-> tftpboot 0x1000000 openwrt-mpc85xx-p1020-ws-ap3825i-initramfs-kernel.bin;␍␊
[20:25:44:446] Speed: 100, full duplex␍␊
[20:25:44:458] Using eTSEC3 device␍␊
[20:25:44:458] TFTP from server 192.168.101.100; our IP address is 192.168.101.220␍␊
[20:25:44:458] Filename 'openwrt-mpc85xx-p1020-ws-ap3825i-initramfs-kernel.bin'.␍␊
[20:25:44:471] Load address: 0x1000000␍␊
[20:25:44:471] Loading: *<0x08>#################################################################␍␊
[20:25:44:717] ⇥	 #################################################################␍␊
[20:25:44:970] ⇥	 #################################################################␍␊
[20:25:45:198] ⇥	 #################################################################␍␊
[20:25:45:443] ⇥	 #################################################################␍␊
[20:25:45:685] ⇥	 #################################################################␍␊
[20:25:45:934] ⇥	 #############################␍␊
[20:25:46:052] done␍␊
[20:25:46:052] Bytes transferred = 6144300 (5dc12c hex)␍␊
[20:25:46:052] Boot (PRI)-> bootm 0x1000000;␍␊
[20:25:49:824] ## Booting kernel from FIT Image at 01000000 ...␍␊
[20:25:49:841]    Using 'config@1' configuration␍␊
[20:25:49:841]    Trying 'kernel@1' kernel subimage␍␊
[20:25:49:841]      Description:  POWERPC OpenWrt Linux-4.14.221␍␊
[20:25:49:841]      Type:         Kernel Image␍␊
[20:25:49:867]      Compression:  lzma compressed␍␊
[20:25:49:867]      Data Start:   0x010000ec␍␊
[20:25:49:867]      Data Size:    6131774 Bytes = 5.8 MiB␍␊
[20:25:49:867]      Architecture: PowerPC␍␊
[20:25:49:867]      OS:           Linux␍␊
[20:25:49:867]      Load Address: 0x00000000␍␊
[20:25:49:867]      Entry Point:  0x00000000␍␊
[20:25:49:867]      Hash algo:    crc32␍␊
[20:25:49:867]      Hash value:   da78c82a␍␊
[20:25:49:867]      Hash algo:    sha1␍␊
[20:25:49:892]      Hash value:   b3b413b0ce4b747e7a3ff046d2f8635a7ea4ad45␍␊
[20:25:49:892]    Verifying Hash Integrity ... crc32+ sha1+ OK␍␊
[20:25:50:044] ## Flattened Device Tree from FIT Image at 01000000␍␊
[20:25:50:050]    Using 'config@1' configuration␍␊
[20:25:50:050]    Trying 'fdt@1' FDT blob subimage␍␊
[20:25:50:063]      Description:  POWERPC OpenWrt ws-ap3825i device tree blob␍␊
[20:25:50:063]      Type:         Flat Device Tree␍␊
[20:25:50:063]      Compression:  uncompressed␍␊
[20:25:50:074]      Data Start:   0x015d9268␍␊
[20:25:50:074]      Data Size:    10640 Bytes = 10.4 KiB␍␊
[20:25:50:074]      Architecture: PowerPC␍␊
[20:25:50:089]      Hash algo:    crc32␍␊
[20:25:50:089]      Hash value:   7f85f3e6␍␊
[20:25:50:089]      Hash algo:    sha1␍␊
[20:25:50:089]      Hash value:   5633df10767582686bab5fe81a3b9957f9f75989␍␊
[20:25:50:089]    Verifying Hash Integrity ... crc32+ sha1+ OK␍␊
[20:25:50:104]    Booting using the fdt blob at 0x15d9268␍␊
[20:25:50:104]    Uncompressing Kernel Image ... OK␍␊
[20:25:51:756]    Loading Device Tree to 09ffa000, end 09fff98f ... OK␍␊

on this step device is freeze

how to config karnel for print all debug and error information
and how find bug, my board freeze on this line

 Loading Device Tree to 09ffa000, end 09fff98f ... OK 
// SPDX-License-Identifier: GPL-2.0-or-later or MIT

/include/ "fsl/p1020si-pre.dtsi"
/ {
	model = "Etreme-networks WS-AP3825i";
	compatible = "extreme-networks,ws-ap3825i";

	

	memory {
		device_type = "memory";
	};

	

	
	lbc: localbus@ffe05000 {
		reg = <0 0xffe05000 0 0x1000>;
		ranges = <0x0 0x0 0x0 0xee000000 0x2000000>;

		nor@0,0 {
			#address-cells = <1>;
			#size-cells = <1>;
			compatible = "cfi-flash";
			reg = <0x0 0x0 0x2000000>;
			bank-width = <2>;
			device-width = <1>;

			partitions {
				compatible = "fixed-partitions";
				#address-cells = <1>;
				#size-cells = <1>;

				partition@0 {
					compatible = "denx,fit";
					reg = <0x0 0x3d60000>;
					label = "FS";
				};

				partition@3d60000 {
					reg = <0x3d60000 0x20000>;
					label = "CALIB";
					read-only;
				};

				partition@3d80000{
					reg = <0x3d80000 0x80000>;
					label = "BootPRI";
					read-only;
				};

				partition@3e00000{
					reg = <0x3e00000 0x100000>;
					label = "NVRAM";
					read-only;
				};

				partition@3f00000 {
					reg = <0x3f00000 0x20000>;
					label = "cfg2";
					read-only;
				};

				partition@3f20000 {
					reg = <0x3f20000 0x20000>;
					label = "cfg1";
					read-only;
				};
			};
		};
	};

	soc: soc@ffe00000 {
		ranges = <0x0 0x0 0xffe00000 0x100000>;

		gpio0: gpio-controller@fc00 {
		};

		mdio@24000 {
			phy4: ethernet-phy@4 {
				reg = <0x4>;
				reset-gpios = <&gpio0 2 1>;
			};
		};

		enet0: ethernet@b0000 {
			phy-connection-type = "rgmii-id";
			phy-handle = <&phy4>;
		};

		enet1: ethernet@b1000 {
			status = "disabled";
		};

		enet2: ethernet@b2000 {
			status = "disabled";
		};

		usb@22000 {
			status = "disabled";
		};

		usb@23000 {
			status = "disabled";
		};
	};

	pci0: pcie@ffe09000 {
		ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
			  0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
		reg = <0 0xffe09000 0 0x1000>;
		pcie@0 {
			ranges = <0x2000000 0x0 0xa0000000
				  0x2000000 0x0 0xa0000000
				  0x0 0x20000000

				  0x1000000 0x0 0x0
				  0x1000000 0x0 0x0
				  0x0 0x100000>;
		};
	};

	pci1: pcie@ffe0a000 {
		reg = <0 0xffe0a000 0 0x1000>;
		ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
			  0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
		pcie@0 {
			ranges = <0x2000000 0x0 0x80000000
				  0x2000000 0x0 0x80000000
				  0x0 0x20000000

				  0x1000000 0x0 0x0
				  0x1000000 0x0 0x0
				  0x0 0x100000>;
		};
	};

};
/include/ "fsl/p1020si-post.dtsi"

The device looks very similar to an Aerohive AP330 or AP370 -- same CPU, same PHY, etc; the big difference between the 330 and 370 was the switch from an ath9k 5GHz chip to an ath10k one.

I think the AP330 has u-boot issues: you would probably have some more success if you look at how it gets around that. It does some trickery to unpack the kernel at boot.

1 Like

How did you manage to get past the password prompt in u-boot?

1 Like

I found the answer to my question from this post about another Extreme Networks product.

The answer: user/password are admin/new2day -- on my AP3825i, this applied both to the bootloader and to the Busybox shell once the onboard Linux had booted.

Update: I completely missed this PR which should support the board already.

Update2: The above is the OP of this thread having difficulty spinning up a port.

Update3:

You have made a mistake here: the flash is 0x4000000 (64MiB) long, not 0x2000000 long.

Update4: I haven't been able to make much progress: I am stuck at the same place as OP. I have pushed my code here: https://github.com/hurricos/openwrt/tree/ap3825i

Update5: I have publicly requested a GPL modification dump from Extreme Networks here: https://community.extremenetworks.com/extremewireless-identifi-233215/acquiring-a-gplv2-dump-of-linux-kernel-modifications-for-the-ap3825i-7831344

Update6: There is a known issue with booting Linux on PPC built using GCC10. This was avoided in all of my builds (which were on top of GCC11 / master, or, more recently, GCC8 / openwrt-21.02).

Update7: Still no dice. @blocktrron suggested that the onboard U-boot image may be manipulating my device tree; it might be possible to replace the U-boot copy, but it sounds daunting.

1 Like

Posting so some one can post again. lol

i have password to u-boot, but i don know how to download source on website provider, i call to office but this idea don't work, worker is dont understand me :upside_down_face:

i go back to porting this model

The user/password were admin/new2day. Unfortunately when I requested the GPL dump they suggested I mail in my request; I haven't done so yet.

I have sent an email out to plm@extremenetworks.com:

We use Extreme Networks / Aerohive products (including WAPs) at $COMPANY_NAME. We are requesting a copy of your modifications to "Das U-boot" bootloader and the Linux kernel for two types of devices:

  • the Extreme Networks WS-AP3825i, and
  • the Aerohive HiveAP 330.

We are requesting these dumps pursuant to the instructions laid out here:

https://cloud.kapostcontent.net/pub/04b28a7b-c5d0-4e4d-a1e7-79da832b3922/osd-extremewireless-os-version-ap-10-dot-51?kui=KD6X9S4PNomHSrog2y_LxQ

Please let us know how you would like to provide us these dumps pursuant to your obligations under the GNU General Public License version 2.

I got a response within 15 minutes from pfrancisco@extremenetworks.com, who was replying directly to "Peter Lam" PLam@extremenetworks.com with me CC'd. We should see come Monday where this goes.

1 Like

i make your git files and have result^

Upload kernel & fdt:
--- tftpboot 0x1000000 192.168.101.100:openwrt-mpc85xx-p1020-extreme-networks_ws-ap3825i-initramfs-kernel.bin

--- tftpboot 0x6000000 192.168.101.100:openwrt-mpc85xx-p1020-extreme-networks_ws-ap3825i-squashfs-fdt.bin

this message on board after load:

Boot (PRI)-> bootm 0x1000000 - 0x6000000
## Booting kernel from Legacy Image at 01000000 ...
   Image Name:   POWERPC OpenWrt Linux-5.4.143
   Image Type:   PowerPC Linux Kernel Image (uncompressed)
   Data Size:    11201712 Bytes = 10.7 MiB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 06000000
   Booting using the fdt blob at 0x6000000
   Loading Kernel Image ... OK
OK
   Loading Device Tree to 09ffa000, end 09fff9a1 ... OK
ft_fixup_l2cache: FDT_ERR_NOTFOUND

and board restarting after 10-20 second

How change compiler to Use uncompressed kernel

you received answer?

Still nothing yet: I am reaching out back again.

i have this device, can i help ?

Yes, for sure! I'm hearing that the engineers are almost done building the dump for both devices.

I will keep you posted; my plan is to post the dump once I get it.

1 Like

I have received my copy of the dumps. Here they are: https://downloads.laboratoryb.org/dumps/

I plan to create a git repository for each of these, where I apply these dumps as a branch on top of the most relevant version of Linux / u-boot.

2 Likes

I'm not sure of these dumps: the board calls itself P1020RDB, not P1020SKU. I would be interested to see:

  • The copy of Linux in this GPL dump actually booting on the AP3825i
  • A vbindiff of the compiled U-boot with one from the boards themselves.

... but after some thought, I don't think that any of that is the reason for this board not booting. I don't think AP3825i can boot using initramfs for AP3710i; there is probably plenty of setup required for the AP3825i specifically, like having a platform file specific to AP3825i (for AP3710i, it is target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3710i.c).

We should closely copy 16b01fb1b9c99513c318109bef96a1a3545c57a0 in this respect.

Edit: Now that I am essentially finished with the AP370 port, I will turn to the ws-ap3825i. I have only one of these boards, but I will soon order more for testing once I get Linux booting on the first ...

2021-11-27: Addendum: I still have not been able to get the serial console to come up to find what is crashing the board on early boot. However, I looked closely into the standard boot script and have found a possible way to view the content of the kernel ring buffer after a soft reset triggered by the watchdog timer (WDT). The stock U-boot uses the WDT to detect whether the watchdog caused the last reboot; it can do this because neither u-boot nor the BootROM reset the content of RAM upon reboot, and the WDT sets the value of a small patch of memory (through some special-purpose registers) upon reboot.

All I'd need to do is use the System.map (https://support.xilinx.com/s/question/0D52E00006hpihR/linux-kernel-hangs-after-allocatting-dma-contiguous-pool-on-zynq-7000?language=en_US) to find the memory location from which to read the kernel message log.

Here are the details of how the existing boot script works:

:
bootcmd=run boot_flash
boot_flash=source boot_kernel
:

boot_kernel is a script stored in u-boot which sets up the watchdog timer (WDT) and then boots an image from JFFS2; it also describes the mechanism for how it sets up the WDT and checks, upon each boot, whether the last reboot was caused by the WDT.

Some other necessary variables to understand the script:

BOOT_KERNEL=primary
DEFAULT_SETTING=0
LOGHDRRREASON=0xfffec24
MOSTRECENTKERNEL=0
REBOOT_PATTERN_WDG=0x5A5A5A5A
WATCHDOG_COUNT=0x00000001
WATCHDOG_LIMIT=3

And the script itself:

boot_kernel
# U-boot script start
bSaveEnvironment=0
saved_ver=$ver
# The watchdog registers are actually SPR's.
# These are hardcoded in the chenv command as 0xffffffff for TSR and 0xfffffffe for TCR.
# NOTE 1: test command is non-intuitive, for environment variables try to do the -eq check for 0, not 1
#         if the variable is not present, -eq 1 will return true
reg_tsr=0xffffffff
reg_tcr=0xfffffffe
if test $DEFAULT_SETTING -eq 1; then
    bSaveEnvironment=1
    setenv DEFAULT_SETTING 0
    setenv CURR_VER $ver
    echo first time using environment, will save at the end...
# The application has informed us which kernel is more recent in MOSTRECENTKERNEL.
if test $MOSTRECENTKERNEL -eq 0; then
    newer="primary"
    older="secondary"
else
    newer="secondary"
    older="primary"
# This is the default order of images to boot.
if test $USE_ALT_DTB -eq 0; then
    smp_amp="-"
    dtbnum=1
    order="${newer} ${older}"
else
    smp_amp="+"
    dtbnum=2
    order="${newer} ${older} ${older}"
if test $WATCHDOG_LIMIT -ne 0; then
    echo check for watchdog, limit=$WATCHDOG_LIMIT...
    if test $WATCHDOG_COUNT -ge $WATCHDOG_LIMIT; then
        echo watchdog count hit previously, running older image...
        order="${older}"
    else        
        echo check for reset by watchdog...
        rebootReason=$LOGHDRRREASON
        if itest.l *${rebootReason} -eq $REBOOT_PATTERN_WDG; then
            if test ${intWd} -ne 1; then
                echo last reset caused by watchdog...
                chenv WATCHDOG_COUNT + 1
                bSaveEnvironment=1
            fi
            if test $WATCHDOG_COUNT -ge $WATCHDOG_LIMIT; then
                echo watchdog limit reached, cnt=$WATCHDOG_COUNT...
                echo switching to older image...
                order="${older}"
            else
                echo updating watchdog count, cnt=$WATCHDOG_COUNT...
            fi
       else
            echo no watchdog...
       fi
    fi
else
    echo skipping all watchdog checks...
echo bSaveEnviron=${bSaveEnvironment} image_order=${order}
if test ${bSaveEnvironment} -eq 1; then
    saveenv
    saveenv
chenv REBOOT_PATTERN_WDG save.l $LOGHDRRREASON
# Set watchdog to about 1 minute.
# If WATCHDOG_DISABLE is not set, then the test command returns 0.
if test $WATCHDOG_DISABLE -eq 0; then
    setenv TCR 0xA4100000
    chenv TCR save.l ${reg_tcr}
    setenv TSR 0xE0000000
for image in ${order}
    # Kick the watchdog.
    if test $WATCHDOG_DISABLE -eq 0; then
        chenv TSR save.l ${reg_tsr}
    fi
    
    if fsload 0x0A000000 "${image}.gz.uImage"; then
        setenv bootargs "$mtdparts BOOT_BOOTROM=\""${saved_ver}"\"" BOOT_KERNEL=${image} $static_bootargs
        echo ready to boot kernel... [DTB ${dtbnum}]
        # Reset system when watchdog occurs (starts the final countdown).
        if test $WATCHDOG_DISABLE -eq 0; then
            chenv TSR save.l ${reg_tsr}
        fi
        # If this command fails, then the image is corrupt. If it succeeds, then we are running the kernel.
        bootm 0x0A000000 - ${smp_amp}
        echo boot failed...
        # For SMP/AMP images, we trying running with the 2nd DTB, for both the newer then the
        # older image. However, if that doesn't work, then try running the older image again with the
        # 1st DTB.
        if test ${image} = ${older}; then
            smp_amp="-"
            dtbnum=1
        fi
    fi
done
# If we are here, there is a problem with the image(s) we were trying to run.
setenv ZERO 0
chenv ZERO save.l $LOGHDRRREASON
setenv ZERO
echo ERROR: Cannot boot either kernel image, dropping to interactive shell (watchdog might trigger)

So a script to set the WDT and boot might be:

setenv ipaddr 10.0.7.2
setenv serverip 10.0.7.1
tftpboot 0xa000000 openwrt-mpc85xx-p1020-extreme-networks_ws-ap3825i-initramfs-kernel.bin
tftpboot 0x6000000 openwrt-mpc85xx-p1020-extreme-networks_ws-ap3825i-squashfs-fdt.bin;

reg_tsr=0xffffffff
reg_tcr=0xfffffffe

chenv REBOOT_PATTERN_WDG save.l $LOGHDRRREASON
setenv TCR 0xA4100000

chenv TCR save.l ${reg_tcr}
setenv TSR 0xE0000000

chenv TSR save.l ${reg_tsr}
bootm 0xa000000 - 0x6000000

My System.map compiles out __log_buf to 0xc0a88e84. An md to that address crashes u-boot, I realize now because that's virtual memory. Apparently CONFIG_KERNEL_START is usually 0xC0000000 on PowerPC. So I just need to do a md a88e84.

This should all work, but unfortunately md shows there is nothing in any of the buffers, so I'm forced to assume the kernel just never launches ...

Edit: I have managed to capture a couple of lines of an oops. Not sure why these lines are so incomplete, though: https://paste.c-net.org/DaisyDearest

Edit: I disabled SMP and got are more robust output: there's probably something going on where output gets destroyed by SMP being active: https://paste.c-net.org/BauerFlippers

2 Likes

Hey @hurricos nice work so far on this. I've been following your progress on IRC for the past two months, and just wanted to toss you a nod of encouragement.

I picked up one of these a couple years ago for cheap and had been planning to force it into standalone AP mode, but could never get it working, so it got set aside and forgotten. I have all kinds of hardware for reading and writing flash chips and EEPROMs, so if you need a hand testing anything, I'm happy to set stuff up. I know one of my buddies had some of these units around in a box as well, so I could borrow a few for unit testing. These units are like $8.00/piece in volume on eBay, so it's definitely worth it to get them going. I'm not much of a programmer once you get past microcontrollers, but I can at least help on the hardware side.

Thanks again, and good luck!

P.S. if you have a link for PayPal etc, I'd be happy to send you a few bucks to help support any needed beer and snacks during development hahaha

Hey @Gadorach ! Thanks for the encouragement, and thanks for reviving the thread (I was coming up against the 3-post limit).

I was ultimately able to pull the full kernel oops: https://paste.c-net.org/LakhiToner


?BUG: Unable to handle kernel data access on read at 0xc9ffa008
?Faulting instruction address: 0xc033c920
?Thread overran stack, or stack corrupted
?Oops: Kernel access of bad area, sig: 11 #1
?BE PAGE_SIZE=4K 
?Modules linked in:
?CPU: 0 PID: 0 Comm: swapper Not tainted 5.10.82 #0
?NIP:  c033c920 LR: c033ca50 CTR: c000e938
?REGS: c0c01e28 TRAP: 0300   Not tainted  (5.10.82)
?	MSR:  00021000 <CE,ME>  CR: 28248044  XER: 200000000 
GPR00: c033ccdc c0c01ee0 c0b7ba40 c9ffa000 00000000 00000004 40000000 60000000 
GPR08: c9ffa000 fffffff8 00000000 00a3a348 88242044 00a3a2a0 00000000 

At point, the problem is that the kernel is given a somewhat high address for the device tree blob (starting at 0x09ffa000 in physical memory / 0xc9ffa000 in ppc32 virtual memory). Upon accessing it the kernel panics, apparently due to a memory restriction violation.

The AP3710i, a working OpenWrt board which is extremely similar but which does not relocate the device tree blob, does not panic.

If I can figure out how to tell u-boot on the AP3825i to not relocate the dtb, I am confident booting will succeed.

One part of that will be figuring out through which region of memory the Linux kernel is informed of the location of the device tree blob.

Edit: I looked up one of the variables, CONFIG_SYS_BOOTMAPSZ, from the u-boot source dump whose value helps determine where the flattened device tree (fdt) gets relocated to, and found a patch (mind you, for ARM) which actually describes the situation we're seeing where the fdt can be relocated high enough that the kernel panics.

This bootlin presentation helps me answer my above question:

One part of that will be figuring out through which region of memory the Linux kernel is informed of the location of the device tree blob.

... the answer is on slide 18:

The DTB address is passed through a dedicated CPU register to the kernel: r2 on ARM32

I also see for the u-boot Beaglebone documentation a variable (fdt_high) which can be used to tell u-boot not to relocate too high to solve the issue we're having -- but I worry our u-boot is too old (and I bet the u-boot derivative used on the AP3825i squashes any attempt to mess with the device tree's relocation address).

1 Like