1
0
forked from dan/liminix

Compare commits

..

No commits in common. "add-archer-ax23-v1-bak" and "main" have entirely different histories.

32 changed files with 135 additions and 1128 deletions

8
NEWS
View File

@ -23,13 +23,5 @@ the name of an outputs that gloms together other filesystem-like
outputs with some kind of partition table - so we might in future have outputs with some kind of partition table - so we might in future have
gptimage or lvmimage or ubimage. gptimage or lvmimage or ubimage.
2024-01-03
Liminix is now targeted to Nixpkgs 23.11 (not 23.05 as previously).
Upstream changes that have led to incompatible Liminix changes are:
* newer U-Boot version
* util-linux can now be built (previously depended on systemd)

View File

@ -3707,10 +3707,9 @@ Here is scope of work for Turris:
recovery/install. recovery/install.
- disk partitioning tools and mkfs stuff - disk partitioning tools and mkfs stuff
- kernel with all the filesystems
- dhcp client for connecting to wired network - dhcp client for connecting to wired network
(II) we need instructions for building the real system (II) we need insttuctions for building the real system
and using min-copy-closure to copy and install the system and using min-copy-closure to copy and install the system
configuration of the real one into /mnt configuration of the real one into /mnt
@ -3743,147 +3742,14 @@ To be any use, the test needs to be end-to-end - as in, rather than
just checking some files are copied, test that the machine rebooted just checking some files are copied, test that the machine rebooted
successfully successfully
Fri Dec 29 18:36:16 GMT 2023
Our test for liminix-rebuild uses qemu block device and ext4 instead
of phram because -device loader doesn't seem to survive a reboot.
And it needs some free space in the ext4 partition inside the
mbr image so that it can install new stuff. However, the
filesystem is sized to be near-full.
If the mbrimage output is to be much use, probably there should be
some way of telling it how big the disk is. Maybe it should use
hardware.flash.size?
UBI also does a bad job of integrating into the hardware.flash hierarchy
(but ubi is also more complicated as the ubi volumes are "nested" inside
an MTD partition)
To move forwards with this test I think I will make it not depend on
mbrimage for now, but we have to come back to this. Maybe importing
the mbrimage module provides new hardware.disk = { partitions, size etc}
config options.
Sun Dec 31 23:52:04 GMT 2023
https://developer.ridgerun.com/wiki/index.php/Setting_up_fw_printenv_to_modify_u-boot_environment_variables#Preparing_the_fw_env.config_file
can we extract the fw_env config data somehow to produce an appropriate
file for the device?
the device config needs to specify partition name and offset at minimum,
possibly also size.
we can create a service that writes the config based on those values. but
if we are to be using fw_setenv from the shell, there is no service
which depends on that service. whatever defines the service also needs
to add it to system.services so that the recovery system can specify it
Sat Jan 6 12:30:27 GMT 2024
How do we min-copy-closure to the device when we don't have anything
hooked to the LAN port? It's rather easy to break the WAN connection
when it involves going out to the internet and back
* Don't want to plug it into the actual lan because it's doing dhcp service
and that is going to confuse
* the machine we're copying from is loaclhost
* we could do some kind of port forwarding thing? maybe a port forward on
run-border-vm qemu user networking ...
* static route on loaclhost?
512 sudo ip netns add test-lan
514 sudo ip link set dev enp1s0 netns test-lan
525 sudo ip link add veth-test-lan type veth peer veth1 netns test-lan
533 sudo ip netns exec test-lan ip link add name br0 type bridge
536 sudo ip netns exec test-lan ip link set veth1 master br0
537 sudo ip netns exec test-lan ip link set enp1s0 master br0
sudo ip netns exec test-lan /nix/store/dh66q9k402pwpmmgc983xwmwb3vvvjbr-busybox-1.36.1/bin/busybox udhcpc -i br0
then we could add a route to 10.8.0.1/32 with dev veth-test-lan ?
Sat Jan 6 20:52:45 GMT 2024
This is all beside the point right now because the _recovery_ system
does not run all this stuff - it just has a dhcp client on the lan
interface. We could plug it straight into the switch.
As we already just plugged it into enp1s0 on loaclhost, could we COPYING /nix/store/dlz86nip271ybaz0cip7bgkbzijk0cr7-make-stuff-mips-unknown-linux-musl TO //persist
do somethin to put it on the lan from there? add it to vbridge0?
Sun Jan 7 15:30:57 GMT 2024
Turns out we should have used a working ethernet cable.
Sun Jan 7 15:31:14 GMT 2024
OK, so
# on device
mount /dev/mmcblk0p1 /mnt
[ take a snapshot if needed ]
[ clear out the turrisos files ]
ls /mnt/@
# on build
$ nix-build -I liminix-config=./examples/rotuer.nix --arg device "import ./devices/turris-omnia" -A outputs.systemConfiguration
$ nix-shell --run "min-copy-closure -r /mnt/@ root@recovery.lan result "
# on device
$ mkdir /mnt/@/persist
$ /mnt/@/nix/store/swf3vn9bzx198c0cwp6naq0glqa9192n-make-stuff-armv7l-unknown-linux-musleabihf/bin/install /mnt/@/
this fails because it tries to copy from the unprefixed nix
store. Also probably it should mkdir $prefix/persist. Also it needs to
create $prefix/boot: it's too late to do that with `activate`
because u-boot will need it to exist in order to load the initramfs
that runs activate
Thu Jan 11 23:36:47 GMT 2024
squashfs rootfsType doesn't rebuild when the kernel config is changed
Mon Jan 22 19:04:45 GMT 2024
setenv serverip 10.0.0.1
setenv ipaddr 10.0.0.8
compraddr=0x01000000
tftpboot ${compraddr} recovery.img.lzma
setexpr writeaddr ${filesize} + $compraddr
lzmadec ${compraddr} $writeaddr
usb start
usb dev 0
wdt dev watchdog@20300
wdt stop
usb write ${writeaddr} 0 ${filesize}
Thu Jan 25 11:55:36 GMT 2024 /nix/store/gr255qjxijksf9361glsj5lz0cklassx-profile
openwrt: md5sum /persist/activate
CONFIG_BROADCOM_PHY=m 8eb0760c39cdee0b141b15bbafbc94a0 /persist/activate BAD
CONFIG_FIXED_PHY=y 6c27b75cbe9f2ce87c1fd1425362108f /persist/activate GOOD
CONFIG_GENERIC_PHY=y 8eb0760c39cdee0b141b15bbafbc94a0 /persist/activate
CONFIG_IP17XX_PHY=m ?
CONFIG_MARVELL_PHY=y
CONFIG_MVSW61XX_PHY=y ?
CONFIG_RTL8366RB_PHY=m ?
CONFIG_RTL8366S_PHY=m ?
CONFIG_RTL8367B_PHY=m ?
CONFIG_SWPHY=y
CONFIG_USB_PHY=y
CONFIG_FIXED_PHY=y
CONFIG_GENERIC_PHY=y
CONFIG_MARVELL_PHY=y
CONFIG_PHY_MVEBU_A3700_COMPHY=y
CONFIG_PHY_MVEBU_A38X_COMPHY=y
CONFIG_SWPHY=y
#

1
ci.nix
View File

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

View File

@ -67,7 +67,6 @@ in {
go-l2tp go-l2tp
min-copy-closure min-copy-closure
fennelrepl fennelrepl
lzma
]; ];
}; };
} }

View File

@ -57,8 +57,8 @@
kernel = { kernel = {
src = pkgs.pkgsBuildBuild.fetchurl { src = pkgs.pkgsBuildBuild.fetchurl {
name = "linux.tar.gz"; name = "linux.tar.gz";
url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.137.tar.gz"; url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.71.tar.gz";
hash = "sha256-PkdzUKZ0IpBiWe/RS70J76JKnBFzRblWcKlaIFNxnHQ="; hash = "sha256-yhO2cXIeIgUxkSZf/4aAsF11uxyh+UUZu6D1h92vCD8=";
}; };
extraPatchPhase = '' extraPatchPhase = ''
${pkgs.openwrt.applyPatches.mediatek} ${pkgs.openwrt.applyPatches.mediatek}
@ -144,10 +144,6 @@
# SERIAL_8250_NR_UARTS="3"; # SERIAL_8250_NR_UARTS="3";
# SERIAL_8250_RUNTIME_UARTS="3"; # SERIAL_8250_RUNTIME_UARTS="3";
SERIAL_OF_PLATFORM="y"; SERIAL_OF_PLATFORM="y";
# Must enble hardware watchdog drivers. Else the device reboots after several seconds
WATCHDOG = "y";
MEDIATEK_WATCHDOG = "y";
}; };
}; };
boot = { boot = {

View File

@ -7,8 +7,8 @@
kernel = { kernel = {
src = pkgs.pkgsBuildBuild.fetchurl { src = pkgs.pkgsBuildBuild.fetchurl {
name = "linux.tar.gz"; name = "linux.tar.gz";
url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.137.tar.gz"; url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.71.tar.gz";
hash = "sha256-PkdzUKZ0IpBiWe/RS70J76JKnBFzRblWcKlaIFNxnHQ="; hash = "sha256-yhO2cXIeIgUxkSZf/4aAsF11uxyh+UUZu6D1h92vCD8=";
}; };
config = { config = {
MTD = "y"; MTD = "y";

View File

@ -152,8 +152,8 @@
kernel = { kernel = {
src = pkgs.pkgsBuildBuild.fetchurl { src = pkgs.pkgsBuildBuild.fetchurl {
name = "linux.tar.gz"; name = "linux.tar.gz";
url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.137.tar.gz"; url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.71.tar.gz";
hash = "sha256-PkdzUKZ0IpBiWe/RS70J76JKnBFzRblWcKlaIFNxnHQ="; hash = "sha256-yhO2cXIeIgUxkSZf/4aAsF11uxyh+UUZu6D1h92vCD8=";
}; };
# Mainline linux 5.19 doesn't have device-tree support for # Mainline linux 5.19 doesn't have device-tree support for

View File

@ -131,8 +131,8 @@
kernel = { kernel = {
src = pkgs.fetchurl { src = pkgs.fetchurl {
name = "linux.tar.gz"; name = "linux.tar.gz";
url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.137.tar.gz"; url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.71.tar.gz";
hash = "sha256-PkdzUKZ0IpBiWe/RS70J76JKnBFzRblWcKlaIFNxnHQ="; hash = "sha256-yhO2cXIeIgUxkSZf/4aAsF11uxyh+UUZu6D1h92vCD8=";
}; };
extraPatchPhase = '' extraPatchPhase = ''
${openwrt.applyPatches.ramips} ${openwrt.applyPatches.ramips}

View File

@ -127,8 +127,8 @@
kernel = { kernel = {
src = pkgs.fetchurl { src = pkgs.fetchurl {
name = "linux.tar.gz"; name = "linux.tar.gz";
url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.137.tar.gz"; url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.71.tar.gz";
hash = "sha256-PkdzUKZ0IpBiWe/RS70J76JKnBFzRblWcKlaIFNxnHQ="; hash = "sha256-yhO2cXIeIgUxkSZf/4aAsF11uxyh+UUZu6D1h92vCD8=";
}; };
extraPatchPhase = '' extraPatchPhase = ''
${openwrt.applyPatches.ramips} ${openwrt.applyPatches.ramips}

View File

@ -1,437 +0,0 @@
{
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
];
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";
};
};
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 ];
};
};
};
};
};
}

View File

@ -2,27 +2,6 @@
description = '' description = ''
Turris Omnia Turris Omnia
************ ************
This is a 32 bit ARMv7 MVEBU device, which is usually shipped with
TurrisOS, an OpenWrt-based system. Rather than reformatting the
builtin storage, we install Liminix on to the existing btrfs
filesystem so that the vendor snapshot/recovery system continues
to work (and provides you an easy rollback if you decide you don't
like Liminix after all).
The install process is designed so that you should not need to open
the device and add a serial console (although it may be handy
for visibility and in case anything goes wrong). In outline
1. build a "recovery" system with useful btrfs tools
2. boot that system using TFTP or a USB stick
3. once booted, mount the real root filesystem on /mnt
4. take a snapshot using schnapps, and then delete everything
5. use min-copy-closure -d /mnt/@ to copy the real configuration
to the device
6. reboot into a fully operational system
Detailed instructions to follow...
''; '';
system = { system = {
@ -51,6 +30,7 @@
imports = [ imports = [
../../modules/arch/arm.nix ../../modules/arch/arm.nix
../../modules/outputs/tftpboot.nix ../../modules/outputs/tftpboot.nix
../../modules/outputs/ext4fs.nix
../../modules/outputs/mbrimage.nix ../../modules/outputs/mbrimage.nix
../../modules/outputs/extlinux.nix ../../modules/outputs/extlinux.nix
]; ];
@ -60,8 +40,8 @@
kernel = { kernel = {
src = pkgs.pkgsBuildBuild.fetchurl { src = pkgs.pkgsBuildBuild.fetchurl {
name = "linux.tar.gz"; name = "linux.tar.gz";
url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.137.tar.gz"; url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.71.tar.gz";
hash = "sha256-PkdzUKZ0IpBiWe/RS70J76JKnBFzRblWcKlaIFNxnHQ="; hash = "sha256-yhO2cXIeIgUxkSZf/4aAsF11uxyh+UUZu6D1h92vCD8=";
}; };
extraPatchPhase = '' extraPatchPhase = ''
${pkgs.openwrt.applyPatches.mvebu} ${pkgs.openwrt.applyPatches.mvebu}
@ -130,10 +110,6 @@
MVNETA_BM_ENABLE = "y"; MVNETA_BM_ENABLE = "y";
SRAM = "y"; # mmio-sram is "compatible" for bm_bppi reqd by BM SRAM = "y"; # mmio-sram is "compatible" for bm_bppi reqd by BM
PHY_MVEBU_A38X_COMPHY = "y"; # for eth2 PHY_MVEBU_A38X_COMPHY = "y"; # for eth2
MARVELL_PHY = "y";
USB_XHCI_MVEBU = "y";
USB_XHCI_HCD = "y";
MVPP2 = "y"; MVPP2 = "y";
MV_XOR = "y"; MV_XOR = "y";
@ -151,12 +127,13 @@
NET_DSA_MV88E6XXX = "y"; # depends on PTP_1588_CLOCK_OPTIONAL NET_DSA_MV88E6XXX = "y"; # depends on PTP_1588_CLOCK_OPTIONAL
}; };
}; };
rootfsType = "ext4";
boot = { boot = {
commandLine = [ commandLine = [
"console=ttyS0,115200" "console=ttyS0,115200"
"pcie_aspm=off" # ath9k pci incompatible with PCIe ASPM "pcie_aspm=off" # ath9k pci incompatible with PCIe ASPM
]; ];
imageFormat = "fit";
}; };
filesystem = filesystem =
let let
@ -199,7 +176,7 @@
defaultOutput = "mtdimage"; defaultOutput = "mtdimage";
loadAddress = lim.parseInt "0x00800000"; # "0x00008000"; loadAddress = lim.parseInt "0x00800000"; # "0x00008000";
entryPoint = lim.parseInt "0x00800000"; # "0x00008000"; entryPoint = lim.parseInt "0x00800000"; # "0x00008000";
rootDevice = "/dev/mmcblk0p1"; rootDevice = "/dev/mtdblock0";
dts = { dts = {
src = "${config.system.outputs.kernel.modulesupport}/arch/arm/boot/dts/armada-385-turris-omnia.dts"; src = "${config.system.outputs.kernel.modulesupport}/arch/arm/boot/dts/armada-385-turris-omnia.dts";
@ -233,7 +210,7 @@
# per # per
# https://www.kernel.org/doc/html/latest/networking/dsa/configuration.html#affinity-of-user-ports-to-cpu-ports # https://www.kernel.org/doc/html/latest/networking/dsa/configuration.html#affinity-of-user-ports-to-cpu-ports
# but apparently OpenWrt doesn't either so maybe it's more # but apparently OpenWrt doesn't either so maybe it's more
# complicated than it looks. # complicated than it looks
wan = link.build { wan = link.build {
# in armada-38x.dtsi this is eth2. It may be connected to # in armada-38x.dtsi this is eth2. It may be connected to
@ -242,13 +219,9 @@
ifname = "wan"; ifname = "wan";
}; };
lan0 = link.build { ifname = "lan0"; }; lan = link.build {
lan1 = link.build { ifname = "lan1"; }; ifname = "lan1";
lan2 = link.build { ifname = "lan2"; }; };
lan3 = link.build { ifname = "lan3"; };
lan4 = link.build { ifname = "lan4"; };
lan5 = link.build { ifname = "lan5"; };
lan = lan0; # maybe we should build a bridge?
wlan = link.build { wlan = link.build {
ifname = "wlan0"; ifname = "wlan0";

View File

@ -1,104 +0,0 @@
{ config, pkgs, lib, ... } :
let
inherit (pkgs) serviceFns;
svc = config.system.service;
inherit (pkgs.pseudofile) dir symlink;
inherit (pkgs.liminix.services) oneshot longrun bundle target;
some-util-linux = pkgs.runCommand "some-util-linux" {} ''
mkdir -p $out/bin
cd ${pkgs.util-linux-small}/bin
cp fdisk sfdisk mkswap $out/bin
'';
in rec {
imports = [
../modules/network
../modules/ssh
../modules/usb.nix
../modules/schnapps
../modules/outputs/mtdimage.nix
../modules/outputs/mbrimage.nix
../modules/outputs/tftpboot.nix
../modules/outputs/ubifs.nix
../modules/outputs/ubimage.nix
../modules/outputs/jffs2.nix
../modules/outputs/ext4fs.nix
];
kernel.config = {
BTRFS_FS = "y";
};
boot.tftp = {
ipaddr = "10.0.0.8"; # my address
serverip = "10.0.0.1"; # build machine or other tftp server
freeSpaceBytes = 1024 * 1024 * 4;
};
hostname = "recovery";
services.dhcpc = svc.network.dhcp.client.build {
interface = config.hardware.networkInterfaces.lan2;
# don't start DHCP until the hostname is configured,
# so it can identify itself to the DHCP server
dependencies = [ config.services.hostname ];
};
services.sshd = svc.ssh.build {
dependencies = [ config.services.growfs ];
};
services.defaultroute4 = svc.network.route.build {
via = "$(output ${services.dhcpc} router)";
target = "default";
dependencies = [services.dhcpc];
};
services.resolvconf = oneshot rec {
dependencies = [ services.dhcpc ];
name = "resolvconf";
up = ''
. ${serviceFns}
( in_outputs ${name}
for i in $(output ${services.dhcpc} dns); do
echo "nameserver $i" > resolv.conf
done
)
'';
};
services.growfs = let name = "growfs"; in oneshot {
inherit name;
up = ''
. ${serviceFns}
device=$(grep /persist /proc/1/mountinfo | cut -f9 -d' ')
${pkgs.e2fsprogs}/bin/resize2fs $device
'';
};
filesystem = dir {
etc = dir {
"resolv.conf" = symlink "${services.resolvconf}/.outputs/resolv.conf";
};
mnt = dir {};
};
rootfsType = "ext4";
# sda is most likely correct for the boot-from-USB case. For tftp
# it's overridden by the boot.scr anyway, so maybe it all works out
hardware.rootDevice = "/dev/sda1";
users.root = {
# the password is "secret". Use mkpasswd -m sha512crypt to
# create this hashed password string
passwd = "$6$y7WZ5hM6l5nriLmo$5AJlmzQZ6WA.7uBC7S8L4o19ESR28Dg25v64/vDvvCN01Ms9QoHeGByj8lGlJ4/b.dbwR9Hq2KXurSnLigt1W1";
};
defaultProfile.packages = with pkgs; [
e2fsprogs # ext4
btrfs-progs
mtdutils # mtd, jffs2, ubifs
dtc # you never know when you might need device tree stuff
some-util-linux
libubootenv # fw_{set,print}env
pciutils
];
}

View File

@ -43,13 +43,8 @@ in rec {
../modules/bridge ../modules/bridge
../modules/ntp ../modules/ntp
../modules/ssh ../modules/ssh
../modules/outputs/btrfs.nix
../modules/outputs/extlinux.nix
]; ];
hostname = "rotuer"; hostname = "rotuer";
rootfsType = "btrfs";
rootOptions = "subvol=@";
boot.loader.extlinux.enable = true;
services.hostap = svc.hostapd.build { services.hostap = svc.hostapd.build {
interface = config.hardware.networkInterfaces.wlan; interface = config.hardware.networkInterfaces.wlan;

View File

@ -40,18 +40,12 @@ in {
rootfsType = mkOption { rootfsType = mkOption {
default = "squashfs"; default = "squashfs";
type = types.enum [ type = types.enum [
"btrfs"
"ext4" "ext4"
"jffs2" "jffs2"
"squashfs" "squashfs"
"ubifs" "ubifs"
]; ];
}; };
rootOptions = mkOption {
type = types.nullOr types.str;
default = null;
};
boot = { boot = {
commandLine = mkOption { commandLine = mkOption {
type = types.listOf types.nonEmptyStr; type = types.listOf types.nonEmptyStr;
@ -100,8 +94,7 @@ in {
"root=${config.hardware.rootDevice}" "root=${config.hardware.rootDevice}"
"rootfstype=${config.rootfsType}" "rootfstype=${config.rootfsType}"
"fw_devlink=off" "fw_devlink=off"
] ++ lib.optional (config.rootOptions != null) "rootflags=${config.rootOptions}"; ];
users.root = { users.root = {
uid = 0; gid= 0; gecos = "Root of all evaluation"; uid = 0; gid= 0; gecos = "Root of all evaluation";
dir = "/home/root/"; dir = "/home/root/";
@ -141,7 +134,6 @@ in {
proc = dir {}; proc = dir {};
run = dir {}; run = dir {};
sys = dir {}; sys = dir {};
tmp = dir {};
}; };
}; };
} }

View File

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

View File

@ -1,37 +0,0 @@
{
config
, pkgs
, lib
, ...
}:
let
inherit (lib) mkIf mkOption types;
o = config.system.outputs;
in
{
imports = [
./initramfs.nix
];
config = mkIf (config.rootfsType == "btrfs") {
kernel.config = {
BTRFS_FS = "y";
};
boot.initramfs.enable = true;
system.outputs = {
rootfs =
let
inherit (pkgs.pkgsBuildBuild) runCommand e2fsprogs;
in runCommand "mkfs.btrfs" {
depsBuildBuild = [ e2fsprogs ];
} ''
tree=${o.bootablerootdir}
size=$(du -s --apparent-size --block-size 1024 $tree |cut -f1)
# add 25% for filesystem overhead
size=$(( 5 * $size / 4))
dd if=/dev/zero of=$out bs=1024 count=$size
echo "not implemented" ; exit 1
# mke2fs -t ext4 -j -d $tree $out
'';
};
};
}

View File

@ -6,7 +6,6 @@
}: }:
let let
inherit (lib) mkIf mkEnableOption mkOption types concatStringsSep; inherit (lib) mkIf mkEnableOption mkOption types concatStringsSep;
inherit (pkgs.pseudofile) dir symlink;
cfg = config.boot.loader.extlinux; cfg = config.boot.loader.extlinux;
o = config.system.outputs; o = config.system.outputs;
cmdline = concatStringsSep " " config.boot.commandLine; cmdline = concatStringsSep " " config.boot.commandLine;
@ -18,7 +17,7 @@ in {
}; };
options.boot.loader.extlinux.enable = mkEnableOption "extlinux"; options.boot.loader.extlinux.enable = mkEnableOption "extlinux";
config = mkIf cfg.enable { config = { # mkIf cfg.enable {
system.outputs.extlinux = pkgs.runCommand "extlinux" {} '' system.outputs.extlinux = pkgs.runCommand "extlinux" {} ''
mkdir $out mkdir $out
cd $out cd $out
@ -28,16 +27,13 @@ in {
mkdir extlinux mkdir extlinux
cat > extlinux/extlinux.conf << _EOF cat > extlinux/extlinux.conf << _EOF
menu title Liminix menu title Liminix
timeout 40 timeout 100
label Liminix label Liminix
kernel /boot/kernel kernel /boot/kernel
# initrd /boot/initramfs # initrd /boot/initramfs
append ${cmdline} append ${cmdline} root=/dev/vda1
${if wantsDtb then "fdt /boot/dtb" else ""} ${if wantsDtb then "fdt /boot/dtb" else ""}
_EOF _EOF
''; '';
filesystem = dir {
boot = symlink config.system.outputs.extlinux;
};
}; };
} }

View File

@ -72,8 +72,9 @@ in {
hex() { printf "0x%x" $1; } hex() { printf "0x%x" $1; }
rootfsStart=${toString cfg.loadAddress} rootfsStart=${toString cfg.loadAddress}
rootfsSize=$(binsize64k ${o.rootfs} ) rootfsSize=$(binsize64k ${o.rootfs} )
rootfsSize=$(($rootfsSize + ${toString cfg.freeSpaceBytes} ))
dtbStart=$(($rootfsStart + $rootfsSize)) dtbStart=$(($rootfsStart + $rootfsSize))
dtbSize=$(binsize ${o.dtb} )
imageStart=$(($dtbStart + $dtbSize))
imageSize=$(binsize ${image}) imageSize=$(binsize ${image})
ln -s ${o.manifest} manifest ln -s ${o.manifest} manifest
@ -101,9 +102,6 @@ in {
fdtput -p -t s dtb /reserved-memory/$node compatible phram fdtput -p -t s dtb /reserved-memory/$node compatible phram
fdtput -p -t lx dtb /reserved-memory/$node reg $ac_prefix $(hex $rootfsStart) $sz_prefix $(hex $rootfsSize) fdtput -p -t lx dtb /reserved-memory/$node reg $ac_prefix $(hex $rootfsStart) $sz_prefix $(hex $rootfsSize)
dtbSize=$(binsize ./dtb )
imageStart=$(($dtbStart + $dtbSize))
cmd="liminix ${cmdline} mtdparts=phram0:''${rootfsSize}(rootfs) phram.phram=phram0,''${rootfsStart},''${rootfsSize},${toString config.hardware.flash.eraseBlockSize} root=/dev/mtdblock0"; 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" fdtput -t s dtb /chosen bootargs "$cmd"

View File

@ -1,61 +0,0 @@
{
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

@ -17,7 +17,6 @@ shift
mount -t proc none /proc mount -t proc none /proc
mount -t sysfs none /sys mount -t sysfs none /sys
mount -t tmpfs none /tmp
# s6-linux-init mounts /dev before this script is called # s6-linux-init mounts /dev before this script is called
mkdir /dev/pts mkdir /dev/pts
mount -t devpts none /dev/pts mount -t devpts none /dev/pts

View File

@ -1,19 +0,0 @@
{ config, pkgs, lib, ... } :
{
config = {
programs.busybox = {
options = {
# schnapps is a shell script that needs
# [ command
# find -maxdepth -mindepth
# head -c
# echo -n
ASH_TEST = "y";
FEATURE_FIND_MAXDEPTH = "y";
FEATURE_FANCY_HEAD = "y";
FEATURE_FANCY_ECHO = "y";
};
};
defaultProfile.packages = [ pkgs.schnapps ] ;
};
}

View File

@ -1,31 +0,0 @@
# support for USB block devices and the common filesystems
# they're likely to provide
{lib, config, ... }:
{
kernel = {
config = {
USB = "y";
USB_EHCI_HCD = "y";
USB_EHCI_HCD_PLATFORM = "y";
USB_OHCI_HCD = "y";
USB_OHCI_HCD_PLATFORM = "y";
USB_SUPPORT = "y";
USB_COMMON = "y";
USB_STORAGE = "y";
USB_STORAGE_DEBUG = "n";
USB_UAS = "y";
USB_ANNOUNCE_NEW_DEVICES = "y";
SCSI = "y";
BLK_DEV_SD = "y";
USB_PRINTER = "y";
MSDOS_PARTITION = "y";
EFI_PARTITION = "y";
EXT4_FS = "y";
EXT4_USE_FOR_EXT2 = "y";
FS_ENCRYPTION = "y";
};
};
}

View File

@ -50,12 +50,6 @@ extraPkgs // {
}; };
# keep these alphabetical # keep these alphabetical
btrfs-progs = prev.btrfs-progs.override {
udevSupport = false;
udev = null;
};
chrony = chrony =
let chrony' = prev.chrony.overrideAttrs(o: { let chrony' = prev.chrony.overrideAttrs(o: {
configureFlags = [ configureFlags = [

View File

@ -10,7 +10,10 @@ let
type' = types.submodule { options = type; }; type' = types.submodule { options = type; };
in (mergeDefinitions [] type' defs).mergedValue; in (mergeDefinitions [] type' defs).mergedValue;
in { in {
pseudofile = callPackage ./pseudofile {};
liminix = { liminix = {
services = callPackage ./liminix-tools/services {};
networking = callPackage ./liminix-tools/networking {};
builders = { builders = {
squashfs = callPackage ./liminix-tools/builders/squashfs.nix {}; squashfs = callPackage ./liminix-tools/builders/squashfs.nix {};
dtb = callPackage ./kernel/dtb.nix {}; dtb = callPackage ./kernel/dtb.nix {};
@ -49,27 +52,32 @@ in {
}; };
inherit typeChecked; inherit typeChecked;
}; };
networking = callPackage ./liminix-tools/networking {};
services = callPackage ./liminix-tools/services {};
}; };
writeFennelScript = callPackage ./write-fennel-script {};
writeFennel = callPackage ./write-fennel {};
writeAshScript = callPackage ./write-ash-script {};
systemconfig = callPackage ./systemconfig {};
s6-init-bin = callPackage ./s6-init-bin {};
s6-rc-database = callPackage ./s6-rc-database {};
run-liminix-vm = callPackage ./run-liminix-vm {};
ppp = callPackage ./ppp {};
pppoe = callPackage ./pppoe {};
# please keep the rest of this list alphabetised :-)
anoia = callPackage ./anoia {};
fennel = callPackage ./fennel {};
fennelrepl = callPackage ./fennelrepl {};
firewallgen = callPackage ./firewallgen {};
firmware-utils = callPackage ./firmware-utils {};
gen_init_cpio = callPackage ./gen_init_cpio {};
go-l2tp = callPackage ./go-l2tp {};
hi = callPackage ./hi {};
ifwait = callPackage ./ifwait {};
initramfs-peek = callPackage ./initramfs-peek {};
kernel-backport = callPackage ./kernel-backport {}; kernel-backport = callPackage ./kernel-backport {};
kernel-modules = callPackage ./kernel-modules {}; mac80211 = callPackage ./mac80211 {};
levitate = callPackage ./levitate {}; netlink-lua = callPackage ./netlink-lua {};
libubootenv = callPackage ./libubootenv {};
linotify = callPackage ./linotify {}; linotify = callPackage ./linotify {};
ifwait = callPackage ./ifwait {};
gen_init_cpio = callPackage ./gen_init_cpio {};
serviceFns = callPackage ./service-fns {};
# these are packages for the build system not the host/target
tufted = callPackage ./tufted {};
routeros = callPackage ./routeros {};
go-l2tp = callPackage ./go-l2tp {};
# we need to build real lzma instead of using xz, because the lzma # we need to build real lzma instead of using xz, because the lzma
# decoder in u-boot doesn't understand streaming lzma archives # decoder in u-boot doesn't understand streaming lzma archives
@ -78,33 +86,24 @@ in {
# https://sourceforge.net/p/squashfs/mailman/message/26599379/ # https://sourceforge.net/p/squashfs/mailman/message/26599379/
lzma = callPackage ./lzma {}; lzma = callPackage ./lzma {};
mac80211 = callPackage ./mac80211 {}; preinit = callPackage ./preinit {};
swconfig = callPackage ./swconfig {};
odhcp6c = callPackage ./odhcp6c {};
openwrt = callPackage ./openwrt {};
initramfs-peek = callPackage ./initramfs-peek {};
min-collect-garbage = callPackage ./min-collect-garbage {}; min-collect-garbage = callPackage ./min-collect-garbage {};
min-copy-closure = callPackage ./min-copy-closure {}; min-copy-closure = callPackage ./min-copy-closure {};
netlink-lua = callPackage ./netlink-lua {}; hi = callPackage ./hi {};
firewallgen = callPackage ./firewallgen {};
kernel-modules = callPackage ./kernel-modules {};
odhcp-script = callPackage ./odhcp-script {}; odhcp-script = callPackage ./odhcp-script {};
odhcp6c = callPackage ./odhcp6c {}; fennel = callPackage ./fennel {};
openwrt = callPackage ./openwrt {}; fennelrepl = callPackage ./fennelrepl {};
ppp = callPackage ./ppp {}; anoia = callPackage ./anoia {};
pppoe = callPackage ./pppoe {};
preinit = callPackage ./preinit {};
pseudofile = callPackage ./pseudofile {};
routeros = callPackage ./routeros {};
run-liminix-vm = callPackage ./run-liminix-vm {};
s6-init-bin = callPackage ./s6-init-bin {};
s6-rc-database = callPackage ./s6-rc-database {};
# schnapps is written by Turris and provides a high-level interface levitate = callPackage ./levitate {};
# to btrfs snapshots. It may be useful on the Turris Omnia to
# install Liminix while retaining the ability to rollback to the
# vendor OS, or even to derisk Liminix updates on that device
schnapps = callPackage ./schnapps {};
serviceFns = callPackage ./service-fns {}; libubootenv = callPackage ./libubootenv {};
swconfig = callPackage ./swconfig {};
systemconfig = callPackage ./systemconfig {};
tufted = callPackage ./tufted {};
writeAshScript = callPackage ./write-ash-script {};
writeFennel = callPackage ./write-fennel {};
writeFennelScript = callPackage ./write-fennel-script {};
} }

View File

@ -1,24 +0,0 @@
{ 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
];
}

View File

@ -12,7 +12,7 @@ target_host=$1
shift shift
if [ -z "$target_host" ] ; then if [ -z "$target_host" ] ; then
echo Usage: liminix-rebuild \[--no-reboot\] target-host params echo Usage: liminix-rebuild [--no-reboot] target-host params
exit 1 exit 1
fi fi

View File

@ -7,8 +7,8 @@ let
name = "openwrt-source"; name = "openwrt-source";
repo = "openwrt"; repo = "openwrt";
owner = "openwrt"; owner = "openwrt";
rev = "refs/tags/v23.05.2"; rev = "a5265497a4f6da158e95d6a450cb2cb6dc085cab";
hash = "sha256-kP+cSOB6LiOMWs7g+ji7P7ehiDYDwRdmT4R5jSzw6K4="; hash = "sha256-YYi4gkpLjbOK7bM2MGQjAyEBuXJ9JNXoz/JEmYf8xE8=";
}; };
doPatch = family : '' doPatch = family : ''
cp -av ${src}/target/linux/generic/files/* . cp -av ${src}/target/linux/generic/files/* .

View File

@ -1,7 +0,0 @@
struct root_opts {
char *device;
char *fstype;
char *mount_opts;
};
void parseopts(char * cmdline, struct root_opts *opts);

View File

@ -3,9 +3,6 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include "opts.h"
static int begins_with(char * str, char * prefix) static int begins_with(char * str, char * prefix)
{ {
while(*prefix) { while(*prefix) {
@ -39,37 +36,34 @@ char * pr_u32(int32_t input) {
i+=2; i+=2;
buf[i] ='\0'; buf[i] ='\0';
if(write(2, buf, i)) write(2, buf, i);
return buf; return buf;
else
return NULL;
} }
static char *eat_word(char *p)
{ void parseopts(char * cmdline, char **root, char **rootfstype) {
*root = 0;
*rootfstype = 0;
for(char *p = cmdline; *p; p++) {
if(begins_with(p, "root=")) {
*root = p + strlen("root=");
while(*p && (*p != ' ')) p++; while(*p && (*p != ' ')) p++;
if(*p) { if(*p) {
*p = '\0'; *p = '\0';
p++; p++;
}; };
return p;
}
static char * eat_param(char *p, char *param_name, char **out)
{
if(begins_with(p, param_name)) {
*out = p + strlen(param_name);
p = eat_word(p);
}; };
return p; if(begins_with(p, "rootfstype=")) {
} *rootfstype = p + strlen("rootfstype=");
while(*p && (*p != ' ')) p++;
void parseopts(char * cmdline, struct root_opts *opts) { if(*p) {
for(char *p = cmdline; *p; p++) { *p = '\0';
p = eat_param(p, "root=", &(opts->device)); p++;
p = eat_param(p, "rootfstype=", &(opts->fstype)); };
p = eat_param(p, "rootflags=", &(opts->mount_opts)); };
}; };
} }
@ -88,59 +82,45 @@ void parseopts(char * cmdline, struct root_opts *opts) {
int main() int main()
{ {
struct root_opts opts = { char * root = "/dev/hda1";
.device = "/dev/hda1", char * rootfstype = "xiafs";
.fstype = "xiafs",
.mount_opts = NULL
};
char *buf; char *buf;
// finds root= rootfstype= rootflags= options // finds root= and rootfstype= options
buf = strdup("liminix console=ttyS0,115200 panic=10 oops=panic init=/bin/init loglevel=8 root=/dev/ubi0_4 rootfstype=ubifs rootflags=subvol=1 fw_devlink=off mtdparts=phram0:18M(rootfs) phram.phram=phram0,0x40400000,18874368,65536 root=/dev/mtdblock0 foo"); buf = strdup("liminix console=ttyS0,115200 panic=10 oops=panic init=/bin/init loglevel=8 root=/dev/ubi0_4 rootfstype=ubifs fw_devlink=off mtdparts=phram0:18M(rootfs) phram.phram=phram0,0x40400000,18874368,65536 root=/dev/mtdblock0 foo");
memset(&opts, '\0', sizeof opts); parseopts(buf, &opts); parseopts(buf, &root, &rootfstype);
expect_equal(opts.device, "/dev/mtdblock0"); expect_equal(root, "/dev/mtdblock0");
expect_equal(opts.fstype, "ubifs"); expect_equal(rootfstype, "ubifs");
expect_equal(opts.mount_opts, "subvol=1");
// in case of duplicates, chooses the latter // in case of duplicates, chooses the latter
// also: works if the option is end of string // also: works if the option is end of string
buf = strdup("liminix console=ttyS0,115200 panic=10 oops=panic init=/bin/init loglevel=8 root=/dev/ubi0_4 rootfstype=ubifs fw_devlink=off mtdparts=phram0:18M(rootfs) phram.phram=phram0,0x40400000,18874368,65536 root=/dev/mtdblock0"); buf = strdup("liminix console=ttyS0,115200 panic=10 oops=panic init=/bin/init loglevel=8 root=/dev/ubi0_4 rootfstype=ubifs fw_devlink=off mtdparts=phram0:18M(rootfs) phram.phram=phram0,0x40400000,18874368,65536 root=/dev/mtdblock0");
memset(&opts, '\0', sizeof opts); parseopts(buf, &opts); parseopts(buf, &root, &rootfstype);
expect_equal(opts.device, "/dev/mtdblock0"); expect_equal(root, "/dev/mtdblock0");
expect_equal(opts.fstype, "ubifs"); expect_equal(rootfstype, "ubifs");
// options may appear in either order // options may appear in either order
buf = strdup("liminix fw_devlink=off root=/dev/hda1 rootfstype=ubifs foo"); buf = strdup("liminix fw_devlink=off root=/dev/hda1 rootfstype=ubifs foo");
memset(&opts, '\0', sizeof opts); parseopts(buf, &opts); parseopts(buf, &root, &rootfstype);
expect_equal(opts.device, "/dev/hda1"); expect_equal(root, "/dev/hda1");
expect_equal(opts.fstype, "ubifs"); expect_equal(rootfstype, "ubifs");
// works when rootflags is the last option
buf = strdup("liminix fw_devlink=off root=/dev/hda1 rootfstype=ubifs rootflags=subvol=@");
memset(&opts, '\0', sizeof opts); parseopts(buf, &opts);
expect_equal(opts.device, "/dev/hda1");
expect_equal(opts.fstype, "ubifs");
expect_equal(opts.mount_opts, "subvol=@");
buf = strdup("liminix rootfstype=ubifs fw_devlink=off root=/dev/hda1 foo"); buf = strdup("liminix rootfstype=ubifs fw_devlink=off root=/dev/hda1 foo");
memset(&opts, '\0', sizeof opts); parseopts(buf, &opts); parseopts(buf, &root, &rootfstype);
expect_equal(opts.fstype, "ubifs"); expect_equal(rootfstype, "ubifs");
expect_equal(opts.device, "/dev/hda1"); expect_equal(root, "/dev/hda1");
// provides NULL for missing options // provides NULL for missing options
buf = strdup("liminix rufustype=ubifs fw_devlink=off foot=/dev/hda1"); buf = strdup("liminix rufustype=ubifs fw_devlink=off foot=/dev/hda1");
memset(&opts, '\0', sizeof opts); parseopts(buf, &opts); parseopts(buf, &root, &rootfstype);
if(rootfstype) die("expected null rootfstype, got \"%s\"", rootfstype);
if(opts.fstype) die("expected null rootfstype, got \"%s\"", opts.fstype); if(root) die("expected null root, got \"%s\"", root);
if(opts.device) die("expected null root, got \"%s\"", opts.device);
if(opts.mount_opts) die("expected null mount_opts, got \"%s\"", opts.mount_opts);
// provides empty strings for empty options // provides empty strings for empty options
buf = strdup("liminix rootfstype= fw_devlink=off root= /dev/hda1"); buf = strdup("liminix rootfstype= fw_devlink=off root= /dev/hda1");
memset(&opts, '\0', sizeof opts); parseopts(buf, &opts); parseopts(buf, &root, &rootfstype);
if(strlen(rootfstype)) die("expected empty rootfstype, got \"%s\"", rootfstype);
if(strlen(opts.fstype)) die("expected empty rootfstype, got \"%s\"", opts.fstype); if(strlen(root)) die("expected null root, got \"%s\"", root);
if(strlen(opts.device)) die("expected null root, got \"%s\"", opts.device);
expect_equal("01", pr_u32(1)); expect_equal("01", pr_u32(1));
expect_equal("ab", pr_u32(0xab)); expect_equal("ab", pr_u32(0xab));

View File

@ -10,7 +10,7 @@
#include <asm/setup.h> /* for COMMAND_LINE_SIZE */ #include <asm/setup.h> /* for COMMAND_LINE_SIZE */
#include "opts.h" void parseopts(char * cmdline, char **root, char **rootfstype);
#define ERR(x) write(2, x, strlen(x)) #define ERR(x) write(2, x, strlen(x))
#define AVER(c) do { if(c < 0) { ERR("failed: " #c ": error=0x" ); pr_u32(errno); ERR("\n"); } } while(0) #define AVER(c) do { if(c < 0) { ERR("failed: " #c ": error=0x" ); pr_u32(errno); ERR("\n"); } } while(0)
@ -49,11 +49,8 @@ char buf[COMMAND_LINE_SIZE];
int main(int argc, char *argv[], char *envp[]) int main(int argc, char *argv[], char *envp[])
{ {
struct root_opts opts = { char *rootdevice = 0;
.device = NULL, char *rootfstype = 0;
.fstype = NULL,
.mount_opts = NULL
};
write(1, banner, strlen(banner)); write(1, banner, strlen(banner));
@ -76,20 +73,16 @@ int main(int argc, char *argv[], char *envp[])
ERR("failed: open(\"/proc/cmdline\")\n"); ERR("failed: open(\"/proc/cmdline\")\n");
die(); die();
} }
parseopts(buf, &opts); parseopts(buf, &rootdevice, &rootfstype);
if(opts.device) { if(rootdevice) {
if(!opts.fstype) opts.fstype = "jffs2"; /* backward compatibility */ if(!rootfstype) rootfstype = "jffs2"; /* backward compatibility */
write(1, "rootdevice ", 11); write(1, "rootdevice ", 11);
write(1, opts.device, strlen(opts.device)); write(1, rootdevice, strlen(rootdevice));
write(1, " (", 2); write(1, " (", 2);
write(1, opts.fstype, strlen(opts.fstype)); write(1, rootfstype, strlen(rootfstype));
if(opts.mount_opts) {
write(1, ", opts=", 7);
write(1, opts.mount_opts, strlen(opts.mount_opts));
}
write(1, ")\n", 2); write(1, ")\n", 2);
AVER(mount(opts.device, "/target/persist", opts.fstype, 0, opts.mount_opts)); AVER(mount(rootdevice, "/target/persist", rootfstype, 0, NULL));
AVER(mount("/target/persist/nix", "/target/nix", AVER(mount("/target/persist/nix", "/target/nix",
"bind", MS_BIND, NULL)); "bind", MS_BIND, NULL));

View File

@ -1,27 +0,0 @@
{
stdenv
, fetchFromGitLab
, makeWrapper
, btrfs-progs
, lib
}:
let search_path = lib.makeBinPath [btrfs-progs];
in stdenv.mkDerivation {
pname = "schnapps";
version = "2.13.0";
src =fetchFromGitLab {
domain = "gitlab.nic.cz";
owner = "turris";
repo = "schnapps";
rev = "53ac92c765d670be4b98dba2c948859a9ac7607f";
hash = "sha256-yVgXK+V2wrcOPLB6X6qm3hyBcWcyzNhfJjFF7YRk5Lc=";
};
nativeBuildInputs = [ makeWrapper ];
buildPhase = ":";
installPhase = ''
install -D schnapps.sh $out/bin/schnapps
wrapProgram $out/bin/schnapps --prefix PATH : "${search_path}"
'';
}

View File

@ -81,22 +81,8 @@ in attrset:
$STRIP --remove-section=.note --remove-section=.comment --strip-all makedevs -o $out/bin/activate $STRIP --remove-section=.note --remove-section=.comment --strip-all makedevs -o $out/bin/activate
ln -s ${s6-init-bin}/bin/init $out/bin/init ln -s ${s6-init-bin}/bin/init $out/bin/init
cat > $out/bin/install <<EOF cat > $out/bin/install <<EOF
#!/bin/sh -e #!/bin/sh
prefix=\''${1-/} cp -v -fP $out/bin/* $out/etc/* \''${1-/}/persist
src=\''${prefix}$out
dest=\$prefix
${# if we are running on a normal mounted system then
# the actual device root is mounted on /persist
# and /nix is bind mounted from /persist/nix
# (see the code in preinit). So we need to check for this
# case otherwise we will install into a ramfs/rootfs
""
}
if test -d $dest/persist; then dest=$dest/persist; fi
cp -v -fP \$src/bin/* \$src/etc/* \$dest
${if attrset ? boot then ''
(cd \$dest && rm ./boot && ln -sf ${lib.strings.removePrefix "/" attrset.boot.target} ./boot)
'' else ""}
EOF EOF
chmod +x $out/bin/install chmod +x $out/bin/install
''; '';