Compare commits

...

5 Commits

Author SHA1 Message Date
Arnout Engelen d20b79e06a
jffs, kexecboot 2024-02-21 15:32:42 +01:00
Arnout Engelen 1a85d09077
WIP: support for TFTP on 'old' uboot versions
Older uboot versions don't have an option to
override the DTB from the `mboot` command, so
the updated DTB needs to be replaced in the image
itself.
2024-02-19 17:04:25 +01:00
Arnout Engelen 4cf7472df8
WIP: example of using the Archer AX23 as extender
Needs cleaning up.

Perhaps (some of) the hostap configuration should
be moved to the 'device' somehow?
2024-02-06 18:01:24 +01:00
Arnout Engelen 63e3f2aa58
Add support for TP-Link Archer AX23 2024-02-06 18:00:55 +01:00
Arnout Engelen 61494fdc0c
Add tplink module for creating 'safeloader' images 2024-02-06 17:59:38 +01:00
8 changed files with 721 additions and 3 deletions

1
ci.nix
View File

@ -11,6 +11,7 @@ let
devices = [
"gl-ar750" "gl-mt300n-v2" "gl-mt300a"
"qemu" "qemu-aarch64" "qemu-armv7l"
"tp-archer-ax23"
];
vanilla = ./vanilla-configuration.nix;
for-device = name:

View File

@ -0,0 +1,440 @@
{
description = ''
TP-Link Archer AX23 / AX1800 Dual Band Wi-Fi 6 Router
*****************************************************
Hardware summary
================
- MediaTek MT7621 (880MHz)
- 16MB Flash
- 128MB RAM
- WLan hardware: Mediatek MT7905, MT7975
Limitations
===========
Status LEDs do not work yet.
Uploading an image via tftp doesn't work yet, because the Archer uboot
version is so old it doesn't support overriding the DTB from the mboot
command. The tftpboot module doesn't support this yet, see
https://gti.telent.net/dan/liminix/pulls/5 for the WiP.
'';
system = {
crossSystem = {
config = "mipsel-unknown-linux-musl";
gcc = {
abi = "32";
# https://openwrt.org/docs/techref/instructionset/mipsel_24kc
arch = "24kc";
};
};
};
module = {pkgs, config, lib, lim, ... }:
let firmware = pkgs.stdenv.mkDerivation {
name = "wlan-firmware";
phases = ["installPhase"];
installPhase = ''
mkdir $out
cp ${pkgs.linux-firmware}/lib/firmware/mediatek/{mt7915,mt7615,mt7622}* $out
'';
};
in {
imports = [
../../modules/arch/mipsel.nix
../../modules/outputs/tftpboot.nix
../../modules/outputs/tplink-safeloader.nix
../../modules/outputs/jffs2.nix
];
config = {
kernel = {
src = pkgs.pkgsBuildBuild.fetchurl {
name = "linux.tar.gz";
url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.137.tar.gz";
hash = "sha256-PkdzUKZ0IpBiWe/RS70J76JKnBFzRblWcKlaIFNxnHQ=";
};
extraPatchPhase = ''
${pkgs.openwrt.applyPatches.ramips}
'';
config = {
# Initially taken from openwrt's ./target/linux/ramips/mt7621/config-5.15,
# then tweaked here and there
ARCH_32BIT_OFF_T="y";
ARCH_HIBERNATION_POSSIBLE="y";
ARCH_KEEP_MEMBLOCK="y";
ARCH_MMAP_RND_BITS_MAX="15";
ARCH_MMAP_RND_COMPAT_BITS_MAX="15";
ARCH_SUSPEND_POSSIBLE="y";
AT803X_PHY="y";
BLK_MQ_PCI="y";
BOARD_SCACHE="y";
CEVT_R4K="y";
CLKSRC_MIPS_GIC="y";
CLK_MT7621="y";
CLOCKSOURCE_WATCHDOG="y";
CLONE_BACKWARDS="y";
CMDLINE_BOOL="y";
COMMON_CLK="y";
COMPAT_32BIT_TIME="y";
CPU_GENERIC_DUMP_TLB="y";
CPU_HAS_DIEI="y";
CPU_HAS_PREFETCH="y";
CPU_HAS_RIXI="y";
CPU_HAS_SYNC="y";
CPU_LITTLE_ENDIAN="y";
CPU_MIPS32="y";
CPU_MIPS32_R2="y";
CPU_MIPSR2="y";
CPU_MIPSR2_IRQ_EI="y";
CPU_MIPSR2_IRQ_VI="y";
CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS="y";
CPU_R4K_CACHE_TLB="y";
CPU_RMAP="y";
CPU_SUPPORTS_32BIT_KERNEL="y";
CPU_SUPPORTS_HIGHMEM="y";
CPU_SUPPORTS_MSA="y";
CRC16="y";
CRYPTO_DEFLATE="y";
CRYPTO_HASH_INFO="y";
CRYPTO_LIB_BLAKE2S_GENERIC="y";
CRYPTO_LIB_POLY1305_RSIZE="2";
CRYPTO_LZO="y";
CRYPTO_ZSTD="y";
CSRC_R4K="y";
DIMLIB="y";
DMA_NONCOHERENT="y";
DTB_RT_NONE="y";
DTC="y";
EARLY_PRINTK="y";
FIXED_PHY="y";
FWNODE_MDIO="y";
FW_LOADER_PAGED_BUF="y";
GENERIC_ATOMIC64="y";
GENERIC_CLOCKEVENTS="y";
GENERIC_CMOS_UPDATE="y";
GENERIC_CPU_AUTOPROBE="y";
GENERIC_FIND_FIRST_BIT="y";
GENERIC_GETTIMEOFDAY="y";
GENERIC_IOMAP="y";
GENERIC_IRQ_CHIP="y";
GENERIC_IRQ_EFFECTIVE_AFF_MASK="y";
GENERIC_IRQ_SHOW="y";
GENERIC_LIB_ASHLDI3="y";
GENERIC_LIB_ASHRDI3="y";
GENERIC_LIB_CMPDI2="y";
GENERIC_LIB_LSHRDI3="y";
GENERIC_LIB_UCMPDI2="y";
GENERIC_PCI_IOMAP="y";
GENERIC_PHY="y";
GENERIC_PINCONF="y";
GENERIC_SCHED_CLOCK="y";
GENERIC_SMP_IDLE_THREAD="y";
GENERIC_TIME_VSYSCALL="y";
GLOB="y";
GPIOLIB_IRQCHIP="y";
GPIO_CDEV="y";
GPIO_GENERIC="y";
GPIO_MT7621="y";
GRO_CELLS="y";
HANDLE_DOMAIN_IRQ="y";
HARDWARE_WATCHPOINTS="y";
HAS_DMA="y";
HAS_IOMEM="y";
HAS_IOPORT_MAP="y";
I2C="y";
I2C_ALGOBIT="y";
I2C_BOARDINFO="y";
I2C_CHARDEV="y";
I2C_GPIO="y";
I2C_MT7621="y";
ICPLUS_PHY="y";
IRQCHIP="y";
IRQ_DOMAIN="y";
IRQ_DOMAIN_HIERARCHY="y";
IRQ_FORCED_THREADING="y";
IRQ_MIPS_CPU="y";
IRQ_WORK="y";
LIBFDT="y";
LOCK_DEBUGGING_SUPPORT="y";
LZO_COMPRESS="y";
LZO_DECOMPRESS="y";
MDIO_BUS="y";
MDIO_DEVICE="y";
MDIO_DEVRES="y";
MEDIATEK_GE_PHY="y";
MEMFD_CREATE="y";
MFD_SYSCON="y";
MIGRATION="y";
MIKROTIK="y";
MIKROTIK_RB_SYSFS="y";
MIPS="y";
MIPS_ASID_BITS="8";
MIPS_ASID_SHIFT="0";
MIPS_CLOCK_VSYSCALL="y";
MIPS_CM="y";
MIPS_CPC="y";
MIPS_CPS="y";
MIPS_CPU_SCACHE="y";
MIPS_GIC="y";
MIPS_L1_CACHE_SHIFT="5";
MIPS_LD_CAN_LINK_VDSO="y";
MIPS_MT="y";
MIPS_MT_FPAFF="y";
MIPS_MT_SMP="y";
MIPS_NR_CPU_NR_MAP="4";
MIPS_PERF_SHARED_TC_COUNTERS="y";
MIPS_SPRAM="y";
MODULES_USE_ELF_REL="y";
MTD_CMDLINE_PARTS="y";
MTD_NAND_CORE="y";
MTD_NAND_ECC="y";
MTD_NAND_ECC_SW_HAMMING="y";
MTD_NAND_MT7621="y";
MTD_NAND_MTK_BMT="y";
MTD_RAW_NAND="y";
MTD_ROUTERBOOT_PARTS="y";
MTD_SERCOMM_PARTS="y";
MTD_SPI_NOR="y";
MTD_SPLIT_FIT_FW="y";
MTD_SPLIT_MINOR_FW="y";
MTD_SPLIT_SEAMA_FW="y";
MTD_SPLIT_TPLINK_FW="y";
MTD_SPLIT_TRX_FW="y";
MTD_SPLIT_UIMAGE_FW="y";
MTD_UBI="y";
MTD_UBI_BEB_LIMIT="20";
MTD_UBI_BLOCK="y";
MTD_UBI_WL_THRESHOLD="4096";
MTD_VIRT_CONCAT="y";
NEED_DMA_MAP_STATE="y";
NET_DEVLINK="y";
NET_DSA="y";
NET_DSA_MT7530="y";
NET_DSA_MT7530_MDIO="y";
NET_DSA_TAG_MTK="y";
NET_FLOW_LIMIT="y";
NET_MEDIATEK_SOC="y";
NET_SELFTESTS="y";
NET_SWITCHDEV="y";
NET_VENDOR_MEDIATEK="y";
NO_HZ_COMMON="y";
NO_HZ_IDLE="y";
NR_CPUS="4";
NVMEM="y";
OF="y";
OF_ADDRESS="y";
OF_EARLY_FLATTREE="y";
OF_FLATTREE="y";
OF_GPIO="y";
OF_IRQ="y";
OF_KOBJ="y";
OF_MDIO="y";
PAGE_POOL="y";
PAGE_POOL_STATS="y";
PCI="y";
PCIE_MT7621="y";
PCI_DISABLE_COMMON_QUIRKS="y";
PCI_DOMAINS="y";
PCI_DOMAINS_GENERIC="y";
PCI_DRIVERS_GENERIC="y";
PCS_MTK_LYNXI="y";
PERF_USE_VMALLOC="y";
PGTABLE_LEVELS="2";
PHYLIB="y";
PHYLINK="y";
PHY_MT7621_PCI="y";
PINCTRL="y";
PINCTRL_AW9523="y";
PINCTRL_MT7621="y";
PINCTRL_RALINK="y";
PINCTRL_SX150X="y";
POWER_RESET="y";
POWER_RESET_GPIO="y";
POWER_SUPPLY="y";
PTP_1588_CLOCK_OPTIONAL="y";
QUEUED_RWLOCKS="y";
QUEUED_SPINLOCKS="y";
RALINK="y";
RATIONAL="y";
REGMAP="y";
REGMAP_I2C="y";
REGMAP_MMIO="y";
REGULATOR="y";
REGULATOR_FIXED_VOLTAGE="y";
RESET_CONTROLLER="y";
RFS_ACCEL="y";
RPS="y";
RTC_CLASS="y";
RTC_DRV_BQ32K="y";
RTC_DRV_PCF8563="y";
RTC_I2C_AND_SPI="y";
SCHED_SMT="y";
SERIAL_8250="y";
SERIAL_8250_CONSOLE="y";
SERIAL_8250_NR_UARTS="3";
SERIAL_8250_RUNTIME_UARTS="3";
SERIAL_MCTRL_GPIO="y";
SERIAL_OF_PLATFORM="y";
SGL_ALLOC="y";
SMP="y";
SMP_UP="y";
SOCK_RX_QUEUE_MAPPING="y";
SOC_BUS="y";
SOC_MT7621="y";
SPI="y";
SPI_MASTER="y";
SPI_MEM="y";
SPI_MT7621="y";
SRCU="y";
SWPHY="y";
SYNC_R4K="y";
SYSCTL_EXCEPTION_TRACE="y";
SYS_HAS_CPU_MIPS32_R1="y";
SYS_HAS_CPU_MIPS32_R2="y";
SYS_HAS_EARLY_PRINTK="y";
SYS_SUPPORTS_32BIT_KERNEL="y";
SYS_SUPPORTS_ARBIT_HZ="y";
SYS_SUPPORTS_HIGHMEM="y";
SYS_SUPPORTS_HOTPLUG_CPU="y";
SYS_SUPPORTS_LITTLE_ENDIAN="y";
SYS_SUPPORTS_MIPS16="y";
SYS_SUPPORTS_MIPS_CPS="y";
SYS_SUPPORTS_MULTITHREADING="y";
SYS_SUPPORTS_SCHED_SMT="y";
SYS_SUPPORTS_SMP="y";
SYS_SUPPORTS_ZBOOT="y";
TARGET_ISA_REV="2";
TICK_CPU_ACCOUNTING="y";
TIMER_OF="y";
TIMER_PROBE="y";
TREE_RCU="y";
TREE_SRCU="y";
UBIFS_FS="y";
USB_SUPPORT="y";
USE_OF="y";
WEAK_ORDERING="y";
XPS="y";
XXHASH="y";
ZLIB_DEFLATE="y";
ZLIB_INFLATE="y";
ZSTD_COMPRESS="y";
ZSTD_DECOMPRESS="y";
} // lib.optionalAttrs (config.system.service ? watchdog) {
RALINK_WDT = "y"; # watchdog
MT7621_WDT = "y"; # or it might be this one
};
};
tplink-safeloader.board = "ARCHER-AX23-V1";
boot = {
commandLine = [ "console=ttyS0,115200" ];
tftp = {
# Should be a segment of free RAM, where the tftp artifact
# can be stored before unpacking it to the 'hardware.loadAddress'
# The 'hardware.loadAddress' is 0x80001000, which suggests the
# RAM would start at 0x8000000 and (being 128MB) go to
# to 0x8800000. Let's put it at the 100MB mark at
# 0x8000000+0x0640000=0x86400000
loadAddress = lim.parseInt "0x86400000";
compressRoot = true;
replaceDtb = true;
};
};
filesystem =
let inherit (pkgs.pseudofile) dir symlink;
in
dir {
lib = dir {
firmware = dir {
mediatek = symlink firmware;
};
};
};
hardware =
let
openwrt = pkgs.openwrt;
mac80211 = pkgs.mac80211.override {
drivers = [
"mt7915e"
];
klibBuild = config.system.outputs.kernel.modulesupport;
};
in {
# from OEM bootlog (openwrt wiki):
# 4 cmdlinepart partitions found on MTD device raspi
# Creating 4 MTD partitions on "raspi":
# 0x000000000000-0x000000040000 : "uboot"
# 0x000000040000-0x000000440000 : "uImage"
# 0x000000440000-0x000000ff0000 : "rootfs"
# 0x000000ff0000-0x000001000000 : "ART"
# from openwrt bootlog (openwrt wiki):
# 5 fixed-partitions partitions found on MTD device spi0.0
# OF: Bad cell count for /palmbus@1e000000/spi@b00/flash@0/partitions
# OF: Bad cell count for /palmbus@1e000000/spi@b00/flash@0/partitions
# OF: Bad cell count for /palmbus@1e000000/spi@b00/flash@0/partitions
# OF: Bad cell count for /palmbus@1e000000/spi@b00/flash@0/partitions
# Creating 5 MTD partitions on "spi0.0":
# 0x000000000000-0x000000040000 : "u-boot"
# 0x000000040000-0x000000fa0000 : "firmware"
# 2 uimage-fw partitions found on MTD device firmware
# Creating 2 MTD partitions on "firmware":
# 0x000000000000-0x0000002c0000 : "kernel"
# 0x0000002c0000-0x000000f60000 : "rootfs"
# mtd: setting mtd3 (rootfs) as root device
# 1 squashfs-split partitions found on MTD device rootfs
# 0x000000640000-0x000000f60000 : "rootfs_data"
# 0x000000fa0000-0x000000fb0000 : "config"
# 0x000000fb0000-0x000000ff0000 : "tplink"
# 0x000000ff0000-0x000001000000 : "radio"
flash = {
# from the OEM bootlog 'Booting image at bc040000'
# (0x40000 from 0xbc000000)
address = lim.parseInt "0xbc040000";
# 0x000000040000-0x000000fa0000
size = lim.parseInt "0xf60000";
# TODO: find in /proc/mtd on a running system
eraseBlockSize = 65536;
};
# since this is mentioned in the partition table as well?
defaultOutput = "tplink-safeloader";
# taken from openwrt sysupgrade image:
# openwrt-23.05.2-ramips-mt7621-tplink_archer-ax23-v1-squashfs-sysupgrade.bin: u-boot legacy uImage, MIPS OpenWrt Linux-5.15.137, Linux/MIPS, OS Kernel Image (lzma), 2797386 bytes, Tue Nov 14 13:38:11 2023, Load Address: 0X80001000, Entry Point: 0X80001000, Header CRC: 0X19F74C5B, Data CRC: 0XF685563C
loadAddress = lim.parseInt "0x80001000";
entryPoint = lim.parseInt "0x80001000";
rootDevice = "/dev/mtdblock3";
dts = {
src = "${openwrt.src}/target/linux/ramips/dts/mt7621_tplink_archer-ax23-v1.dts";
includes = [
"${openwrt.src}/target/linux/ramips/dts"
"${config.system.outputs.kernel.modulesupport}/arch/arm64/boot/dts/mediatek/"
];
};
networkInterfaces =
let
inherit (config.system.service.network) link;
inherit (config.system.service) bridge;
in rec {
lan1 = link.build { ifname = "lan1"; };
lan2 = link.build { ifname = "lan2"; };
lan3 = link.build { ifname = "lan3"; };
lan4 = link.build { ifname = "lan4"; };
wan = link.build { ifname = "wan"; };
wlan = link.build {
ifname = "wlan0";
dependencies = [ mac80211 ];
};
wlan5 = link.build {
ifname = "wlan1";
dependencies = [ mac80211 ];
};
};
};
};
};
}

159
examples/ax23-extneder.nix Normal file
View File

@ -0,0 +1,159 @@
{ config, pkgs, lib, ... } :
let
secrets = import ./ax23-secrets.nix;
inherit (pkgs) serviceFns;
svc = config.system.service;
wirelessConfig = {
country_code = "NL";
ssid = "FRITZ!Box 7581 TN";
wpa_passphrase = secrets.wpa_passphrase;
auth_algs = 1; # 1=wpa2, 2=wep, 3=both
wpa = 2; # 1=wpa, 2=wpa2, 3=both
wpa_key_mgmt = "WPA-PSK";
wpa_pairwise = "TKIP CCMP"; # auth for wpa (may not need this?)
rsn_pairwise = "CCMP"; # auth for wpa2
wmm_enabled = 1;
bridge = "int";
};
in rec {
imports = [
../modules/wlan.nix
../modules/network
../modules/dhcp6c
../modules/ssh
../modules/bridge
../modules/hostapd
../modules/outputs/kexecboot.nix
];
hostname = "yardbird";
boot.tftp = {
serverip = "192.168.0.1";
ipaddr = "192.168.0.2";
};
services.hostap = svc.hostapd.build {
interface = config.hardware.networkInterfaces.wlan;
params = {
# b/g/n/ax
hw_mode = "g";
channel = "2";
ieee80211n = 1;
driver="nl80211";
supported_rates="60 90 120 180 240 360 480 540";
basic_rates="60 120 240";
beacon_int="100";
ht_coex="0";
ht_capab="[LDPC][SHORT-GI-20][SHORT-GI-40][TX-STBC][RX-STBC1][MAX-AMSDU-7935]";
ap_isolate="1";
bss_load_update_period="60";
chan_util_avg_period="600";
disassoc_low_ack="1";
skip_inactivity_poll="0";
preamble="1";
wmm_enabled="1";
ignore_broadcast_ssid="0";
uapsd_advertisement_enabled="1";
utf8_ssid="1";
multi_ap="0";
auth_algs="1";
wpa="0";
wds_bridge="";
bssid="5c:e9:31:63:90:48";
} // wirelessConfig;
};
services.hostap5 = svc.hostapd.build {
interface = config.hardware.networkInterfaces.wlan5;
params = rec {
# a/n/ac/ax
hw_mode = "a";
channel = 36;
#ht_capab = "[HT40+]";
vht_oper_chwidth = 1;
vht_oper_centr_freq_seg0_idx = channel + 6;
ieee80211ac = 1;
driver="nl80211";
country_code="NL";
ieee80211d="1";
ieee80211h="1";
beacon_int="100";
chanlist="36";
tx_queue_data2_burst="2.0";
#num_global_macaddr=1;
ieee80211n="1";
ht_coex="0";
ht_capab="[HT40+][LDPC][SHORT-GI-20][SHORT-GI-40][TX-STBC][RX-STBC1][MAX-AMSDU-7935]";
#ieee80211ac="1";
#vht_oper_chwidth="1";
#vht_oper_centr_freq_seg0_idx="42";
vht_capab="[RXLDPC][SHORT-GI-80][TX-STBC-2BY1][SU-BEAMFORMER][SU-BEAMFORMEE][MU-BEAMFORMER][MU-BEAMFORMEE][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN][RX-STBC-1][SOUNDING-DIMENSION-2][BF-ANTENNA-2][MAX-MPDU-7991][MAX-A-MPDU-LEN-EXP7]";
ap_isolate="1";
bss_load_update_period="60";
chan_util_avg_period="600";
disassoc_low_ack="1";
skip_inactivity_poll="0";
preamble="1";
wmm_enabled="1";
ignore_broadcast_ssid="0";
uapsd_advertisement_enabled="1";
utf8_ssid="1";
multi_ap="0";
eapol_version="1";
auth_algs="1";
wpa="1";
wpa_pairwise="CCMP TKIP";
wds_bridge="";
wpa_disable_eapol_key_retries="0";
wpa_key_mgmt="WPA-PSK";
bssid="5c:e9:31:63:90:47";
#default_macaddr
} // wirelessConfig;
};
services.int = svc.network.address.build {
interface = svc.bridge.primary.build { ifname = "int"; };
family = "inet"; address = "10.8.0.1"; prefixLength = 16;
};
services.bridge = svc.bridge.members.build {
primary = services.int;
members = with config.hardware.networkInterfaces;
[ wlan
wlan5
lan1
lan2
lan3
lan4
wan
];
};
services.dhcpc = svc.network.dhcp.client.build {
interface = services.int;
# don't start DHCP until the hostname is configured,
# so it can identify itself to the DHCP server
dependencies = [ config.services.hostname ];
};
services.dhcp6c = svc.dhcp6c.client.build {
interface = services.int;
};
services.sshd = svc.ssh.build { };
users.root = secrets.root;
defaultProfile.packages = with pkgs; [
tcpdump
# for arp
nettools
# for kexec booting
gnutar
];
}

View File

@ -60,6 +60,9 @@ in
Combined kernel and FDT in uImage (U-Boot compatible) format
'';
};
tplink-safeloader = mkOption {
type = types.package;
};
u-boot = mkOption {
type = types.package;
};

View File

@ -22,6 +22,16 @@ in {
type = types.bool;
default = false;
};
replaceDtb = mkOption {
description = ''
Replace DTB instead of overriding it.
Useful for older versions of uboot that don't support
overriding the DTB from the bootm/bootz command line.
'';
type = types.bool;
default = false;
};
};
options.system.outputs = {
tftpboot = mkOption {
@ -63,8 +73,13 @@ in {
zimage = "bootz";
}; in choices.${cfg.kernelFormat};
cmdline = concatStringsSep " " config.boot.commandLine;
objcopy = "${pkgs.stdenv.cc.bintools.targetPrefix}objcopy";
stripAndZip = ''
${objcopy} -O binary -R .reginfo -R .notes -R .note -R .comment -R .mdebug -R .note.gnu.build-id -S vmlinux.elf vmlinux.bin
rm -f vmlinux.bin.lzma ; lzma -k -z vmlinux.bin
'';
in
pkgs.runCommand "tftpboot" { nativeBuildInputs = with pkgs.pkgsBuildBuild; [ lzma dtc ]; } ''
pkgs.runCommand "tftpboot" { nativeBuildInputs = with pkgs.pkgsBuildBuild; [ lzma dtc pkgs.stdenv.cc ubootTools ]; } ''
mkdir $out
cd $out
binsize() { local s=$(stat -L -c %s $1); echo $(($s + 0x1000 &(~0xfff))); }
@ -77,12 +92,19 @@ in {
imageSize=$(binsize ${image})
ln -s ${o.manifest} manifest
ln -s ${image} image
ln -s ${o.kernel} vmlinux # handy for gdb
${if cfg.compressRoot && cfg.replaceDtb
then ''
echo "Having both compressRoot and replaceDtb enabled is not currently supported"
exit 1
'' else ""
}
${if cfg.compressRoot
then ''
lzma -z9cv ${o.rootfs} > rootfs.lz
# TODO this is no longer correct
rootfsLzStart=$(($imageStart + $imageSize))
rootfsLzSize=$(binsize rootfs.lz)
''
@ -107,6 +129,13 @@ in {
cmd="liminix ${cmdline} mtdparts=phram0:''${rootfsSize}(rootfs) phram.phram=phram0,''${rootfsStart},''${rootfsSize},${toString config.hardware.flash.eraseBlockSize} root=/dev/mtdblock0";
fdtput -t s dtb /chosen bootargs "$cmd"
# re-package image with updated dtb
cp ${o.kernel} vmlinux.elf; chmod +w vmlinux.elf
${objcopy} --update-section .appended_dtb=dtb vmlinux.elf
${stripAndZip}
# TODO don't hardcode mips, entryPoint, loadAddress, name
mkimage -A mips -O linux -T kernel -C lzma -a 0x80001000 -e 0x80001000 -n 'MIPS Liminix Linux' -d vmlinux.bin.lzma image
# dtc -I dtb -O dts -o /dev/stdout dtb | grep -A10 chosen ; exit 1
cat > boot.scr << EOF

View File

@ -0,0 +1,61 @@
{
config
, pkgs
, lib
, ...
}:
let
inherit (lib) mkOption types concatStringsSep;
o = config.system.outputs;
cfg = config.tplink-safeloader;
in {
options.tplink-safeloader = {
board = mkOption {
type = types.str;
};
};
options.system.outputs = {
tplink-safeloader = mkOption {
type = types.package;
description = ''
tplink-safeloader
*****************
For creating 'safeloader' images for tp-link devices.
These can be flashed to the device using the firmware update feature
in the TP-link web UI or the OEM bootloader recovery: Use something
sharp to hold the 'reset' button while turning on the router until
only the orange LED remains lit. The router will assume IP address
192.168.0.1 and expect you to take 192.168.0.5 on one of the LAN ports.
On NixOS, use something like::
networking.interfaces.enp0s20f0u1c2 = {
ipv4.addresses = [ {
address = "192.168.0.5";
prefixLength = 24;
} ];
};
networking.networkmanager = {
unmanaged = [ "enp0s20f0u1c2" ];
};
This connection is rather somewhat temperamental, it may take a couple
of attempts, possibly re-attaching the USB dongle and running
``systemctl restart network-start.service``. The web interface does not
give accurate feedback (the progress bar is a lie), so you may want
to upload the firmware using ``curl -F firmware=@result http://192.168.0.1/f2.htm``.
After this shows a 'success' JSON, the image still needs to be
transferred from memory to flash, so be patient.
'';
};
};
config = {
system.outputs = rec {
tplink-safeloader =
pkgs.runCommand "tplink" { nativeBuildInputs = with pkgs.pkgsBuildBuild; [ firmware-utils ]; } ''
tplink-safeloader -B "${cfg.board}" -k "${o.uimage}" -r "${o.rootfs}" -o $out
'';
};
};
}

View File

@ -58,7 +58,8 @@ in {
anoia = callPackage ./anoia {};
fennel = callPackage ./fennel {};
fennelrepl = callPackage ./fennelrepl {};
firewallgen = callPackage ./firewallgen {};
firewallgen = callPackage ./firewallgen {};
firmware-utils = callPackage ./firmware-utils {};
gen_init_cpio = callPackage ./gen_init_cpio {};
go-l2tp = callPackage ./go-l2tp {};
hi = callPackage ./hi {};

View File

@ -0,0 +1,24 @@
{ stdenv
, fetchFromGitHub
, cmake
, zlib
, openssl
}:
stdenv.mkDerivation {
pname = "firmware-utils";
version = "snapshot";
src = fetchFromGitHub {
owner = "openwrt";
repo = "firmware-utils";
rev = "e87f23849790a7c77b4cd0e8ef0384da188174e5";
hash = "sha256-285Isf9sRuUt5S56SozgqpnS0+LOfnvpxpnWLwuWYUk=";
};
nativeBuildInputs = [
cmake
zlib
openssl
];
}