Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Information about this project #1

Open
boxer4 opened this issue Feb 10, 2019 · 82 comments
Open

Information about this project #1

boxer4 opened this issue Feb 10, 2019 · 82 comments

Comments

@boxer4
Copy link

boxer4 commented Feb 10, 2019

Curious if this project is still being looked at? I am wondering if I should look into using my XTM-21W.

Not sure if this is useful information but I pulled the Atheros wifi card from it and found that it seems to work with the ath9k Linux driver in 4.4.163, which may make porting easier.

@greguu
Copy link
Owner

greguu commented Feb 12, 2019

I have not abandoned this project, but have very limited time at the moment. Next on the list is to get the RTL8366SR switch going so the Ethernet port and WAN port will work. WiFi is not an issue. There has been some progress in regards to Linux support for RTL8366RB chip sets and I need to test if this code actually works on the Watchguard. Once the switch is working the remaining stuff should not be too hard to implement (WiFi, LED and flashing OpenWrt to NAND), but a proper implementation maybe still away a bit.

@boxer4
Copy link
Author

boxer4 commented Feb 12, 2019

Thank you for replying. At this point I was just wondering if I should scavenge the unit for parts and dispose of the unit or not. Seems the architecture of this unit may be one-off and may not be applicable to other devices and not too interesting to keep around? Or do you expect it perhaps one day be accepted for merging with the mainline kernel?

@greguu
Copy link
Owner

greguu commented Feb 12, 2019

I think the unit is quite nice specs wise (even today) and I would not dispose it. The only parts you could scavenge are the WiFi card and the Antennas. I am not sure this specific port will go mainline, but I am confident I can get a functional OpenWrt going sometime this year and maybe OpenWrt will keep the port in their branch if I and others are willing to look after it. As mentioned I am just very busy with other things at the moment and there have not been any other requests about this device. However, you can pick them up on ebay now quite cheap as the official EOL was two years ago so it may get some traction on OpenWrt once a port is complete. Its a nice unit with a somewhat popular ARM SoC (Intel Xscale based) that will remain in the kernel for some years to come.

@greguu greguu pinned this issue Feb 12, 2019
@ismailkisla
Copy link

Hi . I bought an xt22 from the flea market. I'm thinking of buying open-wrt but. I was unable to create the image.i use ubuntu 20.04.

i am getting this error:FATAL ERROR: Unable to parse input tree

@greguu
Copy link
Owner

greguu commented Jan 4, 2023

the last fork of OpenWrt for the XTM 22 is in this repo

@ismailkisla
Copy link

hi
the building finish .
but created files name openwrt-snapshot-r18823-a48f53e9e0-ixp4xx-watchguard-rootfs.tar.gz
no watchguard zimage

@greguu
Copy link
Owner

greguu commented Jan 6, 2023

the zImage is in the openwrt build folder somewhere, its not in the same folder as the rootfs. Once the build finished, you still need to append the watchguard device tree dtb file to the zImage (using cat) as well before you can boot the zImage.

@boxer4
Copy link
Author

boxer4 commented Jan 26, 2023

I may need to try this for the first time. Seems the serial port connector supplies 3v3 which unfortunately I don't have any 3v3 rs232 transceivers for this at this time, so it may be a while before first boot occurs, not to mention not having a bona-fide wall wart for it!

@greguu
Copy link
Owner

greguu commented Jan 26, 2023

@boxer4 I can look up the make / model of the serial adapter I used. I got some really cheap USB TTL adapters as well, but never tried them on this board. I got the one in the picture as I intended to present the serial port through the housing at some stage, for ease of access. You need a 12v 2a, pretty standard power supply.

@zastrixarundell
Copy link

zastrixarundell commented Mar 11, 2023

Hey there! I also bought one from the flea market today and I tried to build my own image for OpenWRT with this but failed as this is my first time doing this so I'm probably doing something wrong.

Thankfully the router has an rj45 console connection and I'm using some random USB->Serial and a hand-made DB9 to rt45 adapter, so I got serial access fairly easily.

I did follow this wiki up to the make menuconfig and I guessed that I have to import the config from _files/ into .config.

If that's wrong, would it be a problem to write some guildes as to how to build the image with these changes?

I saw that this was mentioned:

the last fork of OpenWrt for the XTM 22 is in this repo

But I did get an syntex error during compilation, nor do I really know which settings to enable during compilation (the Y/n prompt).

Error: arch/arm/boot/dts/intel-ixp43x-watchguard-xtm21w.dts:175.3-176.1 syntax error
FATAL ERROR: Unable to parse input tree
make[6]: *** [scripts/Makefile.lib:364: arch/arm/boot/dts/intel-ixp43x-watchguard-xtm21w.dtb] Error 1
make[5]: *** [Makefile:1373: dtbs] Error 2
make[5]: *** Waiting for unfinished jobs....
  HOSTCC  scripts/genksyms/parse.tab.o
  HOSTCC  scripts/genksyms/lex.lex.o
  HOSTLD  scripts/genksyms/genksyms
make[5]: Leaving directory '/var/home/zastrix/Documents/openwrt/build_dir/target-armeb_xscale_musl/linux-ixp4xx/linux-5.18-rc1'
make[4]: *** [Makefile:26: /var/home/zastrix/Documents/openwrt/build_dir/target-armeb_xscale_musl/linux-ixp4xx/linux-5.18-rc1/.modules] Error 2
make[4]: Leaving directory '/var/home/zastrix/Documents/openwrt/target/linux/ixp4xx'
make[3]: *** [Makefile:11: compile] Error 2
make[3]: Leaving directory '/var/home/zastrix/Documents/openwrt/target/linux'
time: target/linux/compile#12.69#5.72#339.51
    ERROR: target/linux failed to build.
make[2]: *** [target/Makefile:30: target/linux/compile] Error 1
make[2]: Leaving directory '/var/home/zastrix/Documents/openwrt'
make[1]: *** [target/Makefile:23: /var/home/zastrix/Documents/openwrt/staging_dir/target-armeb_xscale_musl/stamp/.target_compile] Error 2
make[1]: Leaving directory '/var/home/zastrix/Documents/openwrt'
make: *** [/var/home/zastrix/Documents/openwrt/include/toplevel.mk:230: world] Error 2

Edit:

I'd definitely be willing to write documentation on how to do this + eventually create a Dockerfile for container-based builds of this project.

@ismailkisla
Copy link

Hey there! I also bought one from the flea market today and I tried to build my own image for OpenWRT with this but failed as this is my first time doing this so I'm probably doing something wrong.

Thankfully the router has an rj45 console connection and I'm using some random USB->Serial and a hand-made DB9 to rt45 adapter, so I got serial access fairly easily.

I did follow this wiki up to the make menuconfig and I guessed that I have to import the config from _files/ into .config.

If that's wrong, would it be a problem to write some guildes as to how to build the image with these changes?

I saw that this was mentioned:

the last fork of OpenWrt for the XTM 22 is in this repo

But I did get an syntex error during compilation, nor do I really know which settings to enable during compilation (the Y/n prompt).

Error: arch/arm/boot/dts/intel-ixp43x-watchguard-xtm21w.dts:175.3-176.1 syntax error
FATAL ERROR: Unable to parse input tree
make[6]: *** [scripts/Makefile.lib:364: arch/arm/boot/dts/intel-ixp43x-watchguard-xtm21w.dtb] Error 1
make[5]: *** [Makefile:1373: dtbs] Error 2
make[5]: *** Waiting for unfinished jobs....
  HOSTCC  scripts/genksyms/parse.tab.o
  HOSTCC  scripts/genksyms/lex.lex.o
  HOSTLD  scripts/genksyms/genksyms
make[5]: Leaving directory '/var/home/zastrix/Documents/openwrt/build_dir/target-armeb_xscale_musl/linux-ixp4xx/linux-5.18-rc1'
make[4]: *** [Makefile:26: /var/home/zastrix/Documents/openwrt/build_dir/target-armeb_xscale_musl/linux-ixp4xx/linux-5.18-rc1/.modules] Error 2
make[4]: Leaving directory '/var/home/zastrix/Documents/openwrt/target/linux/ixp4xx'
make[3]: *** [Makefile:11: compile] Error 2
make[3]: Leaving directory '/var/home/zastrix/Documents/openwrt/target/linux'
time: target/linux/compile#12.69#5.72#339.51
    ERROR: target/linux failed to build.
make[2]: *** [target/Makefile:30: target/linux/compile] Error 1
make[2]: Leaving directory '/var/home/zastrix/Documents/openwrt'
make[1]: *** [target/Makefile:23: /var/home/zastrix/Documents/openwrt/staging_dir/target-armeb_xscale_musl/stamp/.target_compile] Error 2
make[1]: Leaving directory '/var/home/zastrix/Documents/openwrt'
make: *** [/var/home/zastrix/Documents/openwrt/include/toplevel.mk:230: world] Error 2

Edit:

I'd definitely be willing to write documentation on how to do this + eventually create a Dockerfile for container-based builds of this project.

Hi.
How do this not explanation here.
I figured out how to do it myself

First you must create zimage and create boot image . Than write boot image to a usb stick.
Dont use ubuntu for create images. Use arch linux.

@greguu
Copy link
Owner

greguu commented Mar 12, 2023

@zastrixarundell Hi, first of all thanks for your interest. This kernel is work in progress and only covers XTM 2 series 21/22/23 models and their Wireless version 21-W/22-W/23-W as they are all identical IXP-4xx based hardware. However, the RJ45 console port is only available on the 25/25-W and 26/26-W models. These use a different boot-loader (U-Boot) that is also password locked! I do not have any of these and the password is not known, hence this port does not cover this model, unfortunately.

@zastrixarundell
Copy link

zastrixarundell commented Mar 13, 2023

@zastrixarundell Hi, first of all thanks for your interest. This kernel is work in progress and only covers XTM 2 series 21/22/23 models and their Wireless version 21-W/22-W/23-W as they are all identical IXP-4xx based hardware. However, the RJ45 console port is only available on the 25/25-W and 26/26-W models. These use a different boot-loader (U-Boot) that is also password locked! I do not have any of these and the password is not known, hence this port does not cover this model, unfortunately.

Thanks for the answer! I spent hours trying to hook up an internal UART port thinking that the rj45 is just doesn't allow to use the password (as I was not getting an error when I typed the one linked in this repo so I thought that it was just not allowed via the accessible port).

In this scenario I'm probably going to keep it somewhere as a glorified switch, if I can even use it like one, but if in any case you want to update the scope of this project just tag me here. I have these two models:

HW MODEL # XP2E62
HW MODEL # FS1E5W

@greguu
Copy link
Owner

greguu commented Mar 13, 2023

@zastrixarundell If you want, can you share some photo of the mainboard to see the internal layout of these models as well as the boot prompt you get via the RJ45 port ? Just to complete the picture. Perhaps try some U-Boot commands to see if you can get the version and more details etc. I assume it should tell you if you enter the correct password and allow further commands. For the password prompt on Redboot you need to push CTRL+C at boot, not sure about U-Boot.

@zastrixarundell
Copy link

Thanks for the answer @greguu.

Here's the menu (yes I can CTRL+C and type in the password). After typing in the password from the repo it just ignores the input and I can use my arrow keys to continue booting.


          WatchGuard U-Boot 2011.03 - 430854 - Sep 17 2013 14:10:34

 +-------------------------------------------------------------------------+
 |WatchGuard (SYSA)                                                        |
 |WatchGuard (SYSB)                                                        |
 |WatchGuard (SAFE MODE)                                                   |
 |                                                                         |
 |                                                                         |
 |                                                                         |
 |                                                                         |
 |                                                                         |
 |                                                                         |
 |                                                                         |
 |                                                                         |
 +-------------------------------------------------------------------------+

      Use the ^ and v keys to select which entry is highlighted.
      Press enter to boot the selected OS.






password> 

Here is the entire boot sequence:


          WatchGuard U-Boot 2011.03 - 430854 - Sep 17 2013 14:10:34

 +-------------------------------------------------------------------------+
 |WatchGuard (SYSA)                                                        |
 |WatchGuard (SYSB)                                                        |
 |WatchGuard (SAFE MODE)                                                   |
 |                                                                         |
 |                                                                         |
 |                                                                         |
 |                                                                         |
 |                                                                         |
 |                                                                         |
 |                                                                         |
 |                                                                         |
 +-------------------------------------------------------------------------+

      Use the ^ and v keys to select which entry is highlighted.
      Press enter to boot the selected OS.






password> asdasdasd
Booting SYSA

NAND read: device 0 offset 0x20000, size 0x500000
Bad block table found at page 131008, version 0x01
Bad block table found at page 130944, version 0x01
nand_read_bbt: Bad block at 0x000001f60000
nand_read_bbt: Bad block at 0x000002420000
nand_read_bbt: Bad block at 0x000005cc0000
nand_read_bbt: Bad block at 0x000007d40000
 5242880 bytes read: OK
## Booting kernel from FIT Image at 01000000 ...
   Using 'conf@1' configuration
   Trying 'kernel@1' kernel subimage
     Description:  WatchGuard Kernel
     Type:         Kernel Image
     Compression:  gzip compressed
     Data Start:   0x010000cc
     Data Size:    2919777 Bytes = 2.8 MiB
     Architecture: PowerPC
     OS:           Linux
     Load Address: 0x00000000
     Entry Point:  0x00000000
     Hash algo:    crc32
     Hash value:   2f9ae4d7
     Hash algo:    sha1
     Hash value:   2234353c9c5c5b521ee5a09d6e0f61101afd58d0
   Verifying Hash Integrity ... crc32+ sha1+ OK
## Flattened Device Tree from FIT Image at 01000000
   Using 'conf@1' configuration
   Trying 'fdt@1' FDT blob subimage
     Description:  Flattened Device Tree blob
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x012c8f58
     Data Size:    9867 Bytes = 9.6 KiB
     Architecture: PowerPC
     Hash algo:    crc32
     Hash value:   a937f12f
     Hash algo:    sha1
     Hash value:   be4a0630b151dcf676c537f39afd699d60e1bec4
   Verifying Hash Integrity ... crc32+ sha1+ OK
   Booting using the fdt blob at 0x12c8f58
   Uncompressing Kernel Image ... OK
   Loading Device Tree to 00ffa000, end 00fff68a ... OK
[    0.000000] Reserving 16MB of memory at 256MB for crashkernel (System RAM: 512MB)
[    0.000000] Using P1020 RDB machine description
[    0.000000] Only using first contiguous memory region
[    0.000000] Memory CAM mapping: 256/256 Mb, residual: 0Mb
[    0.000000] Linux version 3.0.34 (release@cmfarm03) (gcc version 4.4.5 (WatchGuard Inc./crosstool-ng version: 0.1.5/1.9.0) ) #1 SMP Sun Sep 21 19:15:56 PDT 2014
[    0.000000] CPU maps initialized for 1 thread per core
[    0.000000] bootconsole [udbg0] enabled
setup_arch: bootmem
mpc85xx_rdb_setup_arch()
[    0.000000] Found FSL PCI host bridge at 0x00000000ffe0a000. Firmware bus number: 0->1
[    0.000000] PCI host bridge /pcie@ffe0a000  ranges:
[    0.000000]  MEM 0x0000000080000000..0x000000009fffffff -> 0x0000000080000000 
[    0.000000]   IO 0x00000000ffc00000..0x00000000ffc0ffff -> 0x0000000000000000
[    0.000000] /pcie@ffe0a000: PCICSRBAR @ 0xfff00000
[    0.000000] MPC85xx RDB board from Freescale Semiconductor
arch: exit
[    0.000000] Zone PFN ranges:
[    0.000000]   DMA      0x00000000 -> 0x00020000
[    0.000000]   Normal   empty
[    0.000000] Movable zone start PFN for each node
[    0.000000] early_node_map[1] active PFN ranges
[    0.000000]     0: 0x00000000 -> 0x00020000
[    0.000000] MMU: Allocated 1088 bytes of context maps for 255 contexts
[    0.000000] PERCPU: Embedded 7 pages/cpu @a0b13000 s5728 r8192 d14752 u32768
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 130048
[    0.000000] Kernel command line: root=/dev/mtdblock8 rw rootfstype=jffs2 console=ttyS0,115200 ramdisk_size=600000
[    0.000000] PID hash table entries: 2048 (order: 1, 8192 bytes)
[    0.000000] Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
[    0.000000] Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
[    0.000000] Memory: 496068k/524288k available (5732k kernel code, 28220k reserved, 264k data, 1221k bss, 228k init)
[    0.000000] Kernel virtual memory layout:
[    0.000000]   * 0xfffdf000..0xfffff000  : fixmap
[    0.000000]   * 0xfdfeb000..0xfe000000  : early ioremap
[    0.000000]   * 0xc1000000..0xfdfeb000  : vmalloc & ioremap
[    0.000000] SLUB: Genslabs=15, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] Hierarchical RCU implementation.
[    0.000000] NR_IRQS:512
[    0.000000] mpic: Setting up MPIC " OpenPIC  " version 1.2 at ffe40000, max 1 CPUs
[    0.000000] mpic: ISU size: 256, shift: 8, mask: ff
[    0.000000] mpic: Initializing for 256 sources
[    0.000000] clocksource: timebase mult[7800001] shift[22] registered
[    0.000000] Console: colour dummy device 80x25
[    0.010795] pid_max: default: 32768 minimum: 301
L�}�JQPD[P�!.cYY�Q[���J564�[@�b$���W�)P
                                                                                                                            2![*+A��*�[    2.697882] Empty flash at 0x058f74c0 ends at 0x058f7800
[    3.419702] VFS: Mounted root (jffs2 filesystem) on device 31:8.[!.�,�9��XKqP+��51�BX��V@[P!.X���B9W9I:��Vk)V�K��
[    3.425803] Freeing unused kernel memory: 228k init
[    8.155412] Running /etc/runlevel/1/S02rootrw...Done.
[    8.163560] Running /etc/runlevel/1/S05mproc...Done.
[    8.166057] Running /etc/runlevel/1/S05sysfs...Done.
[    8.168957] Running /etc/runlevel/1/S18seed-random...Reseeded random generator
[    8.236671] Done.
[    8.297808] Running /etc/runlevel/2/S10var...Done.
[    8.313814] Running /etc/runlevel/2/S11shm...Done.
[    8.322340] Running /etc/runlevel/2/S13devpts...Done.
[    8.347303] Running /etc/runlevel/2/S14temp...Done.
[    8.349904] Running /etc/runlevel/2/S16pending...Done.
[    8.350994] Running /etc/runlevel/2/S17talitos...[    8.109702] talitos ffe30000.crypto: hwrng
[    8.114000] alg: No test for authenc(hmac(sha1),cbc(aes)) (authenc-hmac-sha1-cbc-aes-talitos)
[    8.122761] talitos ffe30000.crypto: authenc-hmac-sha1-cbc-aes-talitos
[    8.129562] alg: No test for authenc(hmac(sha1),cbc(des3_ede)) (authenc-hmac-sha1-cbc-3des-talitos)
[    8.138819] talitos ffe30000.crypto: authenc-hmac-sha1-cbc-3des-talitos
[    8.146428] setting trigger mode 0 for irq 37 failed (mpc8xxx_irq_set_type+0x0/0x118)
[    8.154885] setting trigger mode 0 for irq 38 failed (mpc8xxx_irq_set_type+0x0/0x118)
[    8.163221] setting trigger mode 0 for irq 39 failed (mpc8xxx_irq_set_type+0x0/0x118)
[    8.171525] setting trigger mode 0 for irq 40 failed (mpc8xxx_irq_set_type+0x0/0x118)
[    8.179828] setting trigger mode 0 for irq 41 failed (mpc8xxx_irq_set_type+0x0/0x118)
[    8.188134] setting trigger mode 0 for irq 44 failed (mpc8xxx_irq_set_type+0x0/0x118)
[    8.196429] setting trigger mode 0 for irq 46 failed (mpc8xxx_irq_set_type+0x0/0x118)
[    8.208800] alg: No test for authenc(hmac(sha256),cbc(aes)) (authenc-hmac-sha256-cbc-aes-talitos)
[    8.218245] talitos ffe30000.crypto: authenc-hmac-sha256-cbc-aes-talitos
[    8.225414] alg: No test for authenc(hmac(sha256),cbc(des3_ede)) (authenc-hmac-sha256-cbc-3des-talitos)
[    8.235197] talitos ffe30000.crypto: authenc-hmac-sha256-cbc-3des-talitos
[    8.242429] alg: No test for authenc(hmac(md5),cbc(aes)) (authenc-hmac-md5-cbc-aes-talitos)
[    8.251169] talitos ffe30000.crypto: authenc-hmac-md5-cbc-aes-talitos
[    8.258054] alg: No test for authenc(hmac(md5),cbc(des3_ede)) (authenc-hmac-md5-cbc-3des-talitos)
[    8.267318] talitos ffe30000.crypto: authenc-hmac-md5-cbc-3des-talitos
[    8.274593] talitos ffe30000.crypto: cbc-aes-talitos
[    8.279971] talitos ffe30000.crypto: cbc-3des-talitos
[    8.287469] talitos ffe30000.crypto: md5-talitos
[    8.292608] talitos ffe30000.crypto: sha1-talitos
[    8.297725] talitos ffe30000.crypto: sha224-talitos
[    8.303005] talitos ffe30000.crypto: sha256-talitos
[    8.308417] talitos ffe30000.crypto: sha384-talitos
[    8.313803] talitos ffe30000.crypto: sha512-talitos
[    8.318942] alg: No test for authenc(hmac(sha1),cbc(cipher_null)) (authenc-hmac-sha1-cbc-cipher-null-talitos)
[    8.329075] talitos ffe30000.crypto: authenc-hmac-sha1-cbc-cipher-null-talitos
[    8.336561] alg: No test for authenc(hmac(sha256),cbc(cipher_null)) (authenc-hmac-sha256-cbc-cipher-null-talitos)
[    8.347034] talitos ffe30000.crypto: authenc-hmac-sha256-cbc-cipher-null-talitos
[    8.354696] alg: No test for authenc(hmac(sha384),cbc(cipher_null)) (authenc-hmac-sha384-cbc-cipher-null-talitos)
[    8.365167] talitos ffe30000.crypto: authenc-hmac-sha384-cbc-cipher-null-talitos
[    8.372830] alg: No test for authenc(hmac(sha512),cbc(cipher_null)) (authenc-hmac-sha512-cbc-cipher-null-talitos)
[    8.383299] talitos ffe30000.crypto: authenc-hmac-sha512-cbc-cipher-null-talitos
[    8.390966] alg: No test for authenc(hmac(sha384),cbc(aes)) (authenc-hmac-sha384-cbc-aes-talitos)
[    8.400043] talitos ffe30000.crypto: authenc-hmac-sha384-cbc-aes-talitos
[    8.407006] alg: No test for authenc(hmac(sha384),cbc(des3_ede)) (authenc-hmac-sha384-cbc-3des-talitos)
[    8.416608] talitos ffe30000.crypto: authenc-hmac-sha384-cbc-3des-talitos
[    8.423657] alg: No test for authenc(hmac(sha512),cbc(aes)) (authenc-hmac-sha512-cbc-aes-talitos)
[    8.432744] talitos ffe30000.crypto: authenc-hmac-sha512-cbc-aes-talitos
[    8.439710] alg: No test for authenc(hmac(sha512),cbc(des3_ede)) (authenc-hmac-sha512-cbc-3des-talitos)
[    8.449312] talitos ffe30000.crypto: authenc-hmac-sha512-cbc-3des-talitos
[    8.456376] alg: No test for authenc(digest_null,cbc(aes)) (authenc-digest-null-cbc-aes-talitos)
[    8.465367] talitos ffe30000.crypto: authenc-digest-null-cbc-aes-talitos
[    8.472349] alg: No test for authenc(digest_null,cbc(des3_ede)) (authenc-digest-null-cbc-3des-talitos)
[    8.481864] talitos ffe30000.crypto: authenc-digest-null-cbc-3des-talitos
[    8.488936] talitos ffe30000.crypto: ablk-cbc-aes-talitos
[    8.494604] talitos ffe30000.crypto: ablk-cbc-3des-talitos
[    8.500371] alg: No test for auth(sha1) (auth-sha1-talitos)
[    8.506140] talitos ffe30000.crypto: auth-sha1-talitos
[    8.511533] alg: No test for auth(sha256) (auth-sha256-talitos)
[    8.517651] talitos ffe30000.crypto: auth-sha256-talitos
[    8.523223] alg: No test for auth(sha384) (auth-sha384-talitos)
[    8.529341] talitos ffe30000.crypto: auth-sha384-talitos
[    8.534919] alg: No test for auth(sha512) (auth-sha512-talitos)
[    8.541048] talitos ffe30000.crypto: auth-sha512-talitos
Done.
[    8.997172] Running /etc/runlevel/2/S18data...[    8.913823] Empty flash at 0x00de48a4 ends at 0x00de5000
Done.
[   10.740974] Running /etc/runlevel/2/S18hotplug...Done.
[   14.127075] Running /etc/runlevel/2/S18kdump...Done.
[   18.105751] Running /etc/runlevel/2/S19fips...Done.
[   18.111638] Running /etc/runlevel/2/S19ipv6...disabling IPv6 autoconf for all
[   18.115428] disabling IPv6 autoconf for default
[   18.115773] enable IPv6 forwarding for all
[   18.116065] enable IPv6 forwarding for default
[   18.116401] disabling IPv6 for all
[   18.116637] disabling IPv6 for default
[   18.116901] Done.
[   18.117128] Running /etc/runlevel/2/S20cleanup-dbg...Done.
[   18.121112] Running /etc/runlevel/2/S20fipstest...Done.
[   18.121513] Running /etc/runlevel/2/S20sigs...Done.
[   19.546917] Running /etc/runlevel/2/S20usb...[   19.147199] Initializing USB Mass Storage driver...
[   19.155596] usbcore: registered new interface driver usb-storage
[   19.161692] USB Mass Storage support registered.
Done.
[   19.616873] Running /etc/runlevel/2/S20wgbase...[   19.182476] wgipc: module license 'Watchguard Proprietary' taints kernel.
[   19.189316] Disabling lock debugging due to kernel taint
Done.
[   19.656598] Running /etc/runlevel/2/S21eth...[   19.230588] 
[   19.230593] wg_dsa_init: Built Sep 21 2014 19:17:46 P1011 SW 1 Flags 2929
[   19.230599] 
[   19.240459] wg_dsa_init: Rename eth1 -> eth3
[   19.248808] wg_dsa_init: Rename eth0 -> sw10
[   19.260458] Distributed Switch Architecture driver version 0.1
[   19.268699] sw10[0]: detected a Marvell 88E6171 switch
[   19.844659] dsa slave smi: probed
[   19.848032] dsa_slave_create: eth0 Marvell headers enabled, len 16
[   19.908416] dsa_slave_create: eth1 Marvell headers enabled, len 16
[   19.968366] dsa_slave_create: eth2 Marvell headers enabled, len 16
[   20.028398] wg_dsa_init: Split sw10
[   20.031903] wg_dsa_init: Rename eth3 -> sw11
[   20.046167] sw11[0]: detected a Marvell 88E6171 switch
[   20.626921] dsa slave smi: probed
[   20.630366] dsa_slave_create: eth3 Marvell headers enabled, len 16
[   20.690335] dsa_slave_create: eth4 Marvell headers enabled, len 16
[   20.751902] wg_dsa_init: Split sw11
[   22.761614] gfar_init_mac: sw10: L2OFF  2  Pad   8 RCTRL   20817ca
[   22.768414] ADDRCONF(NETDEV_UP): sw10: link is not ready
[   22.778064] gfar_init_mac: sw11: L2OFF  2  Pad   8 RCTRL   20817ca
[   22.784823] ADDRCONF(NETDEV_UP): sw11: link is not ready
Done.
[   23.240889] Running /etc/runlevel/2/S22login...Done.
[   23.243484] Running /etc/runlevel/2/S22rtc...Done.
[   23.252920] Running /etc/runlevel/2/S23pppoe...[   22.854223] PPP generic driver version 2.4.2
[   22.899663] PPP MPPE Compression module registered
[   22.913413] PPP Deflate Compression module registered
[   22.926325] NET: Registered protocol family 24
Done.
[   23.398976] Running /etc/runlevel/2/S23sslvpn...[   22.976229] tun: Universal TUN/TAP device driver, 1.6
[   22.981356] tun: (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>
Done.
[   23.443074] Running /etc/runlevel/2/S24l2tpvpn...[   23.016948] L2TP core driver, V2.0
[   23.032550] L2TP netlink interface
[   23.059341] PPPoL2TP kernel driver, V2.0
Done.
[   23.513867] Running /etc/runlevel/2/S25core...Done.
[   23.519323] Running /etc/runlevel/2/S25wgcfg...[   24.756291] PHY: 0:01 - Link is Up - 1000/Full
[   24.761323] ADDRCONF(NETDEV_CHANGE): sw10: link becomes ready
[   24.772337] PHY: 0:02 - Link is Up - 1000/Full
[   24.777171] ADDRCONF(NETDEV_CHANGE): sw11: link becomes ready
Info: No conversion required from version 11.9.3 to 11.9.3.
[   28.389624] Done.
[   28.389793] Running /etc/runlevel/2/S27cfgcheck...Config ok
[   30.934335] Done.
[   30.934523] Running /etc/runlevel/2/S29firewall...Done.
[   30.937218] Running /etc/runlevel/2/S29wgcore...Done.
[   30.974731] Running /etc/runlevel/2/S30bonding...[   30.628317] bonding: Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)
[   30.635515] bonding: MII link monitoring set to 100 ms
Done.
[   31.091317] Running /etc/runlevel/2/S30net...[   30.725195] Bridge firewalling registered
[   30.750745] Ebtables v2.0 registered
[   30.867576] GRE over IPv4 demultiplexor driver
[   30.897400] GRE over IPv4 tunneling driver
[   30.916403] bvpn vif handlers are registered
[   30.954372] 802.1Q VLAN Support v1.8
Done.
[   31.425689] Running /etc/runlevel/2/S30upgrade...Done.
[   31.432692] Running /etc/runlevel/2/S31cacert...Done.
[   31.669754] Running /etc/runlevel/2/S31cert...[   35.881796] JFFS2 notice: (200) check_node_data: wrong data CRC in data node at 0x05c19c70: read 0xd8d54e2f, calculated 0x3f7d0134.
Done.
[   38.031628] Running /etc/runlevel/2/S31crypto...Done.
[   38.073524] Running /etc/runlevel/2/S31purgecert...Done.
[   38.075013] Running /etc/runlevel/2/S31xtables...[   37.638335] Netfilter messages via NETLINK v0.30.
[   37.664006] ip_set_init[1869]: ip_set: protocol 5
[   37.968360] nf_conntrack version 0.5.0 (7770 buckets, 31080 max)
[   37.974627] nf_conntrack_init_init_net: conntrack max=31080 high water mark=24864
[   38.031671] ip_tables: (C) 2000-2006 Netfilter Core Team
[   38.091286] nf_ct_ftp: Maximum expected value 1
[   38.208660] NF_TPROXY: Transparent proxy support initialized, version 4.1.0
[   38.215679] NF_TPROXY: Copyright (c) 2006-2007 BalaBit IT Ltd.
[   38.255022] ctnetlink v0.93: registering with nfnetlink.
[   38.539698] arp_tables: (C) 2002 David S. Miller
[   38.629212] u32 classifier
[   38.631944]     Performance counters on
[   38.635818]     input device check on
[   38.639495]     Actions configured
[   38.688883] Mirror/redirect action on
Done.
[   39.166928] Running /etc/runlevel/2/S31xtables6...Done.
[   39.229803] Running /etc/runlevel/2/S32auth...Done.
[   39.263325] Running /etc/runlevel/2/S32clst...Done.
[   39.416861] Running /etc/runlevel/2/S32modemdrivers...[   39.011078] USB Serial support registered for GSM modem (1-port)
[   39.020686] usbcore: registered new interface driver option
[   39.026325] option: v0.7.2:USB Driver for GSM modems
[   39.054471] USB Serial support registered for Sierra USB modem
[   39.063549] usbcore: registered new interface driver sierra
[   39.069204] wg_sierra: v.1.7.40:USB Driver for Sierra Wireless USB modems
[   39.103422] usbcore: registered new interface driver cdc_acm
[   39.109190] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
[   39.135015] USB Serial support registered for GobiSerial
[   39.145828] usbcore: registered new interface driver GobiSerial
[   39.151848] GobiSerial: 2013-10-08/NTGR_2.12
[   39.192679] usbcore: registered new interface driver cdc_ether
[   39.215938] usbcore: registered new interface driver rndis_host
[   39.242132] usbcore: registered new interface driver sierra_net
[   39.311446] GobiNet: 2013-10-08/NTGR_2.21
[   39.321033] usbcore: registered new interface driver GobiNet
Done.
[   39.777210] Running /etc/runlevel/2/S32wgxt...[   39.357503] ipt_addrpairs_6 v0.1.0: Loading
[   39.402701] xt_session6 : Loading
[   39.406109] xt_session6 : Loaded limit 1000 hash 1024 WG IPC ID 184549376 (0x0B000000)
[   39.480791] ipt_addrpairs: ADDRPAIRS SCALE Set MAX 16384 Entry Max 16384
[   39.487758] ipt_addrpairs: v1.0.0 Loaded
[   39.517940] xt_ifset: Loaded with set limit 5000 and entry limit 5000
[   39.531733] xt_classify : Loaded
[   39.542442] xt_master: Loaded
[   39.552904] xt_MASTER: Loaded
[   39.563500] xt_WGTEE: Loaded
[   39.574914] Schedule: Loaded
[   39.584673] xt_POLICY: Loaded
[   39.595508] xt_policy : Loaded
[   39.605974] xt_EXPIRES: Loaded
[   39.616151] xt_IPPRECEDENCE: Loaded
[   39.632510] xt_PKTCACHE: Loaded
[   39.684607] xt_session : Loaded limit 1000 hash 1024 WG IPC ID 92274688 (0x05800000)
[   39.749521] xt_CONNCLASSIFY: Loaded
[   39.759714] xt_connclassify : Loaded
[   39.772348] xt_ipspoof : Loaded
[   39.827425] xt_LBDNAT: Loaded
[   39.865949] xt_MWAN: Loaded
[   39.891562] xt_psd: Loaded
[   39.904311] xt_ipsd: Loaded
[   39.917028] xt_ddos: Loaded
[   39.930221] xt_dos: Loaded
[   39.953850] xt_wgaccount: Loaded
[   40.011580] xt_block : Loaded limit 1000 hash 1024 WG IPC ID 155189248
[   40.033417] xt_localroute: Loaded
[   40.051472] xt_duplicate: Loaded
[   40.085045] xt_WGCLASSIFY: Loaded
Done.
[   40.565823] Running /etc/runlevel/2/S33appID...[   40.489786] * Make sure sizeof(struct sw_struct)=76 is consistent
[   40.505692] WG workqueue: Loaded
[   40.576908] bw driver: Loaded
Done.
[   41.030400] Running /etc/runlevel/2/S35nropen...updated /proc/sys/fs/nr_open with new value: 2097152
[   41.035509] Done.
[   41.040382] Running /etc/runlevel/2/S35proxy...[   40.602175] Proxy glue: Loaded 19:27:53 (196)
Setting the proxy tmpfs size to size=121m.
[   41.178748] Done.
[   41.178977] Running /etc/runlevel/2/S35scand...Done.
[   48.877292] Running /etc/runlevel/2/S36dynroute...Done.
[   48.879721] Running /etc/runlevel/2/S42ssh...Done.
[   48.884992] Running /etc/runlevel/2/S44sysb...Done.
[   49.374709] Running /etc/runlevel/2/S50nettune...Setting IPv4 route garbage collection timeout to 2 minutes
[   49.377725] Setting promote_secondaries to 1
[   49.378067] Done.
[   49.379352] Running /etc/runlevel/2/S53configdhash...Done.
[   49.380396] Running /etc/runlevel/2/S54[   48.949249] Compat-wireless backport release: compat-wireless-v3.6.8-1
wireless...[   48.956877] Backport based on linux-stable.git v3.6.8
[   48.962851] compat.git: linux-stable.git
[   49.170060] cfg80211: Calling CRDA to update world regulatory domain
[   49.190752] cfg80211: World regulatory domain updated:
[   49.195969] cfg80211:   (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
[   49.204187] cfg80211:   (2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
[   49.211963] cfg80211:   (2457000 KHz - 2482000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
[   49.219736] cfg80211:   (5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
[   49.227511] cfg80211:   (5735000 KHz - 5835000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
[   50.082340] cfg80211: Calling CRDA for country: US
[   50.090644] ieee80211 phy0: Atheros AR9300 Rev:3 mem=0xc52c0000, irq=16
start load wireless modules
[   50.553971] Done.
[   50[   50.108154] cfg80211: Regulatory domain changed to country: US
.554108] Running[   50.114611] cfg80211:   (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
 /etc/runlevel/2[   50.124150] cfg80211:   (2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, 2700 mBm)
/S80seed-random.[   50.133295] cfg80211:   (5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi, 1700 mBm)
..[   50.142432] cfg80211:   (5250000 KHz - 5330000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
[   50.150337] cfg80211:   (5490000 KHz - 5600000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
[   50.158111] cfg80211:   (5650000 KHz - 5710000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
[   50.165885] cfg80211:   (5735000 KHz - 5835000 KHz @ 40000 KHz), (300 mBi, 3000 mBm)
[   50.173658] cfg80211:   (57240000 KHz - 63720000 KHz @ 2160000 KHz), (N/A, 4000 mBm)
Saved random seed
[   50.666135] Done.
[   50.666421] Running /etc/runlevel/2/S90bootmon...Done.
[   50.682920] Running /etc/runlevel/2/S90kcrashrep...Done.
[   50.686081] Running /etc/runlevel/2/S98setmacs...setting device eth0 to 00:90:7f:a2:e8:48
[   50.831251] setting device eth1 to 00:90:7f:a2:e8:49
[   50.831643] setting device eth2 to 00:90:7f:a2:e8:4a
[   50.832008] setting device eth3 to 00:90:7f:a2:e8:4b
[   50.832372] setting device eth4 to 00:90:7f:a2:e8:4c
[   50.833514] Done.
[   50.833654] Running /etc/runlevel/2/S99igmp...Done.
[   50.836374] Running /etc/runlevel/2/S99rootro...Done.
[   58.799204] xt_connbytes: Forcing CT accounting to be enabled
[   60.448963] xt_wgaccount: Requested policy limit 9 is not larger than current limit 100 so limit will not change
[   61.291419] xt_session: TS is shut down by configuration data, ts count: 0 len : 0
[   65.147774] device sw10 entered promiscuous mode
[   65.152759] ADDRCONF(NETDEV_UP): eth0: link is not ready
[   65.489277] ADDRCONF(NETDEV_UP): eth1: link is not ready
[   65.515873] ADDRCONF(NETDEV_UP): eth2: link is not ready
[   65.541632] device sw11 entered promiscuous mode
[   65.546532] ADDRCONF(NETDEV_UP): eth3: link is not ready
[   65.572530] ADDRCONF(NETDEV_UP): eth4: link is not ready
[   66.119806] Running /etc/runlevel/4/S54setmacwifi...setmacs(wifi): set wlan0 interface mac address to 00:90:7F:A2:E8:4E
[   66.137835] Done.

WatchGuard-XTM login:

Here is the archived URL for the xtm2 model which I have. It has the images of the motherboard on both sides.

It's 3am here so I'll send the images (and boot log) for the other machine tomorrow during the day. It has an rs232 connector which I can thankfully connect to.

Also quick question: Which type of VPN services does this project support when it's being ran on the mechine? Does it support only OpenVPN or does it also support Wireguard VPN?

@greguu
Copy link
Owner

greguu commented Mar 13, 2023

@zastrixarundell Thanks for these details.

Once you boot into the vendor system, you can logon usually using the default credentials. Once in, you can dump more info to a USB stick that you plugin, such as system details, kernel modules used etc, via various system specific commands. If you have a vendor logon to their support site, you can download a image file you can extract and inspect as well for kernel config etc. However, this is in the end only useful if there is a way to flash a custom U-Boot or get the U-Boot password, so you can boot your own kernel and rootfs. I did ask the vendor ages ago about their kernel source, but never heard back. I doubt they release the U-Boot password.

The specs on these boxes are still reasonable and with a bit of effort run a recent linux kernel that will allow you OpenWrt etc and your choice of VPN. For the 21-W model, I managed to get most things working, just not the NAND and the Realtek switch yet. However, its time consuming work to keep up with mainline and re-build and test. I will continue with the IXP4xx based models eventually.

@corzani
Copy link

corzani commented Apr 9, 2023

Hi all,
what about XTM 800 series? Does anyone ever dealt with it?
http://watchguard.optrics.com/images/products/xtm/xtm800-mainprod.jpg

@greguu
Copy link
Owner

greguu commented Apr 10, 2023

@corzani Hi, the XTM 800/1500 series should be x86_64 and have an unlocked bootloader. Also around are their predecessors, X750/1000/1250 series, based on X86_32. You can find some guides online on how to run alternative OS on these. This project just covers the XTM21/22/23 series

@readnotify
Copy link

Has anyone considered a different approach... simply adjusting the existing system to let you remove their custom stuff and manually set up whatever config you want through a shell?

e.g. I see this in the boot...
[ 48.879721] Running /etc/runlevel/2/S42ssh...Done.

I've done something similar in the past on a netgear router - once inside, I found "busybox" with every tool I could want, plus google lead me to some other custom binaries that run on that device just fine.

@greguu
Copy link
Owner

greguu commented May 1, 2023

@readnotify I explored it, but as you say, its rather custom setup that Watchguard has on these, including an ancient 2.6 kernel and some licensing stuff. While its relatively easy to get the vendor rootfs out of the offical upgrade file, it would be a bit of messing around to get some static binaries injected that will run with this old kernel. IMHO, the best approach is still to complete the device-tree for this board and get the RTK switch going on 6.x kernel. Its actually not that much more work for someone familiar with the matter as just the NAND config in the .dts and the Realtek switch are missing.

@ellisonmax
Copy link

Hello friend,
Thank you for your project! I have five unused xtm21w devices and I'm trying to give new life to one of them.
I tried the v18.06.9 version of OpenWrt, and it generated the following files:

root@debian:~/openwrt/bin/targets/ixp4xx/generic# ls -lha
total 65M
drwxr-xr-x 4 root root 4.0K Jul 22 16:19 .
drwxr-xr-x 3 root root 4.0K Jul 22 15:55 ..
drwxr-xr-x 2 root root 4.0K Jul 22 16:02 apex
-rw-r--r-- 1 root root  147 Jul 22 15:55 config.seed
-rw-r--r-- 1 root root 1.4M Jul 22 16:18 openwrt-ixp4xx-generic-ap1000-zImage
-rw-r--r-- 1 root root 1.4M Jul 22 16:18 openwrt-ixp4xx-generic-ap42x-zImage
-rw-r--r-- 1 root root 1.4M Jul 22 16:18 openwrt-ixp4xx-generic-avila-zImage
-rw-r--r-- 1 root root 1.4M Jul 22 16:18 openwrt-ixp4xx-generic-cambria-zImage
-rw-r--r-- 1 root root 1.4M Jul 22 16:18 openwrt-ixp4xx-generic-compex-zImage
-rw-r--r-- 1 root root 2.0K Jul 22 16:19 openwrt-ixp4xx-generic-default.manifest
-rw-r--r-- 1 root root 1.4M Jul 22 16:18 openwrt-ixp4xx-generic-dsmg600-zImage
-rw-r--r-- 1 root root 3.6M Jul 22 16:19 openwrt-ixp4xx-generic-fsg3-squashfs.img
-rw-r--r-- 1 root root 3.6M Jul 22 16:19 openwrt-ixp4xx-generic-fsg3-squashfs-webupgrade.img
-rw-r--r-- 1 root root 1.4M Jul 22 16:18 openwrt-ixp4xx-generic-fsg3-zImage
-rw-r--r-- 1 root root 1.4M Jul 22 16:18 openwrt-ixp4xx-generic-gateway7001-zImage
-rw-r--r-- 1 root root 1.4M Jul 22 16:18 openwrt-ixp4xx-generic-ixdpg425-zImage
-rw-r--r-- 1 root root 1.4M Jul 22 16:18 openwrt-ixp4xx-generic-loft-zImage
-rw-r--r-- 1 root root 1.4M Jul 22 16:18 openwrt-ixp4xx-generic-nas100d-zImage
-rw-r--r-- 1 root root  16M Jul 22 16:19 openwrt-ixp4xx-generic-nslu2-squashfs-16mb.bin
-rw-r--r-- 1 root root 8.0M Jul 22 16:19 openwrt-ixp4xx-generic-nslu2-squashfs.bin
-rw-r--r-- 1 root root 1.4M Jul 22 16:18 openwrt-ixp4xx-generic-nslu2-zImage
-rw-r--r-- 1 root root 1.4M Jul 22 16:18 openwrt-ixp4xx-generic-pronghornmetro-zImage
-rw-r--r-- 1 root root 1.4M Jul 22 16:18 openwrt-ixp4xx-generic-pronghorn-zImage
-rw-r--r-- 1 root root 1.4M Jul 22 16:18 openwrt-ixp4xx-generic-sidewinder-zImage
-rw-r--r-- 1 root root 2.2M Jul 22 16:19 openwrt-ixp4xx-generic-squashfs.img
-rw-r--r-- 1 root root 3.5M Jul 22 16:19 openwrt-ixp4xx-generic-squashfs-sysupgrade.bin
-rw-r--r-- 1 root root 1.4M Jul 22 16:18 openwrt-ixp4xx-generic-tw2662-zImage
-rw-r--r-- 1 root root 1.4M Jul 22 16:18 openwrt-ixp4xx-generic-tw5334-zImage
-rw-r--r-- 1 root root 1.4M Jul 22 16:18 openwrt-ixp4xx-generic-wg302v1-zImage
-rw-r--r-- 1 root root 1.4M Jul 22 16:18 openwrt-ixp4xx-generic-wg302v2-zImage
-rw-r--r-- 1 root root 1.4M Jul 22 16:18 openwrt-ixp4xx-generic-wrt300nv2-zImage
-rwxr-xr-x 1 root root 1.4M Jul 22 16:18 openwrt-ixp4xx-generic-zImage
drwxr-xr-x 2 root root 4.0K Jul 22 16:19 packages
-rw-r--r-- 1 root root 3.0K Jul 22 16:19 sha256sums

I loaded the file openwrt-ixp4xx-generic-zImage via serial but it doesn't load. It stops at this point:

RedBoot>                                                                                                           
RedBoot> load -m ymodem -r -v -b %{FREEMEMLO} zImage                                                               
CRaw file loaded 0x001d0000-0x0031e88f, assumed entry at 0x001d0000                                                
xyzModem - CRC mode, 10708(SOH)/1(STX)/0(CAN) packets, 6 retries                                                   
RedBoot>                                                                                                           
RedBoot>                                                                                                           
RedBoot> exec -c "console=ttyS0,115200 root=/dev/sda1 rootdelay=12" -w 5                                           
argc:5                                                                                                             
argv:exec                                                                                                          
argv:-c                                                                                                            
argv:console=ttyS0,115200 root=/dev/sda1 rootdelay=12                                                              
argv:-w                                                                                                            
argv:5                                                                                                             
About to start execution at 0x06000000 - abort with ^C within 5 seconds                                            
Using base address 0x001d0000 and length 0x0014e890                                                                
Uncompressing Linux... done, booting the kernel.

Any idea what I'm doing wrong?

@greguu
Copy link
Owner

greguu commented Jul 25, 2023

@ellisonmax Hello, it seems the kernel you are trying to boot does not have serial console output enabled. The last OpenWrt test build I did was using these sources https://github.com/greguu/openwrt
Building from these should create a Watchguard specific zImage and a very basic rootfs. You still need to add the watchguard specific .dtb file (it will be build as well) to the zImage ,eg. cat zImage <filename>.dtb > zImage_w_dtb before you can boot it. I have not worked on this since last year unfortunately, but hope to pick up on it again.

@greguu
Copy link
Owner

greguu commented Sep 24, 2023

@LeonG71 Thanks, I was following LinusW effort to revive ixp4xx support in OpenWrt.
I have updated the patches for v6.1 and did a build for those interested.

rootfs and kernel: https://github.com/greguu/openwrt/releases/tag/ixp4xx-v6.1
patches: openwrt/openwrt@621ef48

Hopefully I can get some of the outstanding issues resolved so Watchguard support is part of the ixp4xx revival merge into OpenWrt.

@LeonG71
Copy link

LeonG71 commented Sep 24, 2023

8366SR datasheet http://realtek.info/pdf/rtl8366s_8366sr_datasheet_vpre-1.4_20071022.pdf , as used in XTM X21-W

and the already supported 8366S datasheet... http://realtek.info/pdf/rtl8366_8369_datasheet_1-1.pdf

Watchguard says "RTL8366 TMIIOneArm success!" OneARM an 8366 mode where the 8366 has one ethernet link to the xscale (rather than 2 that other modes use ?) and it will tell how to configure the cpu and 8366.

xscale CPU used one ethernet to talk to realtek , and watchguard gets it turn into three by vlan tags ... vendor logs three Vlan TAGS on eth3,4,5 ... So there is 3 10/100 ports and 3 gigabit capable ... the board has 3 small transformers, and two larger ones. Not that we need to do the vlan thing, we could let it work as a switch ..

RTC is s35390a data "0-0030"
my wifi card is Atheros AR9160 MAC/BB Rev:1 AR5133

@greguu
Copy link
Owner

greguu commented Oct 4, 2023

@LeonG71 Thanks for the details around the 8366SR, and the VLAN, I will look further into this. I suspected the WAN port to be a ixp4xx native ethernet as eth0, but you confirmed it. So eth1-5 are Realtek Switch ports via VLAN. Its confusing how these get split between NPE PHYs, I do no yet understand this part.

Vendor log:

ixp400_eth: eth0 is using NPE C PHY 16      
ixp400_eth: eth1 is using NPE C PHY 17      
ixp400_eth: eth2 is using NPE C PHY 18      
ixp400_eth: eth3 is using NPE A PHY 32      
ixp400_eth: eth4 is using NPE A PHY 33      
ixp400_eth: eth5 is using NPE A PHY 34 

eth3 to eth5 also get Realtek tagged, the others do not:

ixp400_eth: eth3 Realtek Tag 9001
ixp400_eth: eth4 Realtek Tag 9002
ixp400_eth: eth5 Realtek Tag 9004

Thanks for identifying the RTC, I will look into adding this to the device tree.

The CH341 way of accessing the UART is interesting, can you share more details ? It got some of these, but used them only for BIOS flashing / backups. I assume you can use the pins for that.

The WiFi card would possibly be the same for all the XTM21/22/23-W models and is supported as far as I can tell.

Currently, the focus is on getting the NAND going, it is apparently using Chip Select 1 and uses gpio-control-nand, instead of gen-nand. I have updated https://github.com/greguu/linux_kernel_xtm2_richland with some details I identified so far. Identifying the GPIO PINs used to control the NAND is possibly whats missing atm.

Once NAND is working, I need also to find another way of booting a kernel, as loading using ymodem is too slow and frustrating. The TFTP implementation on Watchguard Redboot appears to be broken or deliberately disabled.

Flashing a vanilla Redboot is risky and I do not have spare devices to take the risk. If anyone has the time and guts to try this this would be great :)

The switch implementation is the final part, I like to get the others sorted first to ease the work on the switch side.
I did look at the current 8366S implementation briefly, not sure but the vendor Watchguard kernel modules reference SMI, so this needs some work I am not too familiar with.

@LeonG71
Copy link

LeonG71 commented Oct 5, 2023

For the CH341A , I got the schematics and RS232 specific drivers from here https://tad-electronics.com/2019/03/10/ch341a-mini-programmer-schematic-and-drivers/ . Note this page discusses "CH341 powered by 5 volts always" boards.. You might have a board which has control over the CH341's TTL levels.

The ZIF socket doesn't have RS232, so I used some old standard PC motherboard connectors (2 pin ..eg LED or momentary switch) to push onto the TX , RX at both ends. Earth is in ZIF , so I just used a wire from ZIF to a screw at the X21-W,

Check your CH341 is for 5 volts TTL on its data lines (if the option exists to change it ) and set it to RS232 mode with the CH341A board's jumper on 2,3 instead of 1,2 ... and use the RS232 specific driver for the CH341 as per the link I supplied.

Is this the correct command to get greg's latest code ?

git clone https://github.com/greguu/openwrt -b ixp4xx-v6.1-watchguard

...Well I have booted with Greg's kernel and my own filesystem image, created on a USB flashdrive.. e2fs on it, and use it as a real hard drive... not a squashfs or anything like that. I can compile and use packages, and transfer them by using a second USB device ( plug in and unplug live )

@greguu
Copy link
Owner

greguu commented Oct 6, 2023

@LeonG71 Good news!

I need to update the .dts file in this repo, the current one is actually here in the OpenWrt repository:diff

It has support for the 16MB NOR Flash, but not yet NAND and Switch.

I recommend to build your own rootfs and kernel using OpenWrt, you can add the packages you want into the build process and boot from the rootfs via USB. Use this branch

@greguu
Copy link
Owner

greguu commented Oct 10, 2023

@LeonG71
I have added the RTC to the device tree and kernel config. It does get detected, but as expected the battery is possibly dead on most units by now. There is possibly a way to replace it.

rtc-s35390a 0-0030: registered as rtc0
rtc-s35390a 0-0030: setting system clock to 2000-01-01T04:00:44 UTC (946699244)

The firmware files for the IXP4xx-eth are already build and included in the OpenWrt rootfs under /lib/firmware
As I understand they should just get picked up there and do not need to be compiled into the kernel image.

In regards to the RTL switch, I did try both, the "classic" PHY switch and the DSA implementation. It appears the kernel is moving to DSA so it maybe worth migrating 8366SR to DSA, based on the the current 8366S implementation.

The Marvel switch was also enabled as CONFIG_MARVEL_PHY in the vendor kernel, but I could not see any kernel output on the vendor kernel on further details. Its possibly the missing bit to get ethernet ports 0-2 , eg the 10/100 ports, working and would explain the split of the ports between the two switches.

I have not had time to play further with the switches or the NAND for that matter, but will look into it time permitting.

Rebuilding the kernel is fast, but loading it for a test boot via ymodem is very slow. I was playing with the thought to get Redboot TFTP working, by flashing a new Redboot (vanilla), but worried it may brick the board.

@greguu
Copy link
Owner

greguu commented Oct 11, 2023

@LeonG71
The NAND is Samsung yes, but not a OneNAND one as far as I can tell. Its a 2G-bit SLC NAND (k9f2g08u0b).
I added a photo of the back of the board. As you show in the kernel log, the driver is GPIO NAND. To get it going we just need to correct GPIO pins used and what ChipSelect it uses, if any. I think its ChipSelect 1 (CS1), but not figured out the right GPIOs and lack time atm to investigate further.

Redboot does populate a FIS on the NOR FLASH if you run "fis init" but it will wipe the vendor partitions that are static. The device tree that I setup will use the FIS. You can actually put the kernel and/or rootfs into NOR FLASH already and boot from it.

You could also boot the kernel from NAND, if you flash it from Redboot, but I do not see any value of it yet compared to USB boot.

@LeonG71
Copy link

LeonG71 commented Dec 4, 2023

Note, its Vital to configure open-wrt gpio.c's as read only ( disable write8 and write16 in it) , so that a nearly compatible config doesn't trigger it to write bad block info just because of a failure of the ECC algorithm.

dts for the nand .. how can we know what the watchguard expect ??? I guess only by testing , READONLY, on a good watchguard written NAND, ? and then on a nand written by openwrt and read by redboot ?
I have two x21's , one untouched, so I guess I can read out the nand.

openwrt (linux) should really use the new format nand raw in the dts .. while the code is there for old format, its a stupid idea to mix them. ... I think the new format routines make up a default if there is nothing, so the basically its not a good idea to try the old format without first disabling the new format ( by C code forcing it to use read "of" function labelled legacy . )

The nand-ecc strings used in drivers/mtd/nand/.c are the new ones, generally, and the strings used in drivers/mtd/nand/raw/.c are the old ones ( but for io_sync... ) and meant to be avoided.

"maximize" isn't documented in /Documents/device-tree/bindings/... ,
It is if (of_property_read_bool(dn, "nand-ecc-maximize")) ? but it only works for BCH ..so I guess its not the panacea I had hoped.

so something like but the details of bch vs hamming, step size and strength, I do not yet know. I guess I can, as I can put debug prints in uboot , and try things, to get some idea of whats compatible.

                            nand-use-soft-ecc-engine;
                            nand-ecc-algo = "bch";
                            nand-ecc-maximize;

                            nand-bus-width =  8       // won't hurt to set this

                            #address-cells = <1>;
                            #size-cells = <1>;
                            rdy-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
                            nce-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
                            ale-gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
                            cle-gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;

two fixes ...

openwrt was using bank width = 2 if its not in the DTS as bank width 1. its a fix because I thought bank-width defaulted to 1. like it does in uboot. maybe it went to 2 in openwrt because of some of the DTS entries.

Then the cryptically documented io-sync-reg ...
rather than spend any time on deducing what addr should be, why not just change the code as follows, and then its got normal data address to use , for sure.

change it like this and the dts entry isnt going to do a thing.
// if (of_property_read_u64(pdev->dev.of_node, "gpio-control-nand,io-sync-reg", &addr))
// return NULL;
// endif

    r = devm_kzalloc(&pdev->dev, 8, GFP_KERNEL);                                                                         
    if (!r)                                                                                                              
            return NULL;                               

@greguu
Copy link
Owner

greguu commented Dec 5, 2023

@LeonG71 Thanks for this. I will give it a go. To clarify on the io-sync-reg fix, is this just for this particular NAND or generally a better way then specifying the addr in the dts ?

Not related, but similar question, there is a fix for the EHCI to set the offset on ixp43x required, I just hardcoded it, should it be a variable out of dts ? I assume the offset is always the same for ixp43x and so far no other platform needed one ?

@LeonG71
Copy link

LeonG71 commented Dec 5, 2023

Why do you ask about USB ? it works already.... the dts loads the dtsi files. which includes
compatible = "intel,ixp43x-ehci", "generic-ehci" ...

the io sync is a fix for Arm .. in fact for any Arm cpu ? I am reading people advising doing this for the later ARM, as bigger pipelines of modern ARM would have a higher cost for an "every time" fix.... Maybe the gpio driver should do the io_sync instead of leaving it to individual driver.... ?

btw, I had tried building a small openwrt kernel to fit in the NOR... which could boot straight to usb ... there is zexec chain boot of linux kernels.. so the space we have is 500k there in nor right ? well the result I got was a 600K kernel ... damm it. maybe theres things locked in by openwrt which might actually be removable ...??

@LeonG71
Copy link

LeonG71 commented Dec 6, 2023 via email

@LeonG71
Copy link

LeonG71 commented Dec 7, 2023

lol. I see what is wrong with the original gpio.c in openwrt .... the code doesn't have any delays!

The code just let the cpu rush straight through setting a GPIO signal, write a command, read the result, clear the GPIO signal.... the chip going "hey hang on , I missed the bit after "step 1: "... !" .. maybe it works on 10Mhz CISC or early Pi , something like that... just ndelay(1000) after anything which might need a delay... 1000 is a microsecond.. the spec says 20 ns.. but well, why rush,its, when its only a microsecond wasted.

here..... in gpio.c...


                gpio_nand_dosync(gpiomtd);
+               ndelay(1000);
                writeb(instr->ctx.cmd.opcode, gpiomtd->io);
+               ndelay(1000);
                gpio_nand_dosync(gpiomtd);
                gpiod_set_value(gpiomtd->cle, 0);
+               gpio_nand_dosync(gpiomtd);
+               ndelay(1000);
                return 0;
 case NAND_OP_ADDR_INSTR:
                gpio_nand_dosync(gpiomtd);
                gpiod_set_value(gpiomtd->ale, 1);
 

>                gpio_nand_dosync(gpiomtd);

+               ndelay(1000);
                for (i = 0; i < instr->ctx.addr.naddrs; i++)
                        writeb(instr->ctx.addr.addrs[i], gpiomtd->io);
                gpio_nand_dosync(gpiomtd);
+               ndelay(1000);
                gpiod_set_value(gpiomtd->ale, 0);
+               ndelay(1000);
                return 0;
  
        case NAND_OP_DATA_IN_INSTR:
                gpio_nand_dosync(gpiomtd);
+               ndelay(1000);
                if ((chip->options & NAND_BUSWIDTH_16) &&
                    !instr->ctx.data.force_8bit)
                        ioread16_rep(gpiomtd->io, instr->ctx.data.buf.in,
                                     instr->ctx.data.len / 2);
                else
                        ioread8_rep(gpiomtd->io, instr->ctx.data.buf.in,
                                    instr->ctx.data.len);
+               ndelay(1000);
                return 0;
 
        case NAND_OP_WAITRDY_INSTR:
+               ndelay(1000); 
+               ndelay(1000); 
                if (!gpiomtd->rdy)
                        return nand_soft_waitrdy(chip, instr->ctx.waitrdy.timeout_ms);

@LeonG71
Copy link

LeonG71 commented Dec 11, 2023

mtd_debug erase /dev/mtd4
nandwrite -p /dev/mtd4 zImage
nanddump -l 2653534 /dev/mtd4 > zzz
root@OpenWrt:/linux-6.1.52# cmp -l zImage zzz
root@OpenWrt:/linux-6.1.52#

So... the file I read back from NAND is fully perfect over 2 and a half meg of zImage...

Uboot's default seems to be happy to read from the redboot written NAND data.., using
ECC mode: 1 software... hamming.? ( BCH wasn't common back then.)
ECC steps: 8
ECC step size: 256
ECC 3 bytes per step

@LeonG71
Copy link

LeonG71 commented Dec 11, 2023

And.... redboot can read it ... and use it ...

nandtest -t 15 -p 0 -b 0x200000 -n 2900000
nandtest -t 21 -p 0x200000
exec -c "console=ttyS0,115200 root=/dev/sda1 rootdelay=12" -w 1

@LeonG71
Copy link

LeonG71 commented Dec 11, 2023

SYS-A is currently defined as reading 2 megabyte kernel ...
But thats ok, we can easily tweak the kernel to fit .. use the better kernel compressor, we can optimise for size rather than speed, and make some things modules.

@LeonG71
Copy link

LeonG71 commented Dec 12, 2023

yep, mostly the change to lzma compression, and some from omitting extra debugging helpers eg full symbols.

ls -al zImage.
..... 1939808 Dec 12 16:59 zImage so under 2 meg, and should work as SYS-A.

@greguu
Copy link
Owner

greguu commented Dec 13, 2023

@LeonG71 Thanks for you help with this. Good to see the NAND working.

To understand better the proposed boot process, can we not use Redboot and fsinit the NOR to allow a larger size for a zImage? NOR should be 16MB total, enough to hold a kernel. This way we can fit the kernel fully in NOR and the rootfs just in NAND ? I understand some other OpenWrt platforms use a NOR-NAND layout. I have not much experience with NAND partitions, but can the SYSA and SYSB partitions not be changed to fit a larger kernel ?

For NAND to work, is it just the .dts changes and some changes in the raw nand code as you showed ? I will put some patches together and test this weekend.

@LeonG71
Copy link

LeonG71 commented Dec 13, 2023 via email

@greguu
Copy link
Owner

greguu commented Dec 14, 2023

@LeonG71 I assumed the NOR is 16MB in size based on some of the ixp4xx dts templates as its common the full CS0 space is used. But yes, its right there is nothing beyond on the first 1MB on the Watchguard. So its for Redboot and config only. I will update the .dts and documentation as well on this.

@LeonG71
Copy link

LeonG71 commented Dec 14, 2023

From testing, Redboot works with OOB only (BBT off.) ECC defined as

nand-ecc-mode = "soft";
nand-ecc-step-size = <512> 
nand-ecc-strength = <4>;

I booted the 2 meg ( 1974648 bytes ) image and got a working system, first time ever for a totally hands free boot to a working openwrt ... BUT I am having trouble squashing everything into 2 meg... a single byte change in NOR ROM to change it to 4 meg, but ... is it checksummed ? :.. maybe I can an eeprom device to attach to the NOR.,

I booted SYS-B just now, as its defined as loading 4 meg, its more useful...

I noticed the ath9k driver can take IRQ defined by Device tree. I didnt find where the code read it though... maybe the feature has gone missing. I was considering MSI .. looks like the driver supports it, even where the driver sets up a bunch of tests for the ath9k version in use and configures stuff based on that.. it configures all as capable of MSI ?

So we have
the following paths

  1. SYS-A = 2 meg Openwrt proper kernel. I dont see the problem, so much can be made modules.

  2. sys-a = 2 meg linux kernel (down to 600 kb ) just for the purpose of reading NAND or USB to get a bigger kernel, and kexec it .

  3. Sys-a = uboot ... then it loads a bigger kernel from NAND.

But the 2 meg size limit kernel is good, its stable and running "make modules".just change the kernel compression to LZMA, it shaves it right down...

@LeonG71
Copy link

LeonG71 commented Dec 22, 2023

Working gpio.c all that has to be fixed is here. Dont worry about putting the delays in nand_base.c save a few nanoseconds by precise calculations ????
`// SPDX-License-Identifier: GPL-2.0-only
/*

  • Updated, and converted to generic GPIO based driver by Russell King.
  • Written by Ben Dooks ben@simtec.co.uk
  • Based on 2.4 version by Mark Whittaker
  • © 2004 Simtec Electronics
  • Device driver for NAND flash that uses a memory mapped interface to
  • read/write the NAND commands and data, and GPIO pins for control signals
  • (the DT binding refers to this as "GPIO assisted NAND flash")
    */

#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/gpio/consumer.h>
#include <linux/io.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand-gpio.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/delay.h>

static int packets=0, zeropackets=0;
static int wpackets=0 ;

struct gpiomtd {
struct nand_controller base;
void __iomem *io;
void __iomem *io_sync;
struct nand_chip nand_chip;
struct gpio_nand_platdata plat;
struct gpio_desc nce; / Optional chip enable */
struct gpio_desc *cle;
struct gpio_desc *ale;
struct gpio_desc *rdy;
struct gpio_desc nwp; / Optional write protection */
};

void iowrite88_rep(void * addr, u8 * buf,int len, struct gpiomtd *gpiomtd ) {

int i;
int checksum=0;

for(i=0; i< len; i++ ) {

//if (len==64 ) pr_warn("%d",buf[i] );

*( (volatile unsigned char * ) addr) =  buf[i];
checksum+=  buf[i];
//	gpio_nand_dosync(gpiomtd);
	ndelay(200);
};

//pr_warn("write checksum %d \n",checksum );
}

static inline struct gpiomtd *gpio_nand_getpriv(struct mtd_info *mtd)
{
return container_of(mtd_to_nand(mtd), struct gpiomtd, nand_chip);
}

#ifdef CONFIG_ARM
/* gpio_nand_dosync()
*

  • Make sure the GPIO state changes occur in-order with writes to NAND

  • memory region.

  • Needed on PXA due to bus-reordering within the SoC itself (see section on

  • I/O ordering in PXA manual (section 2.3, p35)
    */
    static void gpio_nand_dosync(struct gpiomtd *gpiomtd)
    {
    unsigned long tmp;
    static int count=0;

    if (gpiomtd->io_sync) {
    /*
    * Linux memory barriers don't cater for what's required here.
    * What's required is what's here - a read from a separate
    * region with a dependency on that read.
    */
    tmp = readl(gpiomtd->io_sync);
    asm volatile("mov %1, %0\n" : "=r" (tmp) : "r" (tmp));
    }
    else if (count++ < 10 ) pr_warn("DOSYNC NULL !!\n");
    }
    #else
    static void gpio_nand_dosync(struct gpiomtd *gpiomtd) {
    pr_warn("DOSYNC NULL !!\n");
    }
    #endif

static int gpio_nand_exec_instr(struct nand_chip *chip,
const struct nand_op_instr *instr)
{
struct gpiomtd *gpiomtd = gpio_nand_getpriv(nand_to_mtd(chip));
unsigned int i;
int checksum =0;

switch (instr->type) {
case NAND_OP_CMD_INSTR:
	gpio_nand_dosync(gpiomtd);
	gpiod_set_value(gpiomtd->cle, 1);
	gpio_nand_dosync(gpiomtd);
	ndelay(200);
	writeb(instr->ctx.cmd.opcode, gpiomtd->io);
	ndelay(200);
	gpio_nand_dosync(gpiomtd);
	//pr_warn("CMD %x: \n",instr->ctx.cmd.opcode);
	gpiod_set_value(gpiomtd->cle, 0);
	gpio_nand_dosync(gpiomtd);
	ndelay(200);
	return 0;

case NAND_OP_ADDR_INSTR:
	gpio_nand_dosync(gpiomtd);
	gpiod_set_value(gpiomtd->ale, 1);
	gpio_nand_dosync(gpiomtd);
	ndelay(200);
	for (i = 0; i < instr->ctx.addr.naddrs; i++)
		writeb(instr->ctx.addr.addrs[i], gpiomtd->io);
	gpio_nand_dosync(gpiomtd);
	ndelay(200);
	ndelay(200);
	ndelay(200);
	//if (i != 5 ) 	pr_warn("ADDR n:%d \n",i );
	gpiod_set_value(gpiomtd->ale, 0);
	ndelay(200);
	return 0;

case NAND_OP_DATA_IN_INSTR:
	gpio_nand_dosync(gpiomtd);
	ndelay(200);
	if ((chip->options & NAND_BUSWIDTH_16) &&
	    !instr->ctx.data.force_8bit) { 
		pr_warn("reading 16 bit !!! \n");  
		ioread16_rep(gpiomtd->io, instr->ctx.data.buf.in,
			     instr->ctx.data.len / 2); } 
	else
		{ 
		ioread8_rep(gpiomtd->io, instr->ctx.data.buf.in,
			    instr->ctx.data.len);

		for(i=0;i<instr->ctx.data.len; i++)	
			checksum+= ( ( char * ) instr->ctx.data.buf.in)[i]; 
		packets++;
		if (!checksum ) zeropackets++;
		}

	ndelay(200);
	return 0;

case NAND_OP_DATA_OUT_INSTR:
	gpio_nand_dosync(gpiomtd);
	ndelay(200);
	if ((chip->options & NAND_BUSWIDTH_16) &&
	    !instr->ctx.data.force_8bit)  {  
		pr_warn("writing 16 bit !!! \n");  
		iowrite16_rep(gpiomtd->io, instr->ctx.data.buf.out,
			      instr->ctx.data.len / 2); }
	else
		iowrite8_rep(gpiomtd->io, instr->ctx.data.buf.out,
			     instr->ctx.data.len);
		//iowrite88_rep(gpiomtd->io, instr->ctx.data.buf.out,
		//	     instr->ctx.data.len, gpiomtd);
	wpackets++;
	ndelay(200);
		pr_warn("write n:%d \n", instr->ctx.data.len);
	return 0;

case NAND_OP_WAITRDY_INSTR:
	ndelay(200); 
	ndelay(200); 
	if (!gpiomtd->rdy) {
		 //pr_warn("WR \n");
		return nand_soft_waitrdy(chip, instr->ctx.waitrdy.timeout_ms);
	}

	return nand_gpio_waitrdy(chip, gpiomtd->rdy,
				 instr->ctx.waitrdy.timeout_ms);

default:
	return -EINVAL;
}

return 0;

}

static int gpio_nand_exec_op(struct nand_chip *chip,
const struct nand_operation *op,
bool check_only)
{
struct gpiomtd *gpiomtd = gpio_nand_getpriv(nand_to_mtd(chip));
unsigned int i;
int ret = 0;

if (check_only)
	return 0;

gpio_nand_dosync(gpiomtd);
gpiod_set_value(gpiomtd->nce, 0);
for (i = 0; i < op->ninstrs; i++) {
	ret = gpio_nand_exec_instr(chip, &op->instrs[i]);
	if (ret)
		break;

	// LJG if (op->instrs[i].delay_ns) ndelay(op->instrs[i].delay_ns);
	ndelay(200);
}
gpio_nand_dosync(gpiomtd);
gpiod_set_value(gpiomtd->nce, 1);

return ret;

}

static int gpio_nand_attach_chip(struct nand_chip *chip)
{
if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&
chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
chip->ecc.algo = NAND_ECC_ALGO_HAMMING;

return 0;

}

static const struct nand_controller_ops gpio_nand_ops = {
.exec_op = gpio_nand_exec_op,
.attach_chip = gpio_nand_attach_chip,
};

#ifdef CONFIG_OF
static const struct of_device_id gpio_nand_id_table[] = {
{ .compatible = "gpio-control-nand" },
{}
};
MODULE_DEVICE_TABLE(of, gpio_nand_id_table);

static int gpio_nand_get_config_of(const struct device *dev,
struct gpio_nand_platdata *plat)
{
u32 val;

if (!dev->of_node)
	return -ENODEV;

if (!of_property_read_u32(dev->of_node, "bank-width", &val)) {
	if (val == 2) {
		plat->options |= NAND_BUSWIDTH_16;
	} else if (val != 1) {
		dev_err(dev, "invalid bank-width %u\n", val);
		return -EINVAL;
	}
}

if (!of_property_read_u32(dev->of_node, "chip-delay", &val))
	plat->chip_delay = val;

return 0;

}

static struct resource *gpio_nand_get_io_sync_of(struct platform_device *pdev)
{
struct resource *r;
u64 addr;

if (of_property_read_u64(pdev->dev.of_node,
			       "gpio-control-nand,io-sync-reg", &addr))
	return NULL;

r = devm_kzalloc(&pdev->dev, sizeof(*r), GFP_KERNEL);
if (!r)
	return NULL;

r->start = addr;
r->end = r->start + 0x3;
r->flags = IORESOURCE_MEM;

return r;

}
#else /* CONFIG_OF */
static inline int gpio_nand_get_config_of(const struct device *dev,
struct gpio_nand_platdata *plat)
{
return -ENOSYS;
}

static inline struct resource *
gpio_nand_get_io_sync_of(struct platform_device pdev)
{
return NULL;
}
#endif /
CONFIG_OF */

static inline int gpio_nand_get_config(const struct device *dev,
struct gpio_nand_platdata *plat)
{
int ret = gpio_nand_get_config_of(dev, plat);

if (!ret)
	return ret;

if (dev_get_platdata(dev)) {
	memcpy(plat, dev_get_platdata(dev), sizeof(*plat));
	return 0;
}

return -EINVAL;

}

static inline struct resource *
gpio_nand_get_io_sync(struct platform_device *pdev)
{
struct resource *r = gpio_nand_get_io_sync_of(pdev);

if (r)
	return r;

return platform_get_resource(pdev, IORESOURCE_MEM, 1);

}

static int gpio_nand_remove(struct platform_device *pdev)
{
struct gpiomtd *gpiomtd = platform_get_drvdata(pdev);
struct nand_chip *chip = &gpiomtd->nand_chip;
int ret;

pr_warn("gpio total packets %d zeropackets %d wpackets %d\n",packets,
zeropackets,wpackets );

ret = mtd_device_unregister(nand_to_mtd(chip));
WARN_ON(ret);
nand_cleanup(chip);

/* Enable write protection and disable the chip */
if (gpiomtd->nwp && !IS_ERR(gpiomtd->nwp))
	gpiod_set_value(gpiomtd->nwp, 0);
if (gpiomtd->nce && !IS_ERR(gpiomtd->nce))
	gpiod_set_value(gpiomtd->nce, 0);

return 0;

}

static int gpio_nand_probe(struct platform_device *pdev)
{
struct gpiomtd *gpiomtd;
struct nand_chip *chip;
struct mtd_info *mtd;
struct resource *res;
struct device *dev = &pdev->dev;
int ret = 0;

if (!dev->of_node )       // LJG && !dev_get_platdata(dev))
	return -EINVAL;

gpiomtd = devm_kzalloc(dev, sizeof(*gpiomtd), GFP_KERNEL);
if (!gpiomtd)
	return -ENOMEM;

chip = &gpiomtd->nand_chip;
pr_warn("IO was  %x \n", gpiomtd->io );
gpiomtd->io = devm_platform_ioremap_resource(pdev, 0);
pr_warn("IO now   %x \n", gpiomtd->io );
if (IS_ERR(gpiomtd->io))
	return PTR_ERR(gpiomtd->io);

//res = gpio_nand_get_io_sync(pdev);
//if (res) {
//	gpiomtd->io_sync = devm_ioremap_resource(dev, res);
//	if (IS_ERR(gpiomtd->io_sync))
// return PTR_ERR(gpiomtd->io_sync);
//}
gpiomtd->io_sync = kmalloc(4,GFP_KERNEL); 

ret = gpio_nand_get_config(dev, &gpiomtd->plat);
if (ret)
	return ret;

pr_warn("IO finally   %x \n", gpiomtd->io );
/* NCE is for chip enable */
gpiomtd->nce = devm_gpiod_get_optional(dev, "nce", GPIOD_OUT_HIGH);
if (IS_ERR(gpiomtd->nce))
	return PTR_ERR(gpiomtd->nce);

/* We disable write protection once we know probe() will succeed */
gpiomtd->nwp = devm_gpiod_get_optional(dev, "nwp", GPIOD_OUT_LOW);
if (IS_ERR(gpiomtd->nwp)) {
	ret = PTR_ERR(gpiomtd->nwp);
	goto out_ce;
}

gpiomtd->ale = devm_gpiod_get(dev, "ale", GPIOD_OUT_LOW);
if (IS_ERR(gpiomtd->ale)) {
	ret = PTR_ERR(gpiomtd->ale);
	goto out_ce;
}

gpiomtd->cle = devm_gpiod_get(dev, "cle", GPIOD_OUT_LOW);
if (IS_ERR(gpiomtd->cle)) {
	ret = PTR_ERR(gpiomtd->cle);
	goto out_ce;
}

gpiomtd->rdy = devm_gpiod_get_optional(dev, "rdy", GPIOD_IN);
if (IS_ERR(gpiomtd->rdy)) {
	ret = PTR_ERR(gpiomtd->rdy);
	goto out_ce;
}

nand_controller_init(&gpiomtd->base);
gpiomtd->base.ops = &gpio_nand_ops;

nand_set_flash_node(chip, pdev->dev.of_node);
chip->options		= gpiomtd->plat.options;
chip->controller	= &gpiomtd->base;

mtd			= nand_to_mtd(chip);
mtd->dev.parent		= dev;

platform_set_drvdata(pdev, gpiomtd);

/* Disable write protection, if wired up */
if (gpiomtd->nwp && !IS_ERR(gpiomtd->nwp))
	gpiod_direction_output(gpiomtd->nwp, 1);

/*
 * This driver assumes that the default ECC engine should be TYPE_SOFT.
 * Set ->engine_type before registering the NAND devices in order to
 * provide a driver specific default value.
 */
chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;

ret = nand_scan(chip, 1);
if (ret)
	goto err_wp;

if (gpiomtd->plat.adjust_parts)
	gpiomtd->plat.adjust_parts(&gpiomtd->plat, mtd->size);

ret = mtd_device_register(mtd, gpiomtd->plat.parts,
			  gpiomtd->plat.num_parts);
if (!ret)
	return 0;

err_wp:
if (gpiomtd->nwp && !IS_ERR(gpiomtd->nwp))
gpiod_set_value(gpiomtd->nwp, 0);
out_ce:
if (gpiomtd->nce && !IS_ERR(gpiomtd->nce))
gpiod_set_value(gpiomtd->nce, 0);

return ret;

}

static struct platform_driver gpio_nand_driver = {
.probe = gpio_nand_probe,
.remove = gpio_nand_remove,
.driver = {
.name = "gpio-nand",
.of_match_table = of_match_ptr(gpio_nand_id_table),
},
};

module_platform_driver(gpio_nand_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Ben Dooks ben@simtec.co.uk");
MODULE_DESCRIPTION("GPIO NAND Driver");
`

@LeonG71
Copy link

LeonG71 commented Dec 25, 2023

This is intended as the "all you need to fix" additional to the standard compile for an openwrt kernel, for the watchguard.

a. install a dts file - its not right in the kernel package provided. ( eg GPIO definitions for the samsung flash nand previously here,, the nand partitions could do with an entry for SYS-B , since it can take a 4 meg kernel and be chosen by menu.... also the marvell - lan1 lan2 lan3 sections previously in this "issue" thread. the seiko rtc via I2c on two gpios previously from gregu, the PCI Irq for the wireless card , from me. and
there's some guidelines for the realtek chip here ... https://git.zx2c4.com/linux/plain/Documentation/devicetree/bindings/net/dsa/realtek.yaml
)

b.install drivers/mtd/nand/raw/gpio.c from previous post.

c. install firmware images into roof fs and ensure the firmware functions are in kernel ( a Howard said he got it ETH firmware working to drive ethernet packets through the marvel ethernet chip . )

configure the kernel.

1a. The NOR flash driver is a bit hidden .. and confusing... it reads like its asking the same thing 3 times.

Need to build it into the in the kernel ( seems to be broken for modules, like the MTD above it. )
Openwrt will need you to run "make kernel_menuconfig"
First, go to drivers, memory technology devices
you need to enable RAM/ROM/Flash chip drivers , "RAM chips in bus mapping". or else you can't see the following.
then under " Mapping drivers for chip access "
you can enable "Flash device in physical memory map"
then "Memory device in physical memory map based on OF description" .. OF means device tree, the DTS file..
then "Intel IXP4xx OF-based physical memory map handling" , and so it needs a DTS entry with the correct register value settings.. see gregu's post earlier, with the guts of the bus configuration register (bus size and bus operation timings) exposed in the DTS..

1b.install a default kernel configuration line into the kernel... "console=ttyS0,115200 root=/dev/sda1 rootdelay=12"
Need to use "make kernel_menuconfig" to do this.

1c. Openwrt's "make menuconfig" doesn't turn on USB_EHCI_HCD_PLATFORM ,which we need on to use the USB..
You can turn it on with "make kernel_menuconfig".

Having used kernel_menuconfig, the openwrt version of the kernel config is left with some ill-defined debug definitions, that the default action of "make" detects and asks you about, before it starts compiling. Its of little consequence ( it means that "make &> errs " hangs for ever ,stuck waiting for an answer to a question you won't have been asked. )

You want the USB interface driver, the USB mass storage, and the SCSI generic hard drive drive in the kernel.. (usb mass storage emulates a scsi hard drive.)

  1. When you are trying to get GPIO RAW NAND , for the samsung nand, into the kernel,
    If you set it to be yes in the kernel, it doesn't correctly set the mtd_blkdev.o to be in the kernel too. mtd.o needs mtd_blkdev.o ...

My fix for this was to edit the drivers/mtd Makefile , and add that mtd_blkdev.o file to the "mtd-y = " line, and comment out the module line for it later ,that being the "obj-$(CONFIG_MTD_BLKDEVS" line.

But if you select the Memory Technology Devices, CONFIG_MTD ..well first, it doesnt work, the top doesn't work as a module. seg faults, something messed uop. But You can set the RAW NAND GPIO to be a module and get nand.ko and gpio.ko ..

...if you do try the top end as a module, compiling it fails at first ,due to two errors.
I mean if you see these errors, then just set the MTD to be built into the kernel ... fixed

2a There's a function missing an export , mtd blk dev_trans add function. Simply needs the EXPORT( ) in its implementation C file.

2b There's a variable ROOT_DEV undefined to the module ... not exported from its home in init/do_mounts.c . Its possible to fix by adding the EXPORT declaration to init/do_mounts.c , or , an "#ifndef MODULE " wrappper around its use in drivers/mtd/mtdcore.c ( so the module can't set ROOT_DEV .. so what hey ?)

The above is my notes from a clean compile of the linux kernel and what it took to get it compiled for USB mass storage root fs, the NAND flash and the NOR flash working...

@LeonG71
Copy link

LeonG71 commented Dec 25, 2023

btw, pci INTA is on GPIO pin 0 . there is a line in the watchguard firmware log saying saying the pci interrupt is being assigned to gpio 0.

Buzzed it out with the multimeter, yep , GPIO 0 writes out to pin 20 on the PCI connector. So it ought accept from there too....

the gpio-ixp file tells us why it talks about Irq 6 and irq 23 even though we are using irq 0.. ???? I see, a gpio 0 interrupt means hardware interrupt 6 to linux.
It seems to get that we are telling it to use gpio 0 as the interrupt,

    /* GPIO lines 0..12 have dedicated IRQs */
    if (child == 0) {
            *parent = 6;
            return 0;
    }
    if (child == 1) {
            *parent = 7;
            return 0;
    }
    if (child >= 2 && child <= 12) {
            *parent = child + 17;
            return 0;
    }

But the log output
gpio gpiochip0: (IXP4XX_GPIO_CHIP): allocate IRQ 23, hwirq 0
gpio gpiochip0: (IXP4XX_GPIO_CHIP): found parent hwirq 6
gpio gpiochip0: (IXP4XX_GPIO_CHIP): alloc_irqs_parent for 23 parent hwirq 6

Its applied the mapping twice !. its gone from 0 , to 6, to 23 .... 23 is the grandparent.. this is kaos, there are no grandparents in kaos !! It might be due to the ath9k driver ? , as this pops up when I modprobe ath9k ...

So the documentation says
HW Int6 <> GPIO[0] .... GPIO 0 could trigger a HW IRQ 6.
HW Int23 <> GPIO[6] .... GPIO 6 could trigger a HW IRQ 23.

So the mapping in that C file is right, it just shouldnt be applied twice.

@LeonG71
Copy link

LeonG71 commented Dec 29, 2023

There is a set of patches freshly released that cleans up realtek SMI vs MDIO realtek drivers. But doesn't increase the number of chips supported. but still a good patch to include ?

here
https://lore.kernel.org/netdev/20231223005253.17891-1-luizluca@gmail.com/T/

@greguu
Copy link
Owner

greguu commented Jan 9, 2024

@LeonG71 Thanks again, I will put together a patch for drivers/mtd/nand/raw/gpio.c and do some NAND testing this week. Do you have a gpio.c with comments on your patch ? It would help to understand what is being done. Then attach the file to the comment.

@greguu
Copy link
Owner

greguu commented Jan 10, 2024

@LeonG71 can you also attach the nand section of your .dts ? I tried with your gpio.c and still get errors.

@LeonG71
Copy link

LeonG71 commented Jan 10, 2024

intel-ixp43x-watchguard-xtm21w.txt

@greguu
Copy link
Owner

greguu commented Jan 12, 2024

intel-ixp43x-watchguard-xtm21w.txt

Thanks @LeonG71!

However, I am still getting this error on boot:

[    1.504477] IO was  0 
[    1.507031] IO now   d08b4000 
[    1.510139] IO finally   d08b4000 
[    1.513838] nand: device found, Manufacturer ID: 0xec, Chip ID: 0xda
[    1.520274] nand: Samsung NAND 256MiB 3,3V 8-bit
[    1.524912] nand: 256 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
[    1.532507] ------------[ cut here ]------------
[    1.537126] WARNING: CPU: 0 PID: 1 at drivers/mtd/nand/raw/nand_base.c:5718 nand_scan_with_ids+0x13f4/0x1838
[    1.547015] Hamming ECC initialization failed!
[    1.551456] Modules linked in:
[    1.554516] CPU: 0 PID: 1 Comm: swapper Not tainted 6.1.52 #0
[    1.560266] Hardware name: IXP4xx (Device Tree)
[    1.564799]  unwind_backtrace from show_stack+0x10/0x14
[    1.570069]  show_stack from dump_stack_lvl+0x28/0x30
[    1.575136]  dump_stack_lvl from __warn+0x94/0xdc
[    1.579868]  __warn from warn_slowpath_fmt+0x70/0x84
[    1.584849]  warn_slowpath_fmt from nand_scan_with_ids+0x13f4/0x1838
[    1.591221]  nand_scan_with_ids from gpio_nand_probe+0x2a4/0x34c
[    1.597253]  gpio_nand_probe from platform_probe+0x44/0x84
[    1.602765]  platform_probe from really_probe+0xb4/0x2dc
[    1.608085]  really_probe from driver_probe_device+0x34/0x124
[    1.613840]  driver_probe_device from __driver_attach+0x90/0x17c
[    1.619855]  __driver_attach from bus_for_each_dev+0x64/0x90
[    1.625550]  bus_for_each_dev from bus_add_driver+0x154/0x1e8
[    1.631312]  bus_add_driver from driver_register+0x8c/0x124
[    1.636895]  driver_register from do_one_initcall+0x4c/0x274
[    1.642563]  do_one_initcall from kernel_init_freeable+0x164/0x1ec
[    1.648770]  kernel_init_freeable from kernel_init+0x10/0x128
[    1.654551]  kernel_init from ret_from_fork+0x14/0x2c
[    1.659618] Exception stack(0xc0c25fb0 to 0xc0c25ff8)
[    1.664677] 5fa0:                                     00000000 00000000 00000000 00000000
[    1.672865] 5fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    1.681047] 5fe0: 00000000 00000000 00000000 00000000 00000013 00000000
[    1.687736] ---[ end trace 0000000000000000 ]---
[    1.692383] gpio-nand: probe of 51000000.gpio-nand failed with error -524

Maybe gpio.c is not 100%? Can you attach the latest version ?

@LeonG71
Copy link

LeonG71 commented Jan 12, 2024 via email

@greguu
Copy link
Owner

greguu commented Jan 19, 2024

@LeonG71 Did you build your kernel with OpenWrt or just from vanilla sources ?

I use the OpenWrt SDK and have the following for MTD in .config-6.1

CONFIG_MTD_CFI_ADV_OPTIONS=y
# CONFIG_MTD_CFI_GEOMETRY is not set
CONFIG_MTD_NAND_CORE=y
CONFIG_MTD_NAND_ECC=y
CONFIG_MTD_NAND_ECC_SW_BCH=y
CONFIG_MTD_NAND_GPIO=y
CONFIG_MTD_OTP=y
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_PHYSMAP_IXP4XX=y
CONFIG_MTD_RAW_NAND=y
CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MTD_SPLIT_FIRMWARE=y
CONFIG_MTD_SPLIT_FIRMWARE_NAME="linux"

Can you attach your gpio.c or upload your full kernel source to github so we can verify ? I can not reproduce your NAND fix otherwise..

@LeonG71
Copy link

LeonG71 commented Jan 19, 2024 via email

@LeonG71
Copy link

LeonG71 commented Jan 19, 2024

And how about MTD_NAND_ECC_SW_HAMMING [=y] ... if you want to be able to write the nand so that redboot can read it.

@LeonG71
Copy link

LeonG71 commented Jan 20, 2024

Here is gpio.c as a prestine file.
gpio.c.txt
I just did a rm -rf linux-6.1.52
and did a make, of course with gpio.c and the dts copied in.

and I booted the result and it works

here is a link to tgz with the kernel and modules that work to write to nand. the dtb is appended to the kernel , and its expecting the root fs ext4 / on /dev/sda1 ...

https://1drv.ms/u/s!AsTex5OoPMW8yXrtmrd_t-YPeKJA?e=5Iqnaa

So it just occurred to me, if I have a working kernel in SYSB, I can just have a kernel to try in the filesystem, rather than mess with the working SYSB .. then

"kexec -f zImage" , and bang, running the trial kernel

@greguu
Copy link
Owner

greguu commented Jan 20, 2024

@LeonG71 I will try this asap. Yes, kexec makes sense now as we have ethernet support.

@greguu
Copy link
Owner

greguu commented Jan 30, 2024

@LeonG71 Ok, I got it working now. The gpio.c did the trick with some messing around in the kernel config. Thanks.
I will add some patches to the repository this week after further testing.

There is maybe a way to define custom NAND partitions and make redboot boot from one of these ?

@LeonG71
Copy link

LeonG71 commented Jan 30, 2024 via email

@greguu
Copy link
Owner

greguu commented Apr 24, 2024

Not dead, but limited time to work on this. Current status as below:

  • testing a custom kexecboot kernel as boot loader atm, that fits in the SYSA NAND partition. This kernel then can load any other kernel within a ext4 or squashfs partition including a priority based on a config file. This should ease the OpenWrt update flow, although u-boot still an option, I did not try due to outdated ixp4xx support.

  • bumped to latest OpenWrt build based on kernel 6.1.86, because the build host got out of date. This may help with pushing patches.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants