THOUGHTS.txt (139162B)
1 Thu Sep 22 00:12:42 BST 2022 2 3 Making quite reasonable progress, though only running under emulation. 4 Since almost everything so far has been a recap of nixwrt, that's to 5 be expected. 6 7 The example config starts some services at boot, or at least attempts 8 to. Next we shoud 9 10 - add some network config to run-qemu 11 - implement udhcp and odhcp properly to write outputs 12 and create resolv.conf and all that 13 - write some kind of test so we can refactor the crap 14 - not let the tests write random junk everywhere 15 16 Thu Sep 22 12:46:36 BST 2022 17 18 We can store outputs in the s6 scan directory, it seems: 19 20 > There is, however, a guarantee that s6-supervise will never touch subdirectories named data or env. So if you need to store user information in the service directory with the guarantee that it will never be mistaken for a configuration file, no matter the version of s6, you should store that information in the data or env subdirectories of the service directory. 21 22 https://skarnet.org/software/s6/servicedir.html 23 24 > process 'store/pj0b27l5728cypa5mmagz0q8ibzpik0h-execline-mips-unknown-linux-musl-2.9.0.1-bin/bin/execlineb' started with executable stack 25 26 https://skarnet.org/lists/skaware/1550.html 27 28 29 Thu Sep 22 16:14:49 BST 2022 30 31 what network peers do we want to model for testing? 32 33 - wan: pppoe 34 - wan: ip over ethernet, w/ dhcp service provided 35 - wan: l2tp over (ip over ethernet, w/ dhcp service provided) 36 - lan: something with a dhcp client 37 38 https://accel-ppp.readthedocs.io/en/latest/ could use this for testing 39 pppoe and l2tp? 40 41 42 Thu Sep 22 22:57:47 BST 2022 43 44 To build a nixos vm with accel-ppp installed (not yet configured) 45 46 nix-build '<nixpkgs/nixos>' -A vm -I nixos-config=./tests/ppp-server-configuration.nix -o ppp-server 47 QEMU_OPTS="-display none -serial mon:stdio -nographic" ./ppp-server/bin/run-nixos-vm 48 49 To test it's configured I thought I'd run it against an OpenWrt qemu 50 install, so, fun with qemu networking ensues. This config in ../openwrt-qemu 51 is using two multicast socket networks - 52 53 nix-shell -p qemu --run "./run.sh ./openwrt-22.03.0-x86-64-generic-kernel.bin openwrt-22.03.0-x86-64-generic-ext4-rootfs.img " 54 55 so hopefully we can spin up other VMs connected either to its lan or 56 its wan: *however* we do first need to configure its wan to use pppoe 57 58 uci set network.wan=interface 59 uci set network.wan.device='eth1' 60 uci set network.wan.proto='pppoe' 61 uci set network.wan.username='db123@a.1' 62 uci set network.wan.password='NotReallyTheSecret' 63 64 (it's ext4 so this will probably stick) 65 66 67 Fri Sep 23 10:27:22 BST 2022 68 69 * mcast=230.0.0.1:1234 : access (interconnect between router and isp) 70 * mcast=230.0.0.1:1235 : lan 71 * mcast=230.0.0.1:1236 : world (the internet) 72 73 74 Sun Sep 25 20:56:28 BST 2022 75 76 TODO - bugs, missing bits, other infelicities as they occur to me: 77 78 DONE 1) shutdown doesn't work as its using the busybox one not s6. 79 80 2) perhaps we shouldn't have process-based services like dhcp, ppp 81 implement "address provider interface" - instead have a separate 82 service for interface address that depends on the service and uses its 83 output 84 85 * ppp is not like dhcp because dhcp finds addresses for an existing 86 interface but ppp makes a new one 87 88 3) when I killed ppp it restarted, but I don't think it reran 89 defaultroute which is supposed to depend on it. (Might be important 90 e.g. if we'd been assigned a different IP address). Investigate 91 semantics of s6-rc service dependencies 92 93 DONE 4) make the pppoe test run unattended 94 95 5) write a test for udhcp 96 97 6) squashfs size is ~ 14MB for a configuration with not much in it, 98 look for obvious wastes of space 99 100 7) some of the pppoe config should be moved into a ppp service 101 102 8) some of configuration.nix (e.g. defining routes) should be moved into 103 tools 104 105 DONE 9) split tools up instead of having it all one file 106 107 10) is it OK to depend on squashfs pseudofiles if we might want to 108 switch to ubifs? will there always be a squashfs underneath? might 109 we want to change the pseudofiles in an overlay? 110 111 11) haven't done (overlayfs) overlays at all 112 113 12) overlay.nix needs splitting up 114 115 13) upgrade ppp to something with an ipv6-up-script option 116 117 14) add ipv6 support generally 118 119 15) "ip address add" seems to magically recognise v4 vs v6 but 120 is that specified or fluke? 121 122 16) tighten up the module specs. (DONE) services.foo should be a s6-rc 123 service, (DONE) kernel config should be checked in some way 124 125 DONE 17) rename nixwrt references in kernel builder 126 127 18) maybe stop suffixing all the service names with .service 128 129 19) syslogd - use busybox or s6? 130 131 chat -s -S ogin:--ogin: root / "ip address show dev ppp0 | grep ppp0" 192.168.100.1 "/nix/store/*-s6-linux-init-*/bin/s6-linux-init-hpr -p" 132 133 134 Working towards a general goal of having a derivation we can 135 usefully run `nix path-info` on - or some other tool that will 136 tell us what's making the images big. The squashfs doesn't 137 have this information. 138 139 Towards that end (really? can't remember how ...) what would be a 140 way for packages to declare "I want to add files to /etc"? Is that 141 even a good idea? 142 143 Thinking we should turn s6-init-files back into a real derivation. 144 145 Tue Sep 27 00:31:45 BST 2022 146 147 > Thinking we should turn s6-init-files back into a real derivation. 148 149 This turns out to be Not That Simple, because it contains weird shit 150 (sticky bits and fifos). 151 152 Tue Sep 27 09:50:44 BST 2022 153 154 * allow modules to register activation scripts that are run on the 155 root filesystem once all packages are installed 156 157 - do they run on build or on host? if we're upgrading in place 158 how do we ship filesystem changes to the host? 159 160 or: 161 162 * allow modules to declare environment.*, use pseudofile on build and 163 create real files on host. will need to keep the implementation on 164 host faily simple because restricted environment 165 166 Tue Sep 27 16:14:18 BST 2022 167 168 TODO list is getting both longer and shorter, though longer on 169 average. 170 171 2) perhaps we shouldn't use process-based services like [ou]dhcp as 172 queryable endpoint for interface addresses (e.g. when adding routes). 173 Instead have a separate service for interface address that depends on 174 the *dhcp and uses its output 175 176 3) when I killed ppp it restarted, but I don't think it reran 177 defaultroute which is supposed to depend on it. (Might be important 178 e.g. if we'd been assigned a different IP address). Investigate 179 semantics of s6-rc service dependencies 180 181 4) figure out a nice way to fit ppp into this model as it actually 182 creates the interface instead of using an existing unconfigured one 183 184 5) write a test for udhcp 185 186 7) some of the pppoe config should be moved into a ppp service 187 188 11) haven't done (overlayfs) overlays at all 189 190 13) upgrade ppp to something with an ipv6-up-script option, move ppp and pppoe derivations into their own files 191 192 14) add ipv6 support generally 193 194 15) "ip address add" seems to magically recognise v4 vs v6 but 195 is that specified or fluke? 196 197 19) ship logs somehow to log collection system 198 199 21) dhcp, dns, hostap service for lan 200 201 22) support real hardware 202 203 Tue Sep 27 22:00:36 BST 2022 204 205 Found the cause of huge image size: rp-pppoe ships with scripts that 206 reference build-time packages, so we have x86-64 glibc in there 207 208 We don't need syslog just to accommodate ppp, there's an underdocumented 209 option for it to log to a file descriptor 210 211 Wed Sep 28 16:04:02 BST 2022 212 213 Based on https://unix.stackexchange.com/a/431953 if we can forge 214 ethernet packets we might be able to write tests for e.g. "is the vm 215 running a dhcp server" 216 217 Wed Sep 28 21:29:05 BST 2022 218 219 We can use Python "scapy" to generate dhcp request packets, and Python 220 'socket' model to send them encapsulated in UDP. Win 221 222 It's extremely janky python 223 224 Thu Sep 29 15:24:37 BST 2022 225 226 Two points to ponder 227 228 1) where service config depends on outputs of other services, we 229 do that rather ugly "$(cat ${output ....})" construct. Can we improve on 230 that? Maybe we could have some kind of tooling to read them as environment 231 variables ... 232 233 2) we have given no consideration yet to secrets. we want the secrets to 234 be not in the store; we want some way of refreshing them when they change 235 236 Sat Oct 1 14:24:21 BST 2022 237 238 The MAC80211_HWSIM kernel config creates virtual wlan[01] devices 239 which hostapd will work with, and a hwsim0 which we can use to monitor 240 (though not inject) trafic. Could we use this for wifi tests? How do 241 we make the guest hwsim0 visible to the host? 242 243 244 Sat Oct 1 18:41:31 BST 2022 245 246 virtual serial ports: I struggled with qemu for ages to get this to work. 247 You also need the unhelpfully named CONFIG_VIRTIO_CONSOLE option in 248 kconfig 249 250 QEMU_OPTIONS="-nodefaults -chardev socket,path=/tmp/wlan,server=on,wait=off,id=wlan -device virtio-serial-pci -device virtserialport,name=wlan,chardev=wlan" 251 252 Sun Oct 2 09:34:48 BST 2022 253 254 We could implement the secrets store as a service, then the secrets 255 are outputs. 256 257 Things we can do in qemu 258 259 1) make interface address service that depends on dhcp, instead of 260 being set by it directly 261 2) check out restart behaviour of dependent services when depended-on 262 service dies 263 3) pppd _creates_ an interface, work out how to fit it into this model 264 5) add bridge support for lan 265 8) upgrade ppp to something with an ipv6-up-script option, move ppp and pppoe derivations into their own files 266 9) get ipv6 address from pppoe 267 10) get ipv6 delegation from pppoe and add prefix to lan 268 11) support dhcp6 in dnsmasq, and advertise prefix on lan 269 12) firewalling and nat 270 - default deny or zero trust? 271 14) write secrets holder as a service with outputs 272 20) should we check that references to outputs actually correspond with 273 those provided by a service 274 275 Things we probably do on hardware 276 277 6) writable filesystem (ubifs?) 278 7) overlay with squashfs/ubifs - useful? think about workflows for 279 how this thing is installed 280 16) gl-ar750 281 17) mediatek device - gl-mt300 or whatever I have lying around 282 18) some kind of arm (banana pi router?) 283 19) should we give routeros a hardware ethernet and maybe an l2tp upstream, 284 then we could dogfood the hardware devices. we could run an l2tp service 285 at mythic-beasts, got a /48 there 286 287 288 289 https://skarnet.org/software/s6/s6-fghack.html looks like a handy thing 290 we hope we'll never have to use 291 292 Sun Oct 2 22:22:17 BST 2022 293 294 > make interface address service that depends on dhcp, instead of being set by it directly 295 296 We can do this for dhcp, but we can't do it for ppp. Running the ppp service 297 creates a ppp[012n] interface and assigns it an ipv4 address and there's not 298 a whole lot we can easily do to unbundle that. 299 300 So 301 302 - the ppp service needs to behave as if it were a "link" service 303 - either it *also* needs to behave as an address service, or we could 304 have an address service that subscribes to it and does nothing other than 305 translate output formats 306 307 Note regarding that second bullet: at the moment the static address 308 service has no outputs anyway! 309 310 311 Tue Oct 4 22:43:02 BST 2022 312 313 While trying to make the TFTP workflow not awful I seem to have written 314 a TFTP server. 315 316 317 Thu Oct 6 19:26:40 BST 2022 318 319 We have a booting kernel on gl-ar750, but we aren't at a point that it can 320 find a root filesystem 321 322 I'd *like* to be able to use the same delivery mechanism (kernel uimage 323 concatenated monolithic 324 325 326 Sat Oct 8 11:12:09 BST 2022 327 328 We have it booting on hardware, mounting root fs, running getty :-) 329 330 For NixWRT TFTP boots we used a single image with both kernel and squashfs, and 331 relied on CONFIG_MTD_SPLIT_FIRMWARE to identify where the boundary was and create 332 /dev/mdtn devices at the right offsets so that the kernel could find the 333 squashfs 334 335 For Liminix we're not going to do that. 336 337 * CONFIG_MTD_SPLIT_FIRMWARE is only available in OpenWrt patches 338 * it's an uncomfortable level of automagic just to save us doing two TFTPs 339 instea of one 340 * the generated image is anyway not the one we'd write to flash (has unneeded 341 PHRAM support) 342 * it means we need to memmap out enough ram for the whole image inc kernel when really 343 all we need to reserve is the rootfs bit 344 345 346 Sat Oct 8 11:23:08 BST 2022 347 348 "halt" and "reboot" don't work on gl-ar750 349 350 Sat Oct 8 13:10:00 BST 2022 351 352 Where do we go with this ar750? 353 354 - wired networking 355 - wifi 356 357 358 Sun Oct 9 09:57:35 BST 2022 359 360 We want to be able to package kernel modules as regular derivations, so that 361 they get added to the filesystem 362 363 This means they need access to kernel.modulesupport 364 365 This means kernel.modulesupport needs to be in pkgs too? 366 367 This is fine, probably, but we'd like to avoid closing over vmlinux because 368 there's no need for it to be in the filesystem 369 370 Mon Oct 10 22:57:23 BST 2022 371 372 The problem is that kernel kconfig options are manipulated in the 373 liminix modules, which means that data must be (transitively) available 374 to modules, so they can't be regular packages as they're tied so tightly 375 to the exact config. Unless we define a second overlay that references 376 the configuration object, but my head hurts when I start to think about that 377 so maybe not. 378 379 Tue Oct 11 00:00:13 BST 2022 380 381 Building ag71xx (ethernet driver) as a module doesn't work because 382 it references a symbol ath79_pll_base in the kernel that hasn't been 383 marked with EXPORT_SYMBOL. 384 385 We could forge an object file that "declares" it with a gross and disgusting hack like this 386 387 $ echo > empty # not actually "empty", objcopy complains about that 388 $ grep ath79_pll_base /nix/store/jcc114cd13xa8aa4mil35rlnmxnlmv09-vmlinux-mips-unknown-linux-musl-modulesupport/System.map 389 ffffffff807b2094 B ath79_pll_base 390 $ mips-unknown-linux-musl-objcopy -I binary -O elf32-big --add-section .bss=empty --add-symbol ath79_pll_base=.bss:0x807b2094 empty f.o 391 392 I don't claim this is a good idea, just an idea. Thought was that we would not 393 have to declare its type this way. Also it might not work with kaslr 394 https://stackoverflow.com/a/68903503 395 396 397 Backstory: why are we trying to build this as a module? because the 398 openwrt fork of it seems to be a bit more advanced than the mainline, 399 and I *suspect* that the mainline version doesn't work with our 400 openwrt-based device tree which ahs the mdio as a nested node inside 401 the ag71xx node - in mainline the driver seems to have all the mdio 402 stuff inline. So, could we build the openwrt driver without patching 403 the crap out of our kernel 404 405 Sun Oct 16 15:25:33 BST 2022 406 407 Executive decision: let's use the openwrt kernel (at least for 408 gl-ar750). Mainline kernel doesn’t have devicetree support for this 409 device or the SoC it’s based on, and the OpenWrt dts for it doesn’t 410 have the same "compatible"s, which makes me think that an indefinite 411 amount of patching will be necessary to make dts/modules for one of 412 them work with a kernel for the other 413 414 As a result: now we have eth0 appearing, but not eth1? Guessing we 415 need to add some kconfig for the switch 416 417 Mon Oct 17 21:23:37 BST 2022 418 419 we are spending ridiculous amounts of cpu/io time copying kernel source 420 trees from place to place, because we have kernel tree preparation 421 and actual building as two separate derivations. 422 423 I think the answer is to have a generic kernel build derivation 424 in the overlay, and then have the device overlays override it with 425 an additional phase to do openwrt patching or whatever else they 426 need to do. 427 428 Tue Oct 18 23:02:43 BST 2022 429 430 * previous TODO list is Aug 02, need to review 431 * dts is hardcoded to gl-ar750, that needs cleaning up 432 * figure out persistent addresses for ethernet 433 * fix halt/reboot 434 * "link" services have a "device" attribute, would much rather 435 have everything referenced using outputs than having two 436 different mechanisms for reading similar things 437 * Kconfig.local do we still need it? 438 * check all config instead of differentiating config/checkedConfig 439 440 Sun Feb 5 18:14:02 GMT 2023 441 442 We have resumed. 443 commit eb4efab6a215bf03cf5aab10d4ac909e83e9c148 444 Author: Daniel Barlow <dan@telent.net> 445 Date: Sat Jan 28 23:18:28 2023 +0000 446 447 448 * find out what works 449 * add that stuff to hydra 450 * fix the rest 451 * add that stuff to hydra 452 * convert to flake 453 * check if routeros can be run interactively 454 * some per-device docs in a form that can be transcluded for website 455 456 457 ci builds 458 459 * each of the tests has hardcoded device/config/etc 460 * build an "empty" configuration for each target device 461 * build an unstable configuration for qemu 462 463 464 Wed Feb 8 16:52:22 GMT 2023 465 466 We have hydra builds for all the previously-working devices, though we 467 don't yet know if any of those builds actually boots or does anything 468 useful. 469 470 [DONE] Would be nice to clean up the run-qemu and connect-qemu scripts 471 and put them in the buildEnv 472 473 Some thought needed about how to hook up the gl-ar750 to the internets, 474 ideally in a way that mirrors typical real uses. AAISP have an L2TP 475 service, but I would prefer to use pppoe on the device, so how to 476 translate one to t'other on an intermediary/gateway machine? 477 https://www.rfc-archive.org/getrfc.php?rfc=3817#gsc.tab=0 exists 478 as an RFC but I can't find anything that actually implements it 479 480 Actual Documentation (e.g. user and developer manuals) should live in 481 the liminix repo so it corresponds with the code, and can be rsynced 482 from there to the web site, maybe with a deploy hook or something. 483 Haven't decided what a good doc format is yet 484 485 If we create a flake for Hydra to run on, that _more or less_ means we 486 don't have any manual hydra jobset configuration to document. 487 488 There are still some tests that need adding to CI 489 490 [DONE] Should the per-device config be a module not an overlay? Given that 491 half of what's in it is kernel config (a module could set this) 492 and the rest is source tarball download specs (needs nixpkgs, 493 a module has this and could set it too) I wonder why it isn't already 494 495 [ALREADY DOES] Can we make Hydra report output sizes so we can plot closure size 496 trends and see if it all goes awful? 497 498 Thu Feb 9 08:14:39 GMT 2023 499 500 For better developer experience, I am thinking that either (1) 501 swap tasks 2 and 3 (writable filesystem before module system) 502 or (2) add NBD support so I can iterate on a real device without 503 full rebuilds every time 504 505 506 Fri Feb 10 06:18:25 PM GMT 2023 507 508 did the overlay->module thing 509 510 [DONE] Need to fix all the configuration around PHRAM, I can't see how it 511 would ever work 512 513 Sat Feb 11 14:37:45 GMT 2023 514 515 Consolidated TODO 516 517 * figure out persistent addresses for ethernet (?) 518 [SEEMS DONE] * fix halt/reboot 519 [DONE, NO] * Kconfig.local do we still need it? 520 [DONE] * check all config instead of differentiating config/checkedConfig 521 522 Things we can do in qemu 523 524 * "link" services have a "device" attribute, would much rather 525 have everything referenced using outputs than having two 526 different mechanisms for reading similar things 527 1) make interface address service that depends on dhcp, instead of 528 being set by it directly 529 2) check out restart behaviour of dependent services when depended-on 530 service dies 531 3) pppd _creates_ an interface, work out how to fit it into this model 532 5) add bridge support for lan 533 8) upgrade ppp to something with an ipv6-up-script option, move ppp and pppoe derivations into their own files 534 9) get ipv6 address from pppoe 535 10) get ipv6 delegation from pppoe and add prefix to lan 536 11) support dhcp6 in dnsmasq, and advertise prefix on lan 537 12) firewalling and nat 538 - default deny or zero trust? 539 14) write secrets holder as a service with outputs 540 20) should we check that references to outputs actually correspond with 541 those provided by a service 542 * Actual Documentation (e.g. user and developer manuals) 543 * make a flake 544 * There are still some tests that need adding to CI 545 546 Things we probably do on hardware 547 548 [DONE] * dts is hardcoded to gl-ar750, that needs cleaning up 549 6) writable filesystem (ubifs?) 550 7) overlay with squashfs/ubifs - useful? think about workflows for 551 how this thing is installed 552 16) gl-ar750 553 [DONE] * decide how to hook up the gl-ar750 to the internets 554 17) mediatek device - gl-mt300 or whatever I have lying around 555 18) some kind of arm (banana pi router?) 556 [DONE DIFERENTLY] 19) should we give routeros a hardware ethernet and maybe an l2tp upstream, 557 then we could dogfood the hardware devices. we could run an l2tp service 558 at mythic-beasts, got a /48 there 559 560 561 Sat Feb 11 15:57:31 GMT 2023 562 563 The reason we would like to run PPPoE instead of L2TP on the "rotuer" device is 564 565 - closer to real world scenario 566 - means no need to run dhcp client on the wan interface before we 567 even get to start the l2tpd 568 569 570 Sun Feb 12 14:57:28 GMT 2023 571 572 https://github.com/katalix/go-l2tp#kpppoed 573 574 575 Mon Feb 13 04:44:09 PM GMT 2023 576 577 if the gl-ar750 is connected to an ethernet card that linux is ignoring, 578 we're going to have to set up _some_ qemu thing just to run tftp from. 579 580 Tue Feb 14 17:59:34 GMT 2023 581 582 We should do a derivation that creates an ISO image and a qemu shell 583 script based on a configuration.nix, and put it in buildEnv. We'll 584 call it "borderNetVm" : 585 586 > A broadband remote access server (BRAS, B-RAS or BBRAS) routes 587 traffic to and from broadband remote access devices such as digital 588 subscriber line access multiplexers (DSLAM) on an Internet service 589 provider's (ISP) network.[1][2] BRAS can also be referred to as a 590 broadband network gateway or border network gateway (BNG).[3] 591 592 (for consistency we should rename the "access" qemu socket network to 593 match whatever we call this) 594 595 rm border.qcow2 ; nix-shell --argstr liminix `pwd` --argstr nixpkgs `pwd`/../nixpkgs --argstr unstable `pwd`/../unstable-nixpkgs/ ci.nix -A buildEnv --run "run-border-vm" 596 597 Wed Feb 15 22:56:59 GMT 2023 598 599 configuration for border vm needs to come from somewhere so it's good 600 for more people than just me 601 602 - pci device for setting up the ethernet 603 - lns address 604 - uid so it can do 9p shares? do we need to map things here? 605 606 also need to document the host-side bits so that people can set up 607 their spare ethernet as vfio 608 609 next step for hacking is to figure out what I was doing with pppoe 610 611 Wed Feb 15 22:59:56 GMT 2023 612 613 docs ... 614 615 * introduction 616 617 * user guide 618 ** how to build it 619 ** how to flash it on your device 620 ** what to put in configuration.nix 621 ** modules 622 623 * developer guide 624 ** building/running with qemu 625 *** emulated upstream 626 ** building/running on hardware 627 *** run in place with TFTP 628 *** emulated upstream 629 ** CI 630 ** Roadmap 631 ** Contributing 632 633 634 635 nix-shell -p sphinx --run "make -C doc html" 636 637 https://francis.begyn.be/blog/nixos-home-router contains information about avahi reflector 638 639 640 Fri Feb 17 00:09:34 GMT 2023 641 642 29 11.282085831 81.187.76.242 → 8.8.8.8 ICMP 106 Echo (ping) request id=0x0187, seq=2/512, 4 643 30 11.286314642 90.155.53.19 → 81.187.76.242 ICMP 78 Destination unreachable (Communication admin) 644 645 We're getting packets over the pppoe-l2tp relay thing. Just have to 646 work out now why we're not routing 647 648 Fri Feb 17 16:54:41 GMT 2023 649 650 Haha. We weren't routing because we'd used the wrong CHAP password 651 652 653 654 Fri Feb 17 16:58:27 GMT 2023 655 656 This TODO is for nlnet task 1 and for bits of subsequent tasks that 657 are annoying enough that I might poke at them anyway: 658 659 660 1) gl-ar750, why do we get "ag71xx 19000000.eth: invalid MAC address, using random address" 661 2) gl-ar750, wifi 662 3) document services so I can remember how they work. Refer back to Oct 18 for notes that no longer make sense 663 4) check out restart behaviour of dependent services when depended-on service dies 664 5) pppd _creates_ an interface, work out how to fit it into this model 665 6) add bridge support for lan 666 7) upgrade ppp to something with an ipv6-up-script option, move ppp and pppoe derivations into their own files 667 8) get ipv6 address from pppoe 668 9) get ipv6 delegation from pppoe and add prefix to lan 669 10) support dhcp6 in dnsmasq, and advertise prefix on lan 670 11) firewalling and nat - default deny or zero trust? 671 13) should we check that references to outputs actually correspond with 672 14) make a flake? 673 15) see if there are other tests that need adding to CI 674 15a) is bordervm derivation tested? 675 18) gl-mt300a 676 19) gl-mt300n-v2 677 20) publish the manual using CI 678 679 12) write secrets holder as a service with outputs 680 16) writable filesystem (ubifs?) 681 17) overlay with squashfs/ubifs - useful? think about workflows for how this thing is installed 682 683 684 I could plug tninkpad into the gl-ar750 LAN port to dogfood the wired 685 networking 686 687 Sat Feb 18 14:26:45 GMT 2023 688 689 Apparently we're not currently doing anything special with busybox, 690 just using the default nixos build with the default applets. 691 692 We'd like to be able to say in modules which applets they need, 693 so that we build all necessary applets but don't waste any space. 694 But we don't want to build a busybox for each module because that 695 would be a big waste of space. 696 697 One option: 698 - add busybox configuration to `config` so that modules can maul it 699 - add a busybox module that builds it with union of all config and 700 adds link in /bin 701 - make everything else look in /bin instead of referencing pkgs.busybox 702 703 It would be good if services could assert somehow that their required 704 config is present 705 706 Sat Feb 18 23:45:13 GMT 2023 707 708 # lsmod 709 710 cd /lib/modules/mac80211 711 insmod ./compat/compat.ko 712 insmod ./net/wireless/cfg80211.ko 713 insmod ./net/mac80211/mac80211.ko 714 insmod ./drivers/net/wireless/ath/ath.ko 715 insmod ./drivers/net/wireless/ath/ath9k/ath9k_hw.ko 716 insmod ./drivers/net/wireless/ath/ath9k/ath9k_common.ko 717 insmod ./drivers/net/wireless/ath/ath9k/ath9k.ko 718 insmod ./drivers/net/wireless/ath/ath10k/ath10k_core.ko 719 insmod ./drivers/net/wireless/ath/ath10k/ath10k_pci.ko 720 721 [21.344930] ath9k 18100000.wmac: failed to load calibration data from mtd device 722 [21.352728] ath: phy0: parsing configuration from OF node 723 [21.362576] ath: phy0: serialize_regmode is 0 724 [21.367092] ath: phy0: UNDEFINED -> AWAKE 725 [21.372051] ath: phy0: Trying EEPROM access at Address 0x03ff 726 [21.377999] ath: phy0: Trying EEPROM access at Address 0x0fff 727 [21.383940] ath: phy0: Trying EEPROM access at Address 0x01ff 728 [21.389879] ath: phy0: Trying OTP access at Address 0x03ff 729 [21.400396] Data bus error, epc == 8027964c, ra == 83125880 730 [21.406156] Oops[#1]: 731 732 733 Sun Feb 19 18:15:27 GMT 2023 734 735 We have ath9k listening for packets. To make this ready to use: 736 737 - need to load the modules 738 - enable bridging lan with wlan 739 - packet forwarding 740 - firewall 741 742 743 Mon Feb 20 20:41:17 GMT 2023 744 745 need to fix all the other broken ci jobs :-( 746 747 The wlan test is failing because we moved mac80211 to a module and 748 there's nothing running to insmod it 749 750 Wed Feb 22 18:17:17 GMT 2023 751 752 bridge is e2b3738d0f8c3f2fd76ebcef65612de502a7b121 but it's the wrong 753 way around: the master interface needs to be up whether or not all 754 of its children are, so members depend on master not vice versa 755 756 Next steps: 757 - re-implement bridge, enable bridging lan with wlan 758 - packet forwarding 759 - firewall 760 - ath10k 761 - ipv6 762 763 Fri Feb 24 23:37:56 GMT 2023 764 765 bridging wlan was made complex because can't add a device to a bridge 766 until it's operational, and wlan0 is not operational until hostapd 767 has churned awhile. Therefore, "waitup" listens for netlink messages 768 and notifies s6 readiness stuff 769 770 we have a firewall nft script but we're not running it on boot 771 772 we have forwarding but no dns, maybe because we haven't told 773 dnsmasq about any upstream servers 774 775 Sun Feb 26 21:08:47 GMT 2023 776 777 to add firmware we need to put files in /lib/firmware, which means 778 a module 779 780 i guess we should do that in the device module 781 782 we can create the firmware files as packages 783 784 785 for the cal data we would like to get it from the device MTD "art" 786 partition at 787 boot time. 788 789 f 790 ====from openwrt 791 792 793 794 case "$FIRMWARE" in 795 "ath10k/cal-pci-0000:00:00.0.bin") 796 case $board in 797 allnet,all-wap02860ac|\ 798 araknis,an-500-ap-i-ac|\ 799 araknis,an-700-ap-i-ac|\ 800 engenius,eap1200h|\ 801 engenius,enstationac-v1|\ 802 glinet,gl-x750|\ 803 watchguard,ap300) 804 caldata_extract "art" 0x5000 0x844 805 ath10k_patch_mac $(macaddr_add $(mtd_get_mac_binary art 0x0) 2) 806 807 808 809 810 caldata_extract part offset count 811 caldata_dd $mtd /lib/firmware/$FIRMWARE $count $offset || \ 812 caldata_die "failed to extract calibration data from $mtd" 813 dd if=$source of=$target iflag=skip_bytes,fullblock bs=$count skip=$offset count=1 2>/dev/null 814 815 ======= 816 817 part=$(basename $(dirname $(grep -l art /sys/class/mtd/*/name))) 818 dd if=/dev/$part \ 819 of=/run/cal-pci-0000:00:00.0.bin iflag=skip_bytes,fullblock \ 820 bs=0x844 skip=0x5000 count=1 821 822 Mon Feb 27 22:46:37 GMT 2023 823 824 Found and fixed a bunchg of things that were stopping ath10k from 825 working. The remaining problem is (I think) that insmod is not 826 synchronous, so "ip link set up dev wlan1" doesn't work immediately 827 after the module is inserted. Maybe we need another netlink thing 828 to wait until the interface is present. 829 830 831 Wed Mar 1 18:26:44 GMT 2023 832 833 ath10k works, but the wlan module loading stuff is quite kludgey 834 835 I wonder if wlan0, wlan1, eth0, eth1 etc should be defined per-device 836 - how does the aplication config know which devices exist? If we 837 decide to switch to some form of persistent device naming, the names 838 will differ from one device to the next. Perhaps the device should 839 also provide standard names where possible? 840 841 services.network.links = { 842 lan = interface { ... }; 843 wan = interface { ... }; 844 wlan_24 = interface { ... }; 845 wlan_5 = interface { ... }; 846 } 847 848 Thu Mar 2 22:45:11 GMT 2023 849 850 We have a flashable image! 851 852 Now we can use the gl-ar750 for internet access in the shed, we can 853 apppropriate the other device that's in there and try Liminix on it 854 855 Fri Mar 3 23:08:58 GMT 2023 856 857 If we're going to unplug serial console from the gl-ar750 maybe we 858 should install an ssh server first. 859 860 0) set a root password 861 1) allow setting a root password from configuration.nix 862 (means defining config.users properly) 863 2) allow authorizedKeys per user 864 3) dropbear service 865 4) see if the wired lan works! :-) 866 867 868 Sat Mar 4 12:31:07 GMT 2023 869 870 To improve logging, each service should have its own s6-log service 871 which prefixes the service name onto the log line and then sends to 872 stdout 873 874 https://skarnet.org/software/s6/servicedir.html 875 https://skarnet.org/software/s6/s6-log.html 876 877 As far as I can tell, the `log` directory inside the service 878 directory should itself be a service directory for the s6-log 879 process that does this 880 881 .... hahaha no that doesn't work 882 883 s6-rc, for some reason, ignores the `log` directory and requires 884 that loggers be done with consumer-for and producer-for instead 885 886 887 Sat Mar 4 23:27:00 GMT 2023 888 889 notes for this week's news update 890 891 * ath10k kernel support and and firmware 892 893 - 5GHz wifi works 894 895 - need to retrieve the firmware from a special - partition on the 896 device itself, so we do that using a service that - the wlan 897 interface depends on 898 899 * replace waitup with more generally useful ifwait 900 901 to make the ath10k load at boot, we need to insert the module and then 902 wait for it to do something or other in the background before we can 903 configure the interface. so we need something like waitup but 904 for presence not operational state 905 906 it turns out that a program that just waits for a particular interface 907 state and then exits is quite simple to add into run scripts and 908 we don't need all that notification-fd stuff anyway 909 910 * move FW_LOADER* config to modules/base 911 912 * rejig config a bit. 913 - device hardware characteristics are now under 914 the `hardware` key and include the available network interfaces. 915 - options for users and groups are now defined a bit more 916 specifically than "attrset", making it possible to e.g. set a 917 root password 918 - dts is moved from `boot` to `hardware` 919 920 921 * now producing flashable images, so you can generate a liminix config 922 and write it to the device instead of having to boot using TFTP and 923 a serial console every time 924 925 * ssh support 926 927 * prefix logs with the service name 928 929 Sun Mar 5 22:51:21 GMT 2023 930 931 Added swconfig: it was a straight copy from nixwrt and hasn't changed 932 upstream since. But don't need it, because the lan port works fine 933 without it (I assume both lan ports and the cpu are all connected 934 untagged) 935 936 Mon Mar 6 09:42:33 GMT 2023 937 938 Today I plugged in the mt300a. 939 940 echo 17 >/sys/class/gpio/export 941 echo out >/sys/class/gpio/gpio17/direction 942 943 944 why are our images getting big 945 946 - lua links ncurses 947 - hostapd links openssl and sqlite 948 - nftables needs 949 - iptables? 950 - jansson? what is that? 951 - libedit/readline 952 - ifwait needs bash 953 954 955 File: result/squashfs 956 Size: 10371072 Blocks: 20256 IO Block: 4096 regular file 957 958 with smaller nftables: 9617408 Blocks: 18784 959 960 hostapd wqithout sqlite 9003008 Blocks: 17584 961 962 without bash: 8622080 Blocks: 16840 IO Block: 4096 regular file 963 964 without lua readline: bigger?! 8769536 Blocks: 17128 IO Block: 4096 regular file 965 966 967 Mon Mar 6 20:57:49 GMT 2023 968 969 [ 0.539992] mtk_soc_eth 10100000.ethernet: mdio-bus disabled 970 [ 10.493918] platform regulatory.0: Direct firmware load for regulatory.db fail 971 ed with error -2 972 [ 10.502828] cfg80211: failed to load regulatory.db 973 974 Check in morning, but whichever port the ethernet cable is plugged into, 975 is considered by the kernel as port 0 - which I think we should treat as 976 WAN 977 978 VLAN 1: 979 vid: 1 980 ports: 1 2 3 4 5 6t 981 VLAN 2: 982 vid: 2 983 ports: 0 6t 984 985 ip link add link eth0 name lan type vlan id 1 986 ip link add link eth0 name wan type vlan id 2 987 988 figure out how to add these to gl-mt300a device config 989 then extedner.nix can add a bridge 990 991 Tue Mar 7 20:13:15 GMT 2023 992 993 We need NTP or some other way to get accurate time 994 995 [done] Need to add regulatory.db somewhere standard, maybe modules/wlan? 996 997 Tue Mar 7 21:43:56 GMT 2023 998 999 When we get to phase 2, need to review how network interfaces and 1000 their addresses interplay. It should be possible to have a network 1001 interface and interrogate the addresses associated with it - esp 1002 with ipv6 where there are multiple addresses for the device 1003 1004 This thought prompted by looking at the loopback interface, which is 1005 a bundle of addresses and therefore we can't see what any of them are 1006 1007 1008 Tue Mar 7 22:05:44 GMT 2023 1009 1010 [phase 1] 1011 20) publish the manual using CI 1012 30) document flashing process 1013 31) go through all the unexpected dmesg and triage it 1014 25) ntp or some other accurate time source 1015 1016 [phase 1.5] 1017 26) ssh keys 1018 8) get ipv6 address from pppoe 1019 9) get ipv6 delegation from pppoe and add prefix to lan 1020 10) support dhcp6 in dnsmasq, and advertise prefix on lan 1021 11) firewalling and nat - default deny or zero trust? 1022 7) upgrade ppp to something with an ipv6-up-script option, move ppp and pppoe derivations into their own files 1023 32) set up iperf and do some performance measurement 1024 35) also we need to check our wireless country code 1025 1026 1027 [phase 2] 1028 3) document services so I can remember how they work. Refer back to Oct 18 for notes that no longer make sense 1029 4) check out restart behaviour of dependent services when depended-on service dies 1030 13) check that references to outputs correspond with declared outputs 1031 33) network interfaces vs the services that manage their addresses 1032 34) write a short guide explaining how to use s6-svc 1033 1034 [phase n] 1035 12) write secrets holder as a service with outputs 1036 16) writable filesystem (ubifs?) 1037 17) overlay with squashfs/ubifs - useful? think about workflows for how this thing is installed 1038 1039 1040 dmesg lines to investigate for gl-mt300a: 1041 [ 0.467314] OF: Bad cell count for /palmbus@10000000/spi@b00/flash@0/partition 1042 [ 0.539709] mtk_soc_eth 10100000.ethernet: mdio-bus disabled ? 1043 [ 8.778513] compat: loading out-of-tree module taints kernel. 1044 [ 17.686561] ieee80211 phy0: rt2800_wait_bbp_rf_ready: Error - BBP/RF register access failed, aborting 1045 [ 17.696025] ieee80211 phy0: rt2800_loft_iq_calibration: Warning - RF RX busy in LOFT IQ calibration 1046 [ 17.875147] ieee80211 phy0: rt2800_rxiq_calibration: Warning - Timeout waiting for MAC status in RXIQ calibration 1047 1048 for gl-ar750: 1049 [ 0.000000] Unknown kernel command line parameters "earlyprintk=serial,ttyS0", will be passed to user space. 1050 [ 0.416679] OF: Bad cell count for /ahb/spi@1f000000/flash@0/partitions 1051 [ 0.825495] ag71xx 19000000.eth: Could not connect to PHY device. Deferring probe. 1052 [ 1.632700] pci_bus 0000:00: root bus resource [mem 0x10000000-0x13ffffff] 1053 [ 1.639824] pci_bus 0000:00: root bus resource [io 0x0000] 1054 [ 1.645601] pci_bus 0000:00: No busn resource found for root bus, will use [bus 00-ff] 1055 [ 32.032326] ath10k_pci 0000:00:00.0: pdev param 0 not supported by firmware 1056 [ 36.627844] ath10k_pci 0000:00:00.0: failed to receive initialized event from target: 00000000 1057 1058 1059 Fri Mar 10 13:17:56 GMT 2023 1060 1061 Lunchtime notes on images for real devices, vs ci.nix 1062 1063 * successfully building an image doesn't mean that the image boots 1064 or does anything useful 1065 1066 * don't want to faff with serial wires on every device every time 1067 to test it. so 1068 1069 * ideally, build ram-based images of rotuer, extneder, arhcive in CI 1070 with a watchdog timer that will reboot if it can't see the network 1071 1072 * figure out how to boot into the new image from an ssh connection. I 1073 assume the challenging bit here is grabbing x MB of contiguous phys 1074 mem after boot: I think we'd have to reserve it at _first_ boot and 1075 then somehow copy into it before rebooting 1076 1077 An easier first goal might be a tool to flash from the shell command line, 1078 but that runs a greater risk of bricking 1079 1080 1081 Fri Mar 10 14:35:40 GMT 2023 1082 1083 programs.busybox = { 1084 enable = true; 1085 applets = [... ]; 1086 config = { 1087 }; 1088 } 1089 1090 Fri Mar 10 23:49:04 GMT 2023 1091 1092 Well, we have the backup host config up and running - though haven't 1093 plugged it back into its disk yet. 1094 1095 For task 1 what remains is 1096 1097 1) ntp sync 1098 2) write up the flashing procedure 1099 3) a video? 1100 1101 1102 Sat Mar 11 13:58:20 GMT 2023 1103 1104 ================== for video 1105 1106 what is liminix 1107 - nix-based system for creating OS images for routers 1108 - not "nixos on your router" 1109 - nixos-like module system, 1110 - musl for libc 1111 - s6/s6-rc for services 1112 - entirely cross-compiled 1113 1114 why am i making a video? 1115 - unless you have a suitable spare device to install on, 1116 and you want to take it apart, it's currently hard to 1117 take liminix for a spin 1118 - I have these things, so I can give you a tour 1119 1120 let's have a look at how the hardware's hooked up 1121 1122 web site & manual 1123 1124 a config file: 1125 - observe the comments: 1126 - not going to spend ages on this because it's not in its final form. 1127 - as we get more configs for more use cases, we will 1128 get a better feel for what can be abstracted 1129 - that will come later: work so far has been on the 1130 hardware support side 1131 1132 to show that it builds, we're going to add a package. otherwise, 1133 everything from this build is probably already cached 1134 1135 build the config 1136 1137 tftpboot on hardware 1138 1139 flash on hardware 1140 1141 show ci 1142 1143 show a qemu target 1144 1145 Mon Mar 13 22:46:46 GMT 2023 1146 1147 1) rsync on arhcive is failing because no nogroup group 1148 1149 "/nix/store/gfzzl157r8xyp38lpcfxydkiiy6zrs3c-rsync-3.2.6/bin/rsync" "--verbose" "--stats" "--password-file" "/etc/nixos/secrets/arhcive-rsync" "-rltgoDz" "/var/spool/backup" "backup@arhcive.lan::srv/" 1150 @ERROR: invalid gid nogroup 1151 rsync error: error starting client-server protocol (code 5) at main.c(1837) [sender=3.2.6] 1152 1153 2) we can run findfs in a loop until the disk appears 1154 1155 3) still haven't decided how to do ntp but maybe we should just use 1156 the busybox one 1157 1158 4) some way to do upgrades over the wire 1159 1160 - boot with reserved mem and a phram device at 110-128MB even in the 1161 flashable version 1162 1163 - watchdog timer in kernel 1164 1165 - kexec in kernel 1166 1167 - userland service to feed the dog as long as local network is up 1168 (may need to start it a couple of minutes after boot, how do we 1169 do that?) 1170 1171 - can we use flashcp on a phram mtd? 1172 1173 5) maybe setup a vhost for hydra or something 1174 1175 [nix-shell:~/t]$ wget --reject-regex '\?' -D localhost -N -r --exclude-directories=/api --level=2 --convert-links -e robots=off http://localhost:3003/jobset/liminix/build/ 1176 1177 is almost a mirror 1178 1179 Tue Mar 14 20:17:35 GMT 2023 1180 1181 - do we have a phram mtd? need config for size and location 1182 1183 - how do we set the boot device 1184 - for first boot need to boot real flash, use dtb, ignore bootloader args 1185 - for kexec, boot phram, specify args somehow (could rewrite dtb) 1186 1187 => can use same kernel for both if we can give kexec a dtb with 1188 different params, which seems to be possible 1189 1190 so we need a module for the initial kernel to say 1191 - create phram mtd 1192 - boot from real mtd (will be index + 1) 1193 - enable KEXEC in kernel 1194 - add kexec-tools 1195 1196 and for the kernel we boot into 1197 - most of the above 1198 - except for the boot device 1199 - create an output with objects that kexec(8) can parse 1200 1201 Could be same module for both with different outputs 1202 1203 what do we call this thing? "revertable" 1204 1205 Wed Mar 15 19:11:09 GMT 2023 1206 1207 "revertable" implies mtd support for the rootfs and a ramdisk at 1208 defined location 1209 1210 "tftpboot" implies "revertable", because it will use the same ramdisk 1211 1212 1213 Fri Mar 17 11:44:40 GMT 2023 1214 1215 - patch the kernel kexec code to pass DTB to new kernel unconditionally 1216 - unpatch pernel to pass command line to kexec (breaks DTB passing) 1217 - decide how we specify rootfs. doing it by number is awkward 1218 - may be phram 1219 - may be real mtd root 1220 - may be real mtd root but renumbered becuase phram exists 1221 1222 Wild idea: we could probably get rid of the need for declaring a phram 1223 device in the first kernel, if we can use kexec to copy the squashfs into 1224 physical ram. As far as I can see this is a simple(sic) matter of 1225 specifying it as a segment, but we would have to extend kexec-tools 1226 to do this and it's quite a niche option if we make it do all the 1227 mtd setup. 1228 1229 kexec --dtb=foo.dtb --map-file=squashfs@0x120000 1230 1231 1232 Sat Mar 18 18:02:26 GMT 2023 1233 What if: we added derivations for "apply openwrt changes" as packages, 1234 which could then be called from the kernel derivation's extraPatchPhase? 1235 There could be one for generic and one for each openwrt targetop 1236 1237 Mon Mar 20 18:40:53 GMT 2023 1238 1239 - kexec patch is sent to mailing list, keep an eye for replies 1240 - watchdog 1241 - ntp 1242 - rebuild images for live devices 1243 - can we build a static busybox with flashcp applet and scp it 1244 to arhcive etc? 1245 - [DONE] install mailman and hyperkitty on myhtic, create mailing list 1246 1247 Tue Mar 21 22:59:54 GMT 2023 1248 1249 I haven't found a way to arm the watchdog before userland runs, which 1250 would be really nice: although there's WATCHDOG_HANDLE_BOOT_ENABLED 1251 and WATCHDOG_OPEN_TIMEOUT it doesn't seem to be sufficient, Maybe 1252 those options work only when the hardware watchdog is already 1253 armed. It might not be completely awful insofar as any failure to 1254 mount root usually results in panic anyway, so provided we start 1255 watching early in boot then there's not a big window for anything 1256 to go wrong 1257 1258 What should the watchdog service do? Ideally we want something that 1259 "ratchets" : can be started in early boot and signals health as long 1260 as the system is starting up, then once the system is in "steady 1261 state" it stops pinging as soon as any part of that steady state 1262 becomes unhealthy. This feels like a refinement for a much later 1263 phase though. 1264 1265 Maybe the health criteria might be 1266 (sshd and lan services are running) or (time since boot < 120s) 1267 1268 Thu Mar 23 00:11:23 GMT 2023 1269 1270 tftpboot and (kexecboot || flashable) have incompatible DTB-finding 1271 strategies which is painful if you add both modules and then 1272 expect tftp booting to still work 1273 1274 Maybe we could patch the kernel to use some better strategy for when 1275 to use/ignore the bootloader command line: e.g "only if it 1276 contains the string 'liminix'". Could do this by patching 1277 arch/mips/kernel/setup.c bootcmdline_init to 1278 1279 if(strstr(arcs_cmdline, "liminix") == NULL) arcs_cmdline[0] = '\0' 1280 and then defining CONFIG_MIPS_CMDLINE_DTB_EXTEND. The 1281 bootloader command line then needs to specify only the 1282 _additional_ parameters that weren't in the DTB 1283 1284 (later: that turned out to be quite straighforward) 1285 1286 Fri Mar 24 23:45:12 GMT 2023 1287 1288 - add ntp support 1289 - [DONE] expose hydra to internet 1290 - check MAC address weirdness? 1291 - call Task 1 "done" 1292 1293 Sun Mar 26 00:19:15 GMT 2023 1294 1295 Would be nice to have a flash.sh built in outputs.flashable 1296 1297 Sun Mar 26 15:27:14 BST 2023 1298 1299 Let's think about services and modules. 1300 1301 Module 1302 + can change global config 1303 * add users, groups etc 1304 * change kernel config 1305 * change busybox config 1306 + well-typed parameters 1307 - is a "singleton": can't have the same module included twice 1308 with different config. e.g. can't have two hostap modules running on 1309 different wlan radios. 1310 - can't express dependencies: a depends on b 1311 1312 suppose: 1313 1314 * modules add service functions to the config? then there's no 1315 way to define a service while forgetting to import the module 1316 1317 * we use the lib.types stuff for service function arguments 1318 1319 * maybe we stop naming services.foo for every damn thing 1320 1321 * but remember, s6 services do need unique names 1322 1323 1324 imports = [ ../modules/dhcp4 ]; 1325 1326 services.dhcp4 = config.services.udhcp { 1327 interface = lan.device; 1328 options = { 1329 foo = true; 1330 bar = 42; 1331 }; 1332 depends = [ services.some_other_thing ]; 1333 } 1334 1335 modules/dhcp4 udhcp fn needs to define a type for its argument, then 1336 use something like 1337 1338 if arg_type.check def.value then res 1339 else throw "The option value `${showOption loc}' in `${def.file}' is not a ${arg_type.name}.") 1340 1341 (where def comes from I don't know yet) 1342 1343 Tue Mar 28 10:44:40 BST 2023 1344 1345 we should reserve the name "service" for actual instantiated 1346 services. This means we need a name for the functions that 1347 make services. "class", "template", "fn", "maker", "factory"? 1348 And a namespace name so they're not interleaved with real 1349 services, which sort of suggests they are packages 1350 1351 if we want to do services = { 1352 foo = longrun { ... }; 1353 bar = longrun { ... }; 1354 } 1355 1356 without repeating the `name` as an attribute of the longrun, 1357 then longrun can't return a derivation: it has to return some 1358 function that accepts `name` as a parameter. 1359 1360 where services.a depends on services.b, at the time its builder is run 1361 it needs to know what name s6-rc will use for service b 1362 1363 maybe an s6 service definition should be an attrset not a derivation. 1364 1365 maybe this is outside scope for phase 2 1366 1367 Tue Mar 28 13:22:06 BST 2023 1368 1369 Reading nixos/doc/manual/development/building-parts.chapter.md it 1370 suggests to me that we should rename config.outputs to 1371 config.system.outputs. The more general question here is whether it's 1372 good to be augmenting a variable called "config" with all this 1373 generated stuff that is patently not configuration - perhaps putting 1374 it under a "system" key will keep it all in one place 1375 1376 Tue Mar 28 13:32:30 BST 2023 1377 1378 how should we handle filesystem state? e.g. resolvconf service 1379 1380 if a service provides a file at a known global pathname, it can't be 1381 parametrised - it must be a singleton. 1382 1383 Tue Mar 28 20:25:20 BST 2023 1384 1385 wondering if we should swap phases 2 and 3. We can't really address 1386 modules without addressing services, which is phase +n, whereas we 1387 can tackle overlay/ubi whenever 1388 1389 nand flash may have bad blocks 1390 nor flash (supposedly) doesn't 1391 1392 ubi provides erase counts and bad block remapping on top of the mtd 1393 interface. this means we should avoid flashcp of a ubi image straight 1394 onto (nand) mtd as we will lose the erase counts and bad block information 1395 that UBI tracks. 1396 1397 overlayfs works on a filename basis, so might not be very effective : 1398 any change that results in a new store path will mean the entire package 1399 appears in two places. I think it's reasonable to offer squashfs or 1400 ubifs without overlay. 1401 1402 open questions: 1403 1404 1) if uboot doesn't support UBI, we can't boot a kernel on a ubifs 1405 so we need reserved space for the kernel. 1406 1407 - unless we add some padding after the kernel, every new kernel 1408 that's bigger than its predecessor will trash the start of the 1409 ubi space (and wipe out its erase count) 1410 - This suggests we should build more stuff as modules and less as 1411 compiled-in 1412 1413 2) once a device has had a ubi volume created on it, probably we want 1414 to use ubi-aware tools to update that volume in future instead of a 1415 whole new flash, because we wish to preserve erase counts. This means 1416 running ubiformat --image-file=foo.ubi on the device instead of flashcp 1417 1418 we can add a "ubi-flashable" output that creates a .ubi image and 1419 a flashcp image that wraps it, with instructions on which to use. 1420 1421 Fri Mar 31 22:13:54 BST 2023 1422 1423 Error: too small LEB size 3968, minimum is 15360 1424 1425 > This error means that you are trying to mount too small UBI 1426 volume. Probably because your flash is too small? Try to use JFFS2, 1427 then, because it suits small flashes better since it has much lower 1428 space overhead. Indeed, UBIFS stores much more indexing information on 1429 the flash media than JFFS2, so it has much higher overhead. Also, UBI 1430 has some overhead (see here). Thus, if you have a small flash device 1431 (e.g., about 64MiB), it makes sense to consider using JFFS2. 1432 1433 1434 Argh. Oh well, 1435 1436 Sat Apr 1 15:27:39 BST 2023 1437 1438 There's limited value in recreating pseudofiles for jffs2 because 1439 the system is writable - changes made to /bin, /dev etc in config.filesystem 1440 should take effect on a running system. 1441 1442 Can we take inspiration from https://grahamc.com/blog/erase-your-darlings/ ? 1443 1444 in early boot: 1445 mount ramfs on / 1446 mount the writeable filesystem on /persist/ 1447 bind mount /persist/nix on /nix 1448 run script to populate rootfs from pseudofiles 1449 1450 on a router, do we need _anything_ persistent that's outside the store? 1451 1452 - state for dhcp leases and stuff 1453 - secrets 1454 - maybe, files that the user has downloaded 1455 1456 this will probably require initramfs. if just use jffs2 as the rootfs and 1457 don't worry about /persist, we can skip that step. 1458 1459 1460 1461 1462 [ aside: I think we may be putting two busyboxes in the image: 1463 see modules/s6/default.nix s6-init-scripts has buildInputs = [busybox]; ] 1464 1465 Mon Apr 3 18:34:26 BST 2023 1466 1467 suppose 1468 - we boot the system with systemConfig=/nix/store/eeeeee-system 1469 - the early-init script runs /target/$systemConfig/create-root /target 1470 after mounting /target 1471 - then it runs chroot /target $systemConfig/bin/init "$@" 1472 1473 or maybe we could combine those steps? 1474 or maybe it doesn't matter too much ... 1475 1476 Thu Apr 6 21:25:41 BST 2023 1477 1478 what now? 1479 1480 - put a jffs2 onto some hardware device 1481 - what do we do with uboot? 1482 - should we pad the kernel? 1483 - maybe kernel module support would be good if we're making it 1484 hard to do kernel updates 1485 - try the nix-copy-closure thing and work out what else we don't know 1486 - [done] detect endian correctly 1487 1488 1489 to ask a different question, what else do we need to dogfood a router? 1490 1491 Sun Apr 9 10:06:08 BST 2023 1492 1493 - rename outputs.flashable to outputs.flashimage 1494 - rename modules/flashable to modules/flashable_ro 1495 - create outputs.flashable in modules/jffs2 1496 - rename modules/jffs2 to modules/flashable_rw 1497 - add enable config to both? 1498 - enable kernel module compilation 1499 1500 1501 Mon Apr 10 23:50:41 BST 2023 1502 1503 - initramfs parses /proc/cmdline to find root fs, might not play 1504 nice with defaulting 1505 1506 - how to build kernel modules 1507 1508 - look at closure size, is it this big because we've broken it 1509 or is jffs2 usually this much bigger than squashfs 1510 1511 - maybe squashfs with overlay might be better if we could 1512 ensure hardlinks? 1513 1514 - maybe there's something like overlayfs but content-addressable? 1515 1516 Sat Apr 15 18:57:46 BST 2023 1517 1518 for the same configuration: 1519 1520 -r--r--r-- 1 root root 6066176 Jan 1 1970 /nix/store/0x271rg45mcjjgbma9wi31h1yd109fpy-frob-squashfs 1521 -r--r--r-- 1 root root 12255232 Jan 1 1970 /nix/store/zx11adagcbzqsnqkyz5kgvr392vhlrpr-make-jffs2 1522 1523 may want to reconsider not using squashfs with overlay 1524 1525 Wed Apr 19 22:22:48 BST 2023 1526 1527 Where next? 1528 1529 Sun Apr 23 18:24:34 BST 2023 1530 1531 - we are down to ~ 11MB image for a barely functional (IPV4) router 1532 this is by avoiding all dependencies on openssl or gnutls 1533 - rotuer is not recognising when I set the hostname 1534 - I may have forgotten the root password :-( 1535 - why is hello world 70K unless hardeningDisable? 1536 1537 Fri Apr 28 20:51:52 BST 2023 1538 1539 To do nix-copy-closure we need nix-store, which is a symlink to nix, 1540 which is 1541 1542 -rwxr-xr-x 1 dan users 2.3M Apr 28 21:08 nix 1543 1544 (stripped). This is a lot bigger than, say, a simple script to 1545 loop through the closure of a derivation and copy only the store 1546 folders that don't exist already. 1547 1548 * we'd like to only transmit the packages that aren't already present 1549 1550 * we'd like to use a single ssh connection 1551 1552 1553 S: here is a list of package names 1554 C: these are the names of the packages I want 1555 S: here are the packages 1556 1557 while read $f ; do 1558 test -d $f || echo $f 1559 end 1560 1561 Tue May 2 21:53:08 BST 2023 1562 1563 1) we have a script that runs on the receiver, which 1564 1565 - accepts a list of store paths 1566 - prints the missing store paths 1567 - runs cpio -i < stdio 1568 1569 2) we need a script for the sender that 1570 1571 - refs=$(nix-store -q --references $1 && echo end) 1572 - opens ssh connection 1573 - print ssh $refs 1574 - needed= capture result until "end" received 1575 - find needed | cpio -o > ssh-connection 1576 - close connection 1577 1578 3) to have a reasonable hope of testing this we should do it with qemu. It would be nice 1579 if we could connect without faff to the qemu lan interface : either we do this by bringing up 1580 another qemu vm (preferably with the host store shared, otherwise it has to build a mips cross 1581 compiler/libc) or maybe we could do something unholy with ssh ProxyCommand 1582 1583 ssh -o ProxyCommand "socat - UDP4-DATAGRAM:230.0.0.1:1234,sourceport=1234,reuseaddr,ip-add-membership=230.0.0.1:127.0.0.1" 1584 1585 1586 1587 4) we haven't solved garbage collection, though I think "remove everything not in 1588 nix-path-registration" might be what's needed there 1589 1590 Wed May 3 22:01:19 BST 2023 1591 1592 Something weird is going on with qemu net device enumeration: when I 1593 run it interactively I'm getting the access network (mac ending :02) 1594 on eth0 and the lan (mac ending :01) on eth1, and if it's behaving the 1595 same in CI then how come any of the tests work? vanilla-confinguration.nix 1596 definitely assumes lan=eth0 1597 1598 By switching from -device virtio-net-pci to -device virtio-net then 1599 I get the desired behaviour back 1600 1601 Sat May 6 18:42:28 BST 2023 1602 1603 Next: 1604 1605 - package min-copy-closure 1606 - see if we can use it on some output to copy the whole system closure 1607 - post-copying symlink munging 1608 - try it on a real device, see if it works for config file updates 1609 - collect-garbage/delete-old-generation 1610 1611 1612 Sun May 7 23:03:03 BST 2023 1613 1614 Shortly after all the work to reduce system closure size last time, I 1615 tried adding the necessary packages to support nix-copy-closure and 1616 saw it start building a complete C++ system with Boost. My fears that 1617 this would lead to quite a large increase in the system size were, it 1618 turned out, entirely founded. 1619 1620 So I wrote my own - or at least, a quite minimal substitute. The core 1621 logic is simple - on the sender, we get the list of required packages, 1622 then we check for the existence of `/nix/store/eeeeeee-foo` for 1623 each of them on the target, and whatever's missing we send across the 1624 link using cpio. 1625 1626 It sounds simple, and it should be simple, and in retrospect it _was_ 1627 simple. Along the way I went on a bit of a Qemu networking tangent and 1628 learned quite a lot about the bash `coproc` command 1629 1630 Tue May 9 21:06:53 BST 2023 1631 1632 General direction of my thoughts: 1633 1634 - get a baseline working rotuer system 1635 - prove that min-copy-closure works with it 1636 - refactor the crap out of it 1637 - configurablise the bordervm usb ethernet setup 1638 - when we have a good idea of how/whether min-copy-closure *actually* 1639 works, declare "writeable filesystem" to be done 1640 - start to get more of a feel for how the services/config hang together 1641 1642 ? why does rotuer not have a hostname? 1643 1644 ? how can we get a device hooked up to rotuer's lan port that we can 1645 control remotely 1646 1647 Sun May 14 23:25:46 BST 2023 1648 1649 the outputs.systemConfiguration attribute builds a derivation 1650 containing a single file bin/activate 1651 1652 _Presumably_, copying its closure will copy all the things, as 1653 we already use it as the roots for jffs2 creation. However, there 1654 is also a symlink created from /init at jffs2 creation 1655 1656 Mon May 15 21:32:38 BST 2023 1657 1658 Had a neat idea about uing an overlayfs combining jffs2 and ramfs 1659 to do upgrades that would otherwise be larger than the flash. 1660 Could use "overlay merge" from https://github.com/kmxz/overlayfs-tools 1661 1662 Wed May 17 15:18:55 BST 2023 1663 1664 liminix-rebuild doesn't collect garbage (this is a mising feature, not 1665 a bug). We think we can fix this using nix-path-registration: specifically, 1666 by deleting anything not in it. 1667 1668 What we're going to do: build a fresh system image for rotuer, then 1669 dogfood liminix-rebuild until we've succeeded in getting it to 1670 change its hostname 1671 1672 Also wondering if we should drop outputs.default, but maybe not 1673 1674 * systemConfiguration: used for updates 1675 * vmroot: used for qemu 1676 * flashimage: used for flashing 1677 * tftproot: used for dev/test 1678 1679 As long as we're consistently setting the default output to whichever 1680 is the appropriate "full production image" I think we're good. 1681 1682 Wed May 17 22:45:40 BST 2023 1683 1684 Random thought: when we bind mount /target/persist/nix to /target/nix 1685 we could make it read-only. worth doing? 1686 1687 Thu May 18 10:59:39 BST 2023 1688 1689 - liminix-rebuild can't find reboot: probably the PATH is just 1690 generally wrong for ssh sessions (maybe all non-login sessions?) 1691 1692 - need to copy path registration file somewhere useful and 1693 delete stuff not in it at the appropriate time. Would be safest 1694 to do that either late in the shutdown process before rebooting, 1695 or during boot. 1696 1697 Fri May 19 15:18:13 BST 2023 1698 1699 If we make min-collect-garbage - just a command you can run whenever - 1700 that will be fine for current capabilities. It won't work with the 1701 theoretical overlayfs system, though: we need to copy-down from the 1702 ramfs to real flash before rebooting, and that can't happen until 1703 there's disk space to do it 1704 1705 Sat May 20 22:35:25 BST 2023 1706 1707 We have a working min-collect-garbage (seems to, anyway ...) 1708 1709 - having ssh host key wiped on reboot is sucky. maybe we can have 1710 /persist/secrets and a service that looks there? 1711 1712 - find out what files ash sources on non-login shell startup 1713 [ set ENV=/etc/ashrc in parent process env ] 1714 1715 - services.default is suboptimal as there is no way to add to it 1716 without wiping it 1717 1718 - decide whether to use liminix- or min- as our prefix for nixy 1719 commands 1720 1721 - should we move config.outputs -> config.system.outputs ? see Mar 28 1722 1723 - less crap firewall 1724 1725 - add ipv6 support to rotuer 1726 1727 - create an l2tp configuration 1728 1729 - iperf and tuning 1730 1731 - wlan country code 1732 1733 1734 dropbear weak hashes? https://github.com/mkj/dropbear/issues/138 1735 1736 Sun May 21 11:48:07 BST 2023 1737 1738 dropbear will generate host keys on first connection. It's (probably) good that the 1739 key is generated on-device and also that we wait until there's some randomness. 1740 It's not so good that it will only write the key to DSS_PRIV_FILENAME which is 1741 hardcoded to /run 1742 1743 Sun May 21 17:27:31 BST 2023 1744 1745 What do we need for ipv6? 1746 1747 - upgrade ppp to something with an ipv6-up-script option, move ppp and pppoe derivations into their own files 1748 - get ipv6 address from pppoe 1749 - get ipv6 delegation from DHCPv6 1750 - support dhcp6 in dnsmasq, and advertise prefix on lan 1751 - firewall settings 1752 1753 Sun May 21 21:30:17 BST 2023 1754 1755 Making hydra build the docs is straightforward, but making it 1756 _publish_ the docs is outside scope, really. It can serve the files 1757 but they're all text/plain 1758 1759 Should hydra push the docs to www.liminix.org or should www.liminix.org 1760 pull? 1761 1762 TODO-at-some-point: assign uids and gids dynamically, somehow 1763 1764 Tue May 23 22:56:33 BST 2023 1765 1766 following the guidance at https://support.aa.net.uk/IPv6: 1767 1768 we run odhcp6c to do router solicitation/advertisement dance 1769 1770 1771 odhcp6c environment variables: 1772 1773 RA_ADDRESSES= 1774 RA_REACHABLE=0 1775 CER= 1776 PASSTHRU=00170020200108b0000000000000000000002020200108b0000000000000000000002021 1777 SERVER=fe80::203:97ff:fed6:0 1778 RA_MTU=0 1779 RA_ROUTES=::/0,fe80::203:97ff:fed6:0,65535,512 1780 OPTION_1=00030001e4956e4ef2fa 1781 NTP_FQDN= 1782 OPTION_2=00030001000397d60000 1783 RA_DOMAINS= 1784 DOMAINS= 1785 AFTR= 1786 SIP_IP= 1787 NTP_IP= 1788 PREFIXES=2001:8b0:de3a:40dc::/64,7198,7198 1789 RA_HOPLIMIT=64 1790 RA_DNS= 1791 RDNSS=2001:8b0::2020 2001:8b0::2021 1792 SNTP_IP= 1793 RA_RETRANSMIT=0 1794 SIP_DOMAIN= 1795 ADDRESSES=2001:8b0:1111:1111:0:ffff:51bb:4cf2/128,3598,7198 1796 1797 # ip -6 route |grep default 1798 default via fe80::203:97ff:fed6:0 dev ppp0 metric 1024 expires 65211sec 1799 1800 presumably from RA_ROUTES but why is the metric appaently doubled? 1801 1802 Tue May 30 21:25:37 BST 2023 1803 1804 We have an odhcpc script that preserves the prefix delegation from the 1805 ISP. We need a service that notices whenever the state is 1806 available/has changed, and updates the LAN IPv6 address. 1807 1808 The service can depend on odhcp 1809 1810 add inotify to packages 1811 use writeFennelScript with that dep 1812 see if it works 1813 1814 Wed May 31 23:33:00 BST 2023 1815 1816 We have a thing that sets ipv6 address on lan interface, yay us 1817 1818 A firewall would be a very good idea 1819 1820 Thu Jun 1 18:46:59 BST 2023 1821 1822 TODO for now: 1823 1824 - services.default is suboptimal as there is no way to add to it 1825 without wiping it 1826 1827 - decide whether to use liminix- or min- as our prefix for nixy 1828 commands 1829 1830 - should we move config.outputs -> config.system.outputs ? see Mar 28 1831 1832 - less crap firewall 1833 1834 - create an l2tp configuration 1835 1836 - iperf and tuning 1837 1838 - wlan country code 1839 1840 Thu Jun 1 21:26:37 BST 2023 1841 1842 how can a client machine "opt out" of using the firewall, to allow 1843 incoming connections? Most convenient would be to have a separate SSID 1844 for grownups. Assuming it shows up as a separate wlan device, we can 1845 write firewall rules to allow incoming connections on that interface 1846 (can we? only if the packet is identifiable as destined for that interface) 1847 1848 https://www.rfc-editor.org/rfc/rfc6092.html 1849 https://emailstuff.org/rfc/rfc7084 1850 1851 We could block incoming for slaac and dhcp addresses and permit it for 1852 stable private addresses. If we were fairly sure that devices won't 1853 ask for stable private addresses just for funsies. 1854 1855 https://wiki.archlinux.org/title/IPv6_#Stable_private_addresses 1856 1857 1858 1859 Fri Jun 2 14:42:43 BST 2023 1860 1861 I found a handy guide to nftables at https://ww.telent.net/2023/6/2/turning_the_nftables 1862 1863 Mon Jun 5 16:56:44 BST 2023 1864 1865 1866 How are we going to do this firewall thing then? 1867 I can see no reason to have more than one table per family, so lets 1868 just name the tables after families 1869 1870 There is nothing in nftables for functionally grouping rules by 1871 requirement that may touch multiple hooks/chains, so we need our own 1872 abstraction - and we can't call it any name that nftables uses already 1873 (so, not "ruleset"). rulegroup? 1874 1875 "policy" would be a good name except that it's already taken 1876 1877 "concern"? "requirement"? "feature"? 1878 1879 Mon Jun 19 20:45:48 BST 2023 1880 1881 why is chrony using libedit? 1882 1883 Thu Jun 22 09:52:57 BST 2023 1884 1885 - There is a lot more lua being installed (luac, docs, static 1886 libraries etc) than we really need. 1887 1888 - update User docs to include a list of supported targets 1889 1890 Thu Jun 22 23:43:06 BST 2023 1891 1892 - is there a sysfs to enable ipv6 forwarding? 1893 - we haven't an ipv4 firewall yet 1894 1895 1896 PATH=`echo /nix/store/*nftables*/bin`:$PATH 1897 nft list ruleset 1898 1899 Thu Jun 22 23:58:58 BST 2023 1900 1901 Looks like we're missing at least one kernel config setting for 1902 nftables. Would this be a good time to do a derivation for building 1903 kernel modules? 1904 1905 1906 Sun Jul 9 21:21:17 BST 2023 1907 1908 1909 Tue Jul 11 22:10:17 BST 2023 1910 1911 - s6 cheatsheet, find or write 1912 - could we have > 1 module add to services.default? 1913 - odhcp should parse values from environ and write more files, to save readers 1914 from parsing it 1915 - pkgs.liminix, who knows what thats for any more? 1916 - interface.device, as a general rule, doesn't work because the 1917 device name may be known only at runtime (e.g. for ppp) 1918 - iperf 1919 - figure out wifi regdomain 1920 1921 Tue Jul 11 23:01:59 BST 2023 1922 1923 We can make services depend on kernel modules, however not on bakedin 1924 kernel config 1925 1926 [from March: "Let's think about services and modules."] 1927 1928 Module 1929 + can change global config 1930 * add users, groups etc 1931 * change kernel config 1932 * change busybox config 1933 + well-typed parameters 1934 - is a "singleton": can't have the same module included twice 1935 with different config. e.g. can't have two hostap modules running on 1936 different wlan radios. 1937 - can't express dependencies: a depends on b 1938 1939 thought I had then was: modules provide services. requiring the 1940 ppp module causes config.services.ppp to exist, so you can 1941 1942 services.default = [ 1943 (config.services.ppp { 1944 tty = "17"; 1945 baud = "57600"; 1946 secrets = blah; 1947 }) 1948 ... 1949 ] 1950 1951 this might work. also though we should find out how to do type checking on 1952 service params 1953 1954 Wed Jul 12 23:23:02 BST 2023 1955 1956 https://github.com/NixOS/mobile-nixos/pull/406 // why mobile nixos uses 1957 mobile.outputs instead of system.build 1958 1959 suggests that system.build may not be a thing to blindly emulate 1960 1961 if a service is a derivation should we expect to want to be able to call 1962 it with .override? maybe we want to override the package containing the 1963 daemon it runs. How do we best pass service config as well? 1964 1965 Maybe a service template is a function that returns a derivation 1966 1967 1968 imports = [ ./modules/pqmud.nix ]; 1969 services.mud = system.services.pqmud { 1970 realm = "A deep cavern"; 1971 port = 4067; 1972 users = import ./allowed-users.nix; 1973 # etc etc 1974 }; 1975 services.mudBeta = let mud = 1976 system.services.pqmud { 1977 realm = "A very deep cavern"; 1978 port = 4068; 1979 users = import ./allowed-users.nix; 1980 }; 1981 in mud.overrideAttrs { pqmud = pkgs.pkmudLatest; }; 1982 1983 so we have 1984 1985 config.system.services # services provided by modules 1986 config.system.outputs # build artefacts of various types 1987 1988 the services provided by a module must be introspectable in some way 1989 so that we can compile a list of service options per module 1990 1991 service parameters are defined using the module type system. 1992 Something like this? 1993 1994 # mud.nix 1995 1996 system.services.pqmud = args : 1997 let t = { 1998 name = mkOption { type = types.str; }; 1999 realm = mkOption { type = types.str; }; 2000 port = mkOption { type = types.port; default = 12345; }; 2001 users = mkOption { type = types.any; }; 2002 }; 2003 in assert isType (submodule { options = t; }) args; longrun { 2004 inherit (args) name; 2005 run = "${pkgs.pqmud}/bin/pqmud --port ${port} ....." 2006 }; 2007 2008 Fri Jul 14 19:07:59 BST 2023 2009 2010 It works for pppoe, though typechecking error messages could be 2011 better. 2012 2013 - We need to find a good place to keep the typeCheck function so that 2014 everyone can use it. 2015 2016 - also the type_service type defn exists only locally in modules.nix, 2017 and we would like to refer to it elsewhere 2018 2019 Thu Aug 10 21:46:36 BST 2023 2020 2021 to finish service/modules milestone 2022 2023 [done] there are some modules not using serviceDefn 2024 - modules included by standard.nix should have all their options 2025 grouped together in docs 2026 how can we determine which they are? or maybe "modules that 2027 don't contain services" is an acceptable criterion 2028 maybe this is not actually an issue, if the modules are 2029 reasonably coherent. It looks odd now because base.nix is a mess 2030 [done] print the module pathname so people know what to import 2031 [done] docs don't print the examples 2032 [check?] and seem to be getting the default wrong too 2033 - decide what we deem to be "internal" (if anything) 2034 is `filesystem` internal, for example? or `busybox`? they're 2035 both mostly _used_ internally but may still be valuable to expose 2036 [done] maybe document outputs separately or not at all? 2037 [done] bridge to be one service instead of two? 2038 [done] get rid of services/ 2039 - anything else in rotuer.nix that we should servicify 2040 - services for liminix.networking 2041 - a nice way to specify service dependencies 2042 [done] - do another video 2043 2044 Mon Aug 21 20:02:55 BST 2023 2045 2046 a nice way to do dependencies would be somethng like 2047 2048 services.thething = 2049 let s = svc.thing { .... }; 2050 in addDependencies s (with config.services; [otherthing yetanother]); 2051 2052 except that addDependencies is a really klunky name. dependsOn is very 2053 slightly better? or maybe it could be a function of the derivation? 2054 2055 services.thething = 2056 svc.thing { .... }.depends (with config.services; [otherthing yetanother]); 2057 2058 --- 2059 2060 what does it mean to be dependent on an interface? that's it up? running? 2061 has an address? has a collection of addresses? 2062 2063 2064 services.defaultroute4 = route { 2065 name = "defaultroute4"; 2066 via = "$(output ${services.wan} address)"; 2067 target = "default"; 2068 dependencies = [ services.wan ]; 2069 }; 2070 2071 - this route requires the interface to have an address (if wan is an 2072 interface, anyway ...) 2073 2074 - but otoh a dhcp client doesn't want to wait for an address, because 2075 it is assigning the address. 2076 2077 should an address provider have "interface name" as an output? 2078 is there a set of outputs that every address provider should have - 2079 whether static, dhcp, pppoe? 2080 2081 maybe we're in decision paralysis and should just move forward with 2082 what we know 2083 2084 Wed Aug 23 18:56:08 BST 2023 2085 2086 We may want to change the hardware device files to specify network 2087 interface names not services. Otherwise hardware devices (boards) 2088 depend on module-based-services, which is a bit weird. 2089 2090 Thu Aug 24 18:54:03 BST 2023 2091 2092 - we want network and bridge to be separate modules, because bridge 2093 introduces extra kernel config 2094 2095 - bridge/service wants to create a network device ("ip link"), 2096 using quite similar code as network/link.nix 2097 2098 - but bridge/service is a derivation: it has sight of pkgs but not 2099 config 2100 2101 offtopic: useful s6-rc commands at https://www.skarnet.org/software/s6-rc/faq.html 2102 2103 Fri Aug 25 23:37:57 BST 2023 2104 2105 where we left off: bridge is a bundle, and bundles can't have outputs, 2106 so how do we set the ifname of the bridge? 2107 2108 - ifname of the primary is set 2109 - actually, most things that depend on the bridge really just depend 2110 on the primary anyway (it's OK if 1 <= n < #members are down) 2111 - but *something* should depeond on all the members 2112 2113 turns out maybe we needed two services after all? 2114 2115 Sun Aug 27 23:50:18 BST 2023 2116 2117 I've done enough to make rotuer build, but in the process 2118 trashed vanilla-configuration as I entirely forgot we don't have 2119 a dhcpv4 client service. Need to fix that ... 2120 2121 - anything else in rotuer.nix that we should servicify 2122 - anything in vanilla-configuration ditto 2123 - and arhcive (rsync, watchdog) 2124 - services for liminix.networking 2125 - tidy up the dependency handling in serviceDefn build 2126 (interface is fine, implementation is a bit brutal) 2127 - write a blog entry 2128 2129 Mon Aug 28 16:58:49 BST 2023 2130 2131 - [done] ntp is not setting the time 2132 - nftables syntax error 2133 2134 Thu Aug 31 23:53:54 BST 2023 2135 2136 - anything else in rotuer.nix that we should servicify 2137 [done] - packet forwarding 2138 - dhcp6 client 2139 - what to do with acquire-{wan,lan} scripts? 2140 - resolvconf 2141 - [done] anything in vanilla-configuration ditto 2142 - packet forwarding 2143 - and arhcive 2144 - [not doing] rsync 2145 - [done] watchdog 2146 - [done] mount 2147 - nftables syntax error 2148 - tidy up the dependency handling in serviceDefn build 2149 (interface is fine, implementation is a bit brutal) 2150 - [done] services for liminix.networking 2151 - [done] write a blog entry 2152 - [done] ntp is not setting the time 2153 - [done] static dhcp(6) lease support reqd for dogfooding 2154 2155 Sat Sep 2 21:35:41 BST 2023 2156 2157 Considerations for "mount" service: each filesystem needs to depend on 2158 any mount points for its parent directories, and maybe also on other 2159 services (e.g. filesystem modules, network devices, routes) 2160 2161 mountpoints = { 2162 mnt = { 2163 media = svc.mountpoint.build { 2164 fstype = "msdos"; 2165 device = "/dev/sda1"; 2166 options = [ ...]; 2167 }; 2168 archive = svc.mountpoint.build { 2169 fstype = "ext4"; 2170 device = "/dev/sda2"; 2171 options = [ ...]; 2172 mountpoints = { 2173 remote = svc.mountpoint.build { 2174 fstype = "nfs"; 2175 device = "doc.ic.ac.uk:/public"; 2176 }; 2177 }; 2178 }; 2179 }; 2180 } 2181 2182 services.somethingelse = svc.ftpd.build { 2183 # ... 2184 dependencies = [ mountpoints.mnt.archive ]; 2185 } 2186 2187 what don't we like about this? we have to walk the nested attrset in a 2188 weird way, because the services may contain other mountpoints. Maybe 2189 just keep it simple and do 2190 2191 2192 services.mountpoints = bundle { 2193 name = "mountpoints"; 2194 contents = [ 2195 svc.mountpoint.build { 2196 device = "/dev/sda2"; fstype = "ext4"; directory = "/mnt/isos"; 2197 }; 2198 svc.mountpoint.build { 2199 device = "/dev/sdb1"; fstype = "msdos"; directory = "/mnt/backup"; 2200 dependencies = [ load-vfat-module ]; 2201 }; 2202 ]; 2203 } 2204 2205 Sun Sep 3 17:34:36 BST 2023 2206 2207 how to dogfood 2208 2209 DHCP6 server: static lease support 2210 DHCP client and acquire-{lan-prefix,wan-address} 2211 2212 The emergency boot thingy in glinet u-boot won't help because it 2213 expects to flash from its tftp request instead of booting it. So we 2214 could use kexec instead except that the openwrt install doesn't have 2215 it. So we could swap the hardware devices, the only downside of that 2216 being that then I don't have a test system any more. Or we could YOLO it. 2217 2218 Sun Sep 3 22:11:02 BST 2023 2219 2220 I think we should rejigger the documentation ... 2221 2222 - "getting started": worked example, building and installing Liminix 2223 with a very simple config (wifi AP with ssh daemon) 2224 2225 - using modules 2226 - link to module reference 2227 2228 - creating custom services 2229 - longrun or oneshot 2230 - dependencies 2231 - outputs 2232 2233 - creating your own modules 2234 2235 - hacking on Liminix itself 2236 2237 - contributing 2238 2239 - external links and resources 2240 2241 - module reference 2242 2243 - hardware device reference 2244 2245 --- 2246 2247 I think we might rename wlan_24 to wlan and wlan_5 to wlan1. 2248 This is on the assumption that almost no device is 5GHz only, so 2249 would make it easier to write a basic wlan example that works 2250 both on 2.4GHz boards and dual radio boards 2251 2252 Mon Sep 4 23:15:26 BST 2023 2253 2254 If dhcpcd parsed the update-script output into separate files, half 2255 the complexity of acquire-lan-prefix would go away. The other half is 2256 because it subscribes to changes in the outputs instead of just 2257 running once. Perhaps there's a better way to do that? 2258 2259 Could separate prefixes and addresses something like this... 2260 2261 outputs/prefix/2001\:8b0\:de3a\:40dc\:\:/prefix 2262 outputs/prefix/2001\:8b0\:de3a\:40dc\:\:/length 2263 outputs/prefix/2001\:8b0\:de3a\:40dc\:\:/preferred 2264 outputs/prefix/2001\:8b0\:de3a\:40dc\:\:/valid 2265 outputs/prefix/2001\:8b0\:de3a\:80\:\:/prefix 2266 outputs/prefix/2001\:8b0\:de3a\:80\:\:/length 2267 outputs/prefix/2001\:8b0\:de3a\:80\:\:/preferred 2268 outputs/prefix/2001\:8b0\:de3a\:80\:\:/valid 2269 2270 the directory name is arbitrary as long as it's unique. Might even be better to 2271 remove the colons 2272 2273 outputs/prefix/200108b0de3a40dc/valid 2274 2275 or we could adopt the MS convention and replace with hyphens 2276 2277 outputs/prefix/2001-8b0-de3a-40dc--/prefix 2278 2279 Also: we should write some kind of test for this... 2280 2281 2282 Tue Sep 5 21:36:39 BST 2023 2283 2284 How do we set the cpu governor? 2285 2286 2287 Fri Sep 8 21:26:36 BST 2023 2288 2289 We want a fennel thing that reads a filesystem tree into a nested 2290 table. And a thing to diff two tables 2291 2292 Sat Sep 9 22:40:50 BST 2023 2293 2294 Subscribers to odhcp6c outputs need to be able to tell which addresses 2295 are new and which have been removed since the last run, which now we 2296 have ohdcp-script producing parsed data means they need to compare 2297 tables by value. Which is a faff. 2298 2299 What if the directory name were a hash of all the relevant fields 2300 such that clients could just say "new directory, must be new address" 2301 2302 We can have literal prefix, then need to encode 2303 length,preferred,valid,extra space-efficiently. I cannot currently see 2304 any way to use whatever hashing Lua uses for its table lookups, 2305 which is a bit disapppointing, so we might have to make our own 2306 2307 2308 https://gist.github.com/scheler/26a942d34fb5576a68c111b05ac3fabe 2309 this is DJBHash, though doesn't appear to deal with integer overflow 2310 2311 2312 function hash(str) 2313 h = 5381; 2314 2315 for c in str:gmatch"." do 2316 h = ((h << 5) + h) + string.byte(c) 2317 end 2318 return h 2319 end 2320 2321 2322 Mon Sep 11 20:31:25 BST 2023 2323 2324 acquire-lan/wan-foo have no tests, and the test setup is a bit of a 2325 faff as they are both waiting on the filesystem 2326 2327 also, testing lua scripts is a faff without splitting them into 2328 script/module 2329 2330 am wondering if we could do some kind of convention that we only write 2331 modules not scripts but something in the fennel->lua can call the 2332 module's `run` method. 2333 2334 Tuesday 2335 2336 Here is a working shebang for write-fennel: 2337 2338 #!/nix/store/5iwv3h2jjbk2vib2bpwx3g9knpb02x3y-lua-5.3.6/bin/lua -e dofile(arg[0]).run() 2339 2340 Tue Sep 12 20:47:52 BST 2023 2341 2342 We don't handle unbound or stopped states in odhcp consumers. I think 2343 probably we should do this in odhcp-script by deleting the outputs, 2344 rather than making each consumer do it. 2345 2346 ... turns out that odhcp6c itself unsets ADDRESSES and PREFIXES before 2347 calling the script with "unbound", so maybe we don't need to do 2348 anything special. 2349 2350 Wed Sep 13 17:55:33 BST 2023 2351 2352 2353 2354 @400000000000001f2723b3cb eth1.link.pppoe Script /nix/store/nyks8zl86dcp44k5sjcc76digrnfgm17-ip-up finished (pid 403), status = 0x0 2355 @400000000000001f27b2db3b eth1.link.pppoe Script /nix/store/ds0lc4qd1zfiyxsva87rpplyr21awjh1-ip6-up finished (pid 404), status = 0x1 2356 2357 @400000000000001f30a7c5c5 /nix/store/v9ijgyywizqbbd9y73r2wifkxc0d1jjm-route-default-1a22c69d0e1f-up: line 4: input: not found 2358 @400000000000001f31abf9b5 ip: command line is not complete, try "help" 2359 @400000000000001f31ca1395 s6-rc: warning: unable to start service route-default-1a22c69d0e1f: command exited 1 2360 @400000000000001f31f236b4 s6-rc: info: service route-default-d2586cf00da0 successfully started 2361 @ 2362 2363 2364 Wed Sep 13 18:05:38 BST 2023 2365 2366 TODO 2367 2368 - service for dhcp6 client 2369 - move acquire-{wan,lan} scripts out of examples/ 2370 - service for resolvconf 2371 - nftables syntax error 2372 - tidy up the dependency handling in serviceDefn build 2373 (interface is fine, implementation is a bit brutal) 2374 - docs 2375 2376 considerations: 2377 2378 1) in some ways, we should be able to specify acquire-{wan,lan} as if 2379 they were just additional addresses on the respective 2380 interfaces. However, they're longruns so the implementation of 2381 "address" doesn't really fit. 2382 2383 2) should they be bundled into a dhcp client service? I think the 2384 answer is "no" because which of the dhcp config we want to 2385 honour locally (and how) is policy not mechainmsm 2386 2387 svc.dhcp6c.client.build { interface = wan; }; 2388 svc.dhcp6c.address.build { 2389 inherit client; 2390 interface = lan; 2391 }; 2392 svc.dhcp6c.address.build { 2393 inherit client; 2394 interface = wan; 2395 }; 2396 svc.dhcp6c.prefix.build { 2397 inherit client; 2398 interface = lan; 2399 index = 1; # default to first interface 2400 }; 2401 svc.dhcp6c.prefix.build { 2402 inherit client; 2403 interface = vpn; 2404 index = 2; 2405 }; 2406 2407 2408 2409 Fri Sep 15 12:04:25 BST 2023 2410 2411 Qemu worked example provides dhcp and ssh service 2412 2413 Hardware worked example needs to be plugged into same lan as build 2414 machine if we are going to tftp the image onto it - so it might be 2415 awkward if we run dhcp on it 2416 2417 The device I have lying around is the A 2418 2419 How do we do the actual flash step? Assuming the device is running 2420 stock firmware, from a laptop we can wifi to it and use the web ui to 2421 upgrade 2422 2423 we can't build the hellonet config because it requires tftp 2424 2425 plug in mt300a 2426 put stock firmware on it 2427 2428 Sun Sep 17 00:08:03 BST 2023 2429 2430 I don't think the user manual needs a full justification of why we 2431 have the module/service split. Maybe we should have "decision records" 2432 in the git tree instead 2433 2434 Sun Sep 17 16:44:31 BST 2023 2435 2436 Can we figure out which bits of the old doc are missing from the new 2437 one and just transplant those? Then we can merge it sooner 2438 instead of blocking on writig all the new stuff 2439 2440 Mon Sep 25 16:58:51 BST 2023 2441 2442 jffs2 on mt300a isn't finding root partition in initramfs, and it 2443 seems to be because MTD_SPLIT_UIMAGE_FW isn't working 2444 2445 [ 0.426792] spi spi0.0: force spi mode3 2446 [ 0.431305] spi-nor spi0.0: w25q128 (16384 Kbytes) 2447 [ 0.436322] 5 fixed-partitions partitions found on MTD device spi0.0 2448 [ 0.442875] OF: Bad cell count for /palmbus@10000000/spi@b00/flash@0/partitions 2449 [ 0.450400] OF: Bad cell count for /palmbus@10000000/spi@b00/flash@0/partitions 2450 [ 0.458208] OF: Bad cell count for /palmbus@10000000/spi@b00/flash@0/partitions 2451 [ 0.465751] OF: Bad cell count for /palmbus@10000000/spi@b00/flash@0/partitions 2452 [ 0.473522] Creating 5 MTD partitions on "spi0.0": 2453 [ 0.478466] 0x000000000000-0x000000030000 : "u-boot" 2454 [ 0.484447] 0x000000030000-0x000000040000 : "u-boot-env" 2455 [ 0.490888] 0x000000040000-0x000000050000 : "factory" 2456 [ 0.497110] 0x000000050000-0x000000fd0000 : "firmware" 2457 [ 0.596423] 0x000000ff0000-0x000001000000 : "art" 2458 [ 0.611508] gsw: setting port4 to ephy mode 2459 2460 with squashfs root it's the same but for the extra split partitions: 2461 2462 [ 0.468715] Creating 5 MTD partitions on "spi0.0": 2463 [ 0.473653] 0x000000000000-0x000000030000 : "u-boot" 2464 [ 0.479652] 0x000000030000-0x000000040000 : "u-boot-env" 2465 [ 0.486085] 0x000000040000-0x000000050000 : "factory" 2466 [ 0.492318] 0x000000050000-0x000000fd0000 : "firmware" 2467 [ 0.499304] 2 uimage-fw partitions found on MTD device firmware 2468 [ 0.505457] Creating 2 MTD partitions on "firmware": 2469 [ 0.510543] 0x000000000000-0x000000260000 : "kernel" 2470 [ 0.516616] 0x000000260000-0x000000f80000 : "rootfs" 2471 [ 0.522570] mtd: device 5 (rootfs) set to be root filesystem 2472 [ 0.528565] 0x000000ff0000-0x000001000000 : "art" 2473 2474 turns out this is because the device thinks it has 4k erase block size 2475 because MTD_SPI_NOR_USE_4K_SECTORS was set, and that was causing 2476 mtdsplit to look in the wrong place for a root filesystem 2477 2478 Mon Sep 25 18:50:05 BST 2023 2479 2480 No, that wasn't it. Turned out to be an endianness-dependent check for 2481 JFFS2 magic in mtdsplit. 2482 2483 setenv serverip 10.0.0.1 2484 setenv ipaddr 10.0.0.8 2485 tftp 0xa00000 result/uimage 2486 bootm 0xa00000 2487 2488 Fri Sep 29 20:50:39 BST 2023 2489 2490 setenv bootargs 'liminix mtdparts=phram0:M(rootfs) phram.phram=phram0,0x40411f28,4194304,65536 memmap=4194304$0x40411f28 root=/dev/mtdblock0 console=ttyAMA0,115200 earlycon' 2491 2492 setenv serverip 10.0.0.1 2493 setenv ipaddr 10.0.0.5 2494 setenv bootargs 'liminix console=ttyS0,115200 panic=10 oops=panic earlycon=uart8250,mmio32,0x11002000 root=/dev/mtdblock0' 2495 tftp 0x4007ff28 result/uimage ; tftp 0x40432f28 result/rootfs 2496 bootm 0x4007ff28 2497 2498 setenv bootargs 'liminix console=ttyS0,115200 panic=1 oops=panic earlycon root=/dev/mtdblock0' 2499 2500 md 0x42ff0000 2501 2502 Cannot find regmap for /infracfg@10000000: -524. 2503 2504 # "console=ttyAMA0,38400 panic=10 oops=panic init=/bin/init loglevel=8 root=/dev/mtdblock0 rootfstype=squashfs fw_devlink=off" 2505 2506 2507 40812468: 69726553 203a6c61 41424d41 304c5020 Serial: AMBA PL0 2508 40812478: 55203131 20545241 76697264 3c0a7265 11 UART driver.< 2509 40812488: 61723e33 706f6f6d 61203a73 6165726c 3>ramoops: alrea 2510 40812498: 69207964 6974696e 7a696c61 3c0a6465 dy initialized.< 2511 408124a8: 61723e34 706f6f6d 70203a73 65626f72 4>ramoops: probe 2512 408124b8: 20666f20 66663234 30303030 6d61722e of 42ff0000.ram 2513 408124c8: 73706f6f 69616620 2064656c 68746977 oops failed with 2514 408124d8: 72726520 2d20726f 3c0a3232 61433e33 error -22.<3>Ca 2515 408124e8: 746f6e6e 6e696620 65722064 70616d67 nnot find regmap 2516 408124f8: 726f6620 6e692f20 63617266 31406766 for /infracfg@1 2517 40812508: 30303030 3a303030 32352d20 333c0a34 0000000: -524.<3 2518 40812518: 6e61433e 20746f6e 646e6966 67657220 >Cannot find reg 2519 MT7622> 2520 40812528: 2070616d 20726f66 666e692f 66636172 map for /infracf 2521 40812538: 30314067 30303030 203a3030 3432352d g@10000000: -524 2522 40812548: 3e333c0a 6e6e6143 6620746f 20646e69 .<3>Cannot find 2523 40812558: 6d676572 66207061 2f20726f 72666e69 regmap for /infr 2524 40812568: 67666361 30303140 30303030 2d203a30 acfg@10000000: - 2525 40812578: 0a343235 433e333c 6f6e6e61 69662074 524.<3>Cannot fi 2526 40812588: 7220646e 616d6765 6f662070 702f2072 nd regmap for /p 2527 40812598: 63697265 31406766 32303030 3a303030 ericfg@10002000: 2528 408125a8: 32352d20 313c0a34 616e553e 20656c62 -524.<1>Unable 2529 408125b8: 68206f74 6c646e61 656b2065 6c656e72 to handle kernel 2530 408125c8: 67617020 20676e69 75716572 20747365 paging request 2531 408125d8: 76207461 75747269 61206c61 65726464 at virtual addre 2532 408125e8: 66207373 66666666 66666666 66666666 ss fffffffffffff 2533 408125f8: 0a656666 4d3e313c 61206d65 74726f62 ffe.<1>Mem abort 2534 2535 2536 CONFIG_SERIAL_8250_FSL=y 2537 CONFIG_SERIAL_8250_MT6577=y 2538 CONFIG_SERIAL_8250_NR_UARTS=3 2539 CONFIG_SERIAL_8250_RUNTIME_UARTS=3 2540 CONFIG_SERIAL_DEV_BUS=y 2541 CONFIG_SERIAL_DEV_CTRL_TTYPORT=y 2542 CONFIG_SERIAL_MCTRL_GPIO=y 2543 CONFIG_SERIAL_OF_PLATFORM=y 2544 2545 Mon Oct 2 10:17:04 BST 2023 2546 2547 We have a bootable aarch64 kernel for the Belkin, but it does not 2548 understand the memmap= parameter we're using to protect the 2549 phram image from being used as general memory. 2550 2551 One option is to add a reserved-memory stanza in the device tree, 2552 using u-boot "fdt" command, but we don't know the fdt address in u-boot 2553 because it doesn't have any commands to parse the image and set 2554 variables pointing at the sub-components. (There's iminfo, but it's 2555 onyl human-readable) 2556 2557 Second option is to amend the dtb in the tftpboot module: this 2558 would mean regenerating the uimage 2559 2560 Third option: for tftpboot do we _have_ to use FIT? maybe we could 2561 grab the fdt as a separate tftp transaction 2562 2563 we need to apply kernel patch 9401911f2d9f89035f7acebab16e72d43d1282fb 2564 to avoid using ioremap on sysem ram which is not allowed on arm 2565 2566 2567 Tue Oct 3 14:15:38 BST 2023 2568 2569 Progress on Liminix ARM support. The device I'm starting with is 2570 the Belkin RT3200 (also known as [Linksys E8450](https://openwrt.org/toh/linksys/e8450)) which seems to be a featureful piece of kit, and whioch I snagged for a 2571 very good price on the Bay of E 2572 2573 # Where are we right now? 2574 2575 * we can TFTP boot it to userland 2576 * ethernet works 2577 2578 ## What else needs doing? 2579 2580 * it has dual band wifi with many interesting features. I've built the 2581 2582 * we're only running in RAM, probably need to add some kernel config 2583 to support the flash 2584 * initramfs support is not yet implemented 2585 * the flash is NAND flash and it's quite large compared with the 2586 existing Liminix devices, so we're going to add UBIFS which will 2587 use it better than JFFS2 does 2588 * all this work is on a branch and needs to be cleaned up a lot before 2589 I'm letting it into main 2590 2591 ## What have we found? 2592 2593 There are some significant differences between this and the MIPS 2594 devices (yes, other than an entirely different architecture), mostly 2595 to do with "legacy boot" support or the lack thereof. For example: 2596 2597 * there aren't any options like `MIPS_RAW_APPENDED_DTB` to glom 2598 together a kernel and device tree (FDT), because the bootloader is 2599 expected to be able to provide a FDT following "standards". 2600 U-Boot will do this, provided that we use the newer "FIT" Uimage 2601 format which allows a kernel and DTB and initrd to be combined in 2602 the same container. (Sadly we can't use FIT everywhere because a 2603 lot of MIPS devices use really old forks of U-Boot that don't 2604 understand it) 2605 2606 * for tftpboot, on MIPS we use the `memmap` kernel command line option 2607 to reserve some RAM for the root filesystem. On Arm there's no such 2608 option, so we have to add a 2609 [reserved-memory](https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/reserved-memory/reserved-memory.yaml) 2610 node in the device tree instead. Which means, given that we _only_ 2611 want to do this when tftp booting (the memory is wasted 2612 otherwise), we have to rewrite the device tree in that 2613 scenario. 2614 2615 * then it turns out that phram doesn't (didn't) work anyway, because 2616 it calls ioremap() and [you can't use ioremap on system memory on ARM](https://lwn.net/Articles/409689/). In newer kernels this is 2617 fixed: there is a [conditional](https://github.com/torvalds/linux/blob/master/drivers/mtd/devices/phram.c#L127) here to use whichever of ioremap or 2618 memremap is appropriate for the memory passed to phram, but it looks 2619 non-trivial to backport so I've gone for a [much less sophisticated approach](https://gti.telent.net/dan/liminix/commit/f7cd9c2b6e6c99a228e066b09e3febcf71c63fa1#diff-d8e355f1b2dcde7378ebb40c92cdd2ce3125753c) 2620 2621 * we're using [DSA](https://www.kernel.org/doc/Documentation/networking/dsa/dsa.txt) instead of the OpenWrt [swconfig](https://openwrt.org/docs/techref/swconfig) program. There was actually surprisingly little work needed to adjust to this. 2622 2623 2624 Other than that, it was mostly the usual process of "did the kernel 2625 crash silently, or has it just been unable to open a console device?". 2626 In this regard, *one neat trick*: even though U-Boot on this device 2627 doesn't support pstore, we can use it anyway if we don't do compression. 2628 Enable 2629 2630 ``` 2631 PSTORE = "y"; 2632 PSTORE_RAM = "y"; 2633 PSTORE_CONSOLE = "y"; 2634 PSTORE_DEFLATE_COMPRESS = "n"; 2635 ``` 2636 2637 then boot with `panic=3 oops=panic`, then when it resets use the 2638 U_Boot `md` command to see what happened: 2639 2640 ``` 2641 MT7622> md 0x42ff0000 2642 42ff0000: 43474244 00000000 00000ff4 3d3d3d3d DBGC........==== 2643 42ff0010: 39342e31 36373031 500a442d 63696e61 1.491076-D.Panic 2644 42ff0020: 50203123 31747261 3e363c0a 20505050 #1 Part1.<6>PPP 2645 42ff0030: 20445342 706d6f43 73736572 206e6f69 BSD Compression 2646 [....] 2647 42ff0ca0: 20676e69 73756e75 6b206465 656e7265 ing unused kerne 2648 42ff0cb0: 656d206c 79726f6d 3731203a 0a4b3832 l memory: 1728K. 2649 42ff0cc0: 523e363c 2f206e75 74696e69 20736120 <6>Run /init as 2650 42ff0cd0: 74696e69 6f727020 73736563 3e373c0a init process.<7> 2651 ``` 2652 2653 Wed Oct 4 21:08:44 BST 2023 2654 2655 By randomly including chinks of the openwrt config we have made it 2656 find the mt7915e on the pcie bus. I just don't yet know which bit of 2657 the openwrt config it was. 2658 2659 It doesn't actually work yet though. 5GHz wifi gets calibration data 2660 from the flash, so it is not going to work unless (1) we reflash the 2661 firmware partition, or (2) we find another way to provide it 2662 calibration data. 2663 2664 https://forum.openwrt.org/t/belkin-rt3200-linksys-e8450-wifi-ax-discussion/94302/401 2665 2666 Sat Oct 7 22:56:40 BST 2023 2667 2668 We're almost ready to merge the rt3200 support (it's not finished 2669 but it mostly won't break mips) except for the uimage module 2670 which needs all that FIT stuff, and the tftpboot contortions 2671 to amend the dtb for memmap 2672 2673 For legacy uimage 2674 2675 1) add commandline params to dtb 2676 2) objcopy fdt into vmlinux.elf 2677 3) strip to raw image and compress 2678 4) mkimage 2679 2680 2681 For FIT uimage 2682 2683 1) add commandline params to dtb 2684 2) strip to raw image and compress 2685 3) create its file 2686 4) mkimage 2687 2688 Do we still want to handle the no-dtb case? what about 2689 standards-compliant boot, where u-boot is providing the dtb? No option 2690 to provide a commandline in that case, but maybe also no need to. 2691 2692 For tftpboot, am undecided. We could use the dtb rewriting thing 2693 everywhere, in the interest of consistency. 2694 2695 Mon Oct 9 20:45:54 BST 2023 2696 2697 we bumped the kernel entry point to the 32MB mark, as 2698 2699 (1) when using jffs2 (big rootfs image) it was clobbering the dtb at 2700 the end of the filesystem 2701 2702 (2) it should be 2MB aligned anyway and wasn't 2703 2704 However, this has given us the next problem: 2705 2706 OF: fdt: Reserved memory: failed to reserve memory for node 'secmon@43000000': base 0x00000000430B 2707 OF: reserved mem: OVERLAP DETECTED! 2708 phram-rootfs (0x0000000040400000--0x0000000053a31488) overlaps with ramoops@42ff0000 (0x000000004) 2709 Zone ranges: 2710 DMA [mem 0x0000000040000000-0x000000005fffffff] 2711 DMA32 empty 2712 Normal empty 2713 Movable zone start for each node 2714 2715 the end of that phram-rootfs region looks well sus. 2716 2717 [ turns out that decimal is not hex ] 2718 2719 Tue Oct 10 21:37:31 BST 2023 2720 2721 UBI bleurgh ... 2722 2723 The DTB for this device, and/or the OpenWrt installer, seems to 2724 expect already that mtd4 is a UBI thing 2725 2726 mtdinfo -a says: 2727 mtd4 2728 Name: ubi 2729 Type: nand 2730 Eraseblock size: 131072 bytes, 128.0 KiB 2731 Amount of eraseblocks: 1000 (131072000 bytes, 125.0 MiB) 2732 Minimum input/output unit size: 2048 bytes 2733 Sub-page size: 2048 bytes 2734 OOB size: 64 bytes 2735 Character device major/minor: 90:8 2736 Bad blocks are allowed: true 2737 Device is writable: true 2738 2739 <5>UBI: auto-attach mtd4 2740 <5>ubi0: attaching mtd4 2741 <5>ubi0: scanning is finished 2742 <5>ubi0: attached mtd4 (name "ubi", size 125 MiB) 2743 <5>ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes 2744 <5>ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 2048 2745 2746 we made a volume using "ubimkvol /dev/ubi0 -N liminix -S 825" 2747 2748 and from ubinfo -a we can see 2749 2750 0 ubootenv 2751 1 ubootenv2 2752 2 recovery 2753 3 boot_backup 2754 4 liminix 2755 2756 Now we could use "ubiupdatevol /dev/ubi0_4 /path/to/ubifs.img" 2757 to put a ubifs on that volume, but obviously we'd have to boot the 2758 device into Liminix somehow first. 2759 2760 Alternatively in the build environment we could use ubinize to 2761 create the entire image that can be flashed to MTD, but 2762 2763 - this will overwrite erase counters. 2764 - we have to give it a config file that describes all the volumes, 2765 and I'm guessing they need to match up with the existing ones 2766 otherwise we trash the uboot env 2767 2768 2769 Wed Oct 11 17:37:09 BST 2023 2770 2771 We can write ubi volumes from u-boot. Let's for the moment use 2772 mkfs.ubifs and tftp those files to u-boot - we can figure out the 2773 ubinize dance later 2774 2775 We need either 2776 2777 (a) to write an analogue of our jffs2 graft option for mkfs.ubifs, or 2778 (b) to have a "cpio-like" mkfs.ubifs variant that reads filenames on stdin 2779 and writes only those, or 2780 (c) to create a "staging" directory during build with all the store folders that need to go into the filesystem 2781 2782 although the least elegant, option (c) is the simplest and probably 2783 not even slow, at least by comparison with unpacking the kernel source 2784 tarball 2785 2786 we used 2787 uboot> tftpboot 0x40400000 result/rootfs 2788 uboot> ubi write 40400000 liminix $filesize 2789 2790 then can use ubifsmount ubi0:liminix ; ubifsls / to check that it wrote 2791 something valid. To boot this: 2792 2793 setenv serverip 10.0.0.1 2794 setenv ipaddr 10.0.0.8 2795 setenv bootargs 'liminix console=ttyS0,115200 panic=10 oops=panic init=/bin/init loglevel=8 root=ubi0:liminix rootfstype=ubifs fw_devlink=off' 2796 tftpboot 0x4007ff28 result/uimage 2797 bootm 0x4007ff28 2798 2799 The other thing we had to fix here is that activate wasn't being built 2800 statically. Have to add -Xlinker -static to CFLAGS - I don't know if 2801 this is a no-op on MIPS 2802 2803 Mon Oct 16 20:51:08 BST 2023 2804 2805 Here's a thing: the u-boot installed by openwrt on this device has a 2806 ubifsload command, and it has a writable ubootenv. So instead of 2807 having a separate partition for the kernel we could put the kernel in 2808 the actual filesystem 2809 2810 I think we should do this by excluding flashimage and including some 2811 other module (to be written) instead. ubimage or somesuch, perhaps. 2812 2813 So the image we wish to create is a ubifs with a kernel inside it in 2814 /boot and we also need to change the u-boot env value of 2815 2816 boot_production=led $bootled_pwr on ; run ubi_read_production && bootm $loadaddr#$bootconf ; led $bootled_pwr off 2817 2818 so that it mounts the rootfs and finds /boot/uimage inside it 2819 2820 From uboot this is setenv and saveenv; from a running linux this is fw_setenv 2821 2822 Thu Oct 19 09:34:15 BST 2023 2823 2824 setenv bootargs 'liminix console=ttyS0,115200 panic=10 oops=panic init=/bin/init loglevel=8 root=ubi0:liminix rootfstype=ubifs fw_devlink=off' 2825 2826 2827 ubifsmount ubi0:liminix 2828 ubifsload 4007ff28 boot/uimage 2829 bootm 0x4007ff28 2830 2831 2832 Thu Oct 19 23:11:17 BST 2023 2833 2834 Assuming you've done the openwrt installer to repartion the device, 2835 what are the steps to install Liminix? 2836 2837 1) build rootfs, which incorporates kernel 2838 2839 2) from u-boot: 2840 2841 uboot> ubimkvol /dev/ubi0 -N liminix -S 825 2842 uboot> tftpboot 0x40400000 result/rootfs 2843 uboot> ubi write 40400000 liminix $filesize 2844 uboot> setenv boot_production 'led $bootled_pwr on ; ubifsmount ubi0:liminix; ubifsload 4007ff28 boot/uimage; bootm 4007ff28' 2845 2846 What if we don't have a serial console? can we do all this from openwrt? 2847 2848 Fri Oct 27 23:21:08 BST 2023 2849 2850 setenv serverip 10.0.0.1 2851 setenv ipaddr 10.0.0.8 2852 setenv bootargs 'liminix earlyprintk earlycon=uart8250,mmio32,0xf1012000 ramoops.mem_address=0x8000000 ramoops.mem_size=0x40000 ramoops=max_reason=2 mem=128M earlycon=ttyS0 console=ttyS0,115200 panic=10 oops=panic init=/bin/init loglevel=8 root=ubi0:liminix rootfstype=ubifs fw_devlink=off' 2853 setenv bootargs 'liminix ramoops.mem_address=0x8000000 ramoops.mem_size=0x40000 ramoops=max_reason=2 mem=128M console=ttyS0,115200 panic=10 oops=panic init=/bin/init loglevel=8 root=ubi0:liminix rootfstype=ubifs fw_devlink=off' 2854 tftpboot ${kernel_addr_r} result 2855 bootm ${kernel_addr_r} 2856 2857 2858 --- 2859 this is potentially worth checkng out because we do have very slow 2860 decompress speed 2861 2862 https://scm.linefinity.com/common/u-boot/commit/5818198e6a184963c6afc82178b23a64435ace6a 2863 2864 Commit 5bb2c550b1 ("arm: mvebu: Move internal registers in 2865 arch_very_early_init() function") implemented code movement according to 2866 (now incomplete) comments which resulted in semi-broken code. 2867 2868 The result is that I-cache is currently disabled for all Armada 38x boards 2869 and maybe there are some other (unreported / undetected) issues. 2870 2871 [...] After this change lzmadec command with lzma image of 0x7000000 bytes is 2872 doing decompression just 5 seconds. Before this change it was 30 seconds. 2873 2874 2875 Mon Oct 30 21:03:55 GMT 2023 2876 2877 We have a kernel that boots on the Omnia, now we need to build a 2878 rootfs. Given this device uses mmc for its primary storage, we should 2879 use a block filesystem not a flash filesystem. 2880 2881 2882 setenv serverip 10.0.0.1 2883 setenv ipaddr 10.0.0.8 2884 setenv bootargs 'liminix console=ttyS0,115200 panic=10 oops=panic init=/bin/init loglevel=8 root=/dev/mtdblock0 rootfstype=ext4fs fw_devlink=off mtdparts=phram0:22M(rootfs) phram.phram=phram0,0x1300000,23068672,65536 root=/dev/mtdblock0' 2885 tftpboot 0x1000000 tftpboot/uimage ; tftpboot 0x1300000 tftpboot/dtb ; tftpboot 0x29b0000 tftpboot/dtb; tftpboot 0x29c0000 initrd.img 2886 2887 2888 Sat Nov 4 12:22:37 GMT 2023 2889 2890 setenv serverip 10.0.0.1 2891 setenv ipaddr 10.0.0.8 2892 setenv bootargs 'liminix console=ttyS0,115200 panic=10 oops=panic init=/bin/init loglevel=8 root=/dev/mtdblock0 rootfstype=ext4 fw_devlink=off mtdparts=phram0:22M(rootfs) phram.phram=phram0,0x40300000,23068672,65536 root=/dev/mtdblock0' 2893 tftpboot 0x40000800 tftpboot/uimage ; tftpboot 0x419b0800 tftpboot/dtb ; tftpboot 0x41a00000 initrd.img ; tftpboot 0x40300000 tftpboot/rootfs 2894 bootm 0x40000800 0x41a00000 0x419b0800 2895 2896 kernel 0x40000800 + 2af400 = "402afc00" 2897 rootfs 0x40300000 + 15f9400 = "418f9400" 2898 dtb 0x419b0800 + 4e00 = "419b5600" 2899 2900 Sun Nov 5 00:01:56 GMT 2023 2901 2902 Open questions 2903 2904 1) using -device loader for qemu phram, how do we choose appropriate 2905 start address for all architectures? we could try to unify this 2906 with the tftpboot approach, but that would mean providing the dtb 2907 ourselves somehow which seems silly when qemu already does it 2908 2909 2) flash erase block size for tftpboot phram, it need to match the hardware 2910 - we don't use it at all for squashfs 2911 - for jffs2 it needs to match if tftpboot is to use same rootfs image 2912 as flash 2913 - we don't have any way to do a tftpboot ubifs 2914 - ext4 doesn't care 2915 2916 3) the rootfstype needs thought. 2917 2918 - for all but squashfs it implies an initramfs 2919 - jffs2 can be flashed naively 2920 - ubifs needs an installer to not clobber erase counts 2921 - ext4 (for omnia) needs a block device and can't be flashed along 2922 with the kernel/initramfs because it's a separate disk. or maybe 2923 the omnia can load kernel from mmc? 2924 2925 phram plus mtd_block is ok for ext4 for qemu, so that's one thing 2926 fewer to deal with 2927 2928 4) for tftpboot with a separate initramfs, is there any way to 2929 make address selection easier? 2930 2931 5) ubifs needs a different set of flash parameters (PEB, LEB etc) 2932 2933 Tue Nov 7 23:19:10 GMT 2023 2934 2935 We can flash the turris omnia from a USB stick 2936 https://docs.turris.cz/hw/omnia/rescue-modes/ 2937 2938 it looks for omnia-medkit-latest.tar.gz and (I'm guessing) just 2939 unpacks it onto the emmc. 2940 2941 Perhaps we need per-device installation instructions in the docs. 2942 2943 * rename defaultOutput to installerOutput 2944 * attach some docs to the various options for installerOutput 2945 * add a link from the device's rendered manual section to the 2946 relevant installer output doc 2947 2948 do we expect that outputs will build on each other? e.g. 2949 turris omnia output is basically a tarball (other devices 2950 might want this too) but with docs describing how to reset the 2951 device and hold the button down until the led flashes four times 2952 (other devices probably won't want this). maybe the model here 2953 is that the turris output is a directory with a symlink to the 2954 tarball and an informative README containing the instructions. 2955 Although we also want the instructions in the manual where people 2956 can read them before building anything. 2957 2958 Fri Nov 10 21:27:50 GMT 2023 2959 2960 Realising now that outputs and installers aren't the same thing. 2961 2962 e.g. flashimage can be installed from u-boot or from kexecboot 2963 2964 perhaps we distinguish between the 2965 2966 "installation image": 2967 - firmware.bin 2968 - tarball 2969 - ubifs image 2970 - kernel + rootfs 2971 2972 and "installer" 2973 - kexecboot script 2974 - u-boot script to flash squashfs image 2975 2976 Sun Nov 12 17:17:30 GMT 2023 2977 2978 What TODO? 2979 2980 - "does the kernel live on the filesystem" depends on the bootloader 2981 not the filesystem 2982 - could we implement this with a module that adds to config.filesystem ? 2983 it would depend on whether the bootloader can follow symlinks to 2984 files not in /boot (probably fine unless crossing filesystems) 2985 - the other question is how much futzing around in u-boot can/do we do 2986 to tell u-boot how to boot? for grown-up u-boot it's not a 2987 problem as we can saveenv but are there broken u-boots that would 2988 prevent this? 2989 2990 - kexecboot is unloved and documented in the wrong place. do we have a 2991 test for it even? 2992 - it won't work on aarch64 because it needs memmap= 2993 - hardcodes memory size, which we should probably work out dynamically 2994 2995 - how to put device name into the device docs 2996 maybe devices 2997 2998 - make config.boot.commandLine a single string 2999 - finish omnia 3000 - for installation on turris omnia we need tarball not ext4 image 3001 (but keep the ext4 image anyway for tftpboot and possibly kexecboot) 3002 [done] - now we have lim.parseInt should we use it consistently? 3003 - usefulness tiers for devices ("stable", "experimental", "wip") 3004 - params for ubi(fs) are a mess 3005 - create an l2tp configuration 3006 - iperf and tuning 3007 - wlan country code 3008 3009 3010 Fri Nov 17 17:30:39 GMT 2023 3011 3012 kexec is fraught. I spent some time trying (unsuccesfully) to get a 3013 kexecboot test running, but it doesn't work in qemu for the reason 3014 that the kernel I built for qemu has SMP support but does not have 3015 kexec_nonboot_cpu_func() - which is the needed function to stop 3016 non-boot CPUs before jumping into the new kernel. That this code is 3017 all MIPS-specific (I have to assume that other architectures have 3018 entirely different ways to stop non-boot CPUs?) is a bit worrisome: how 3019 many other ways is kexec hardware-dependent? 3020 3021 We have two scenarios where we may want to use it: 3022 3023 1) the "installer": e.g. for UBI platforms, we want to plonk 3024 a new ubifs on the device without clobbering the erase counters, which 3025 means either doing it from U-Boot - needs serial connection - 3026 or doing it from a Linux of some kind that is not running on the 3027 filesystem we're toasting. 3028 3029 2) reinstalling after the initial install - this is a big deal for 3030 squashfs where there is no other way to change data, and an only slightly 3031 smaller deal for jffs2, where there isn't much room to change much 3032 data. 3033 3034 Maybe instead of kexec we could do this by stopping services and then 3035 pivot_root into a ramfs. We would, I assume, need to stop any processes 3036 that have open files on the root fs, but we would need to have network 3037 interfaces running. So we need a subset of services that run in recovery: 3038 can make this a bundle 3039 3040 * mount a ramfs 3041 * copy the closure of the bundle into the ramfs 3042 * stop all processes (including init?) 3043 3044 sending pid 1 a signal FOO will cause it to run .s6-svscan/SIGFOO 3045 3046 Fri Nov 17 23:53:43 GMT 2023 3047 3048 So we need to extend .s6-svscan/finish to 3049 3050 if test -e /maintenance/bin/init 3051 cd /maintenance 3052 mount --bind /maintenance/ / 3053 chroot . 3054 exec /bin/init -D maintenance 3055 fi 3056 3057 3058 foreground { 3059 if { test -e /maintenance/bin/init } 3060 cd /maintenance 3061 foreground { mount --move /maintenance/ / } 3062 foreground { chroot . } 3063 redirfd -r 0 /dev/console 3064 redirfd -w 1 /dev/console 3065 fdmove -c 2 1 3066 emptyenv /bin/init -D maintenance 3067 } 3068 ${s6-linux-init}/bin/s6-linux-init-hpr -fr 3069 3070 3071 https://openwrt.org/docs/techref/sysupgrade 3072 3073 s6-svscanctl -t /run/service 3074 3075 Sun Nov 19 10:23:17 GMT 2023 3076 3077 # cat `type -p reboot` 3078 #!/nix/store/0v3q2lnh7bwg0ldk24lzmsdnmidmdvm6-execline-mips-unknown-linux-musl-2.9.3.0-bin/bin/execlineb -S0 3079 /nix/store/j41b85ccx0rmf7lm5g13zqb7fs68l8y2-s6-linux-init-mips-unknown-linux-musl-1.1.1.0-bin/bin/s6-linux-init-hpr -r \$@ 3080 3081 3082 s6-linux-init-hpr calls hpr_send("", 0) 3083 then 3084 hpr_shutdown(what, &tain_zero, 0)) 3085 which sends "Shpr"[what] to SCANDIRFULL "/" SHUTDOWND_SERVICEDIR "/" SHUTDOWND_FIFO 3086 3087 which I assume is s6-linux-init-shutdownd.c 3088 3089 it calls prepare_shutdown on socket read, which sets deadline, grace_time. 3090 later (when?) it calls 3091 3092 run_stage3(basedir) ; # we can see this by adding a message to rc.shutdown 3093 # this causes s6-rc services to be downed gently 3094 s6-rc -v2 -bDa change 3095 3096 prepare_stage4(basedir, what) 3097 3098 creates a file STAGE4_FILE with the contents: 3099 s6-linux-init-umountall 3100 scripts/rc.shutdown.final 3101 s6-linux-init-hpr -f -r 3102 3103 unsupervise_tree() ; 3104 3105 goes through /run/service/*/supervise/control fifos 3106 except shutdownd and logger, sending 3107 "d" to each 3108 3109 then does 3110 s6_svc_write(SCANDIRFULL "/" S6_SVSCAN_CTLDIR "/control", "an", 2) 3111 (this is a rescan not a terminate) 3112 3113 #define SCANDIRFULL S6_LINUX_INIT_TMPFS "/" S6_LINUX_INIT_SCANDIR 3114 (works out to be /run/service "/" ".s6-svscan") 3115 3116 ls 3117 kill(-1, SIGTERM) ; 3118 3119 s6-rc -v2 -bDa change 3120 cd /run/service 3121 for i in s6-linux-init-runleveld s6rc-oneshot-runner s6rc-fdholder eth* getty ; do s6-svc -d /run/service/$i; done 3122 3123 3124 s6-rc -v2 -bDa change 3125 cd /run/service 3126 for i in s6-linux-init-runleveld s6rc-oneshot-runner s6rc-fdholder eth* ; do s6-svc -d /run/service/$i; done 3127 s6-svscanctl -an /run/service 3128 3129 Wed Nov 22 22:01:02 GMT 2023 3130 3131 - define a subset of services that run in maintenance mode. 3132 - write a command that copies the closure of this bundle into 3133 /run/maintenance 3134 - create enough non-store filesystem (proc dev etc) to make it run 3135 3136 Thu Nov 23 00:09:44 GMT 2023 3137 3138 I was as surprised as anybody that this seems to work, at least 3139 insofar as it has started a busybox sh process. there is a serious 3140 deficit of symlinks to busybox, so almost no shell scripts work. and I 3141 think we need an rc.init 3142 3143 It would be worth tidying up the main s6 run-image quite a lot before 3144 we go further with this 3145 3146 We'd like to be able to reuse the s6 pseudofile structure (/etc/s6-rc 3147 and /etc/s6-linux-init) but we can't make it a derivation because it's 3148 pseudofiles (with funny permissions) not real files. Maybe we can 3149 invoke the module as a function? 3150 3151 Fri Nov 24 23:29:48 GMT 2023 3152 3153 Turris TODO 3154 3155 - see if network works (eth[012], which is which?) 3156 - wireless drivers 3157 [DONE] ath9k and ath10k, it's like old times 3158 https://docs.turris.cz/hw/omnia/omnia/#turris-omnia-wi-fi-6 3159 (note: other variant of the device has a MT7915AN, should we add 3160 support for that as well?) 3161 3162 - [DONE] feed the watchdog 3163 it looks like compiling watchdog support is sufficient to stop the 3164 thing from rebooting after three minutes, there is no need to actually 3165 feed it from userspace. 3166 3167 - "does the kernel live on the filesystem" depends on the bootloader 3168 not the filesystem 3169 - could we implement this with a module that adds to config.filesystem ? 3170 it would depend on whether the bootloader can follow symlinks to 3171 files not in /boot (probably fine unless crossing filesystems) 3172 - the other question is how much futzing around in u-boot can/do we do 3173 to tell u-boot how to boot? for grown-up u-boot it's not a 3174 problem as we can saveenv but are there broken u-boots that would 3175 prevent this? 3176 - perhaps we need different boot "recipes" - e.g. some device 3177 might want boot.scr and another something different 3178 3179 - create installable tarball and test 3180 - gpio thingy for SFP switching 3181 - iperf 3182 3183 - document the watchdog 3184 - remove kexecboot? it's unloved and documented in the wrong place. do we have a 3185 test for it even? 3186 - it won't work on aarch64 because it needs memmap= 3187 - hardcodes memory size, which we should probably work out dynamically 3188 3189 - how to put device name into the device docs 3190 3191 - [WONT] make config.boot.commandLine a single string 3192 this sounds sensible but it just makes it harder to put useful comments 3193 against command line fragments so that we know why they're there 3194 3195 - usefulness tiers for devices ("stable", "experimental", "wip") 3196 - params for ubi(fs) are a mess 3197 - iperf and tuning 3198 - wlan country code 3199 - create an l2tp configuration 3200 3201 Sun Nov 26 15:37:07 GMT 2023 3202 3203 hatching a plan ... we could do "predictable" network interfaces like this: 3204 3205 . add a devpath attr to network/link.nix 3206 . get the kernel-issued name from "/sys${devpath}/net" 3207 . use ip link set ${oldname} name ${newname} 3208 3209 if we had the full iproute2 thng we could keep the old name as well: 3210 # ip link property add dev wan altname eth1 3211 3212 maybe we could do this with lua/netlink? no support in there currently 3213 for RTM_NEWLINKPROP though 3214 3215 Maybe we'll skip doing the altname. The attraction of it is that it 3216 means the existing name isn't removed, so there's no possibility of a 3217 race. 3218 3219 The kernel will allocate eth0 when asked for eth%d and there is no 3220 eth0. This might be the case where eth0 previously existed but it 3221 just got renamed to lan 3222 3223 Sun Nov 26 21:20:23 GMT 2023 3224 3225 The wrinkle here is ifwait: using netlink we can't wait for an 3226 interface by devpath but have to do it by name - which is a problem if 3227 the interface is not yet present, because there won't be a devpath 3228 in which to look up the name until it is. 3229 3230 So we need a new flow 3231 3232 - wait for devpath to exist 3233 - get the ifindex (which shouldn't change, even if the name does) 3234 - churn rtnetlink messages for that index 3235 3236 We don't want to poll the sysfs file, but we can check it whenever 3237 we get a netlink message 3238 3239 Sun Nov 26 22:33:16 GMT 2023 3240 3241 There is no way to refer to the hardware device for a bridge interface 3242 by sysfs path because it has none. This is probably true of other 3243 virtual devices as well. 3244 3245 ls: cannot access '/sys/class/net/vbridge0/device': No such file or directory 3246 3247 Also, there is no way to refer to the _netdevice_ of a hardware 3248 interface without also knowing its default name, which doesn't help us 3249 if enumeration changes 3250 3251 ls /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/net/ 3252 enp1s0 3253 3254 So we should only be specifying devices by devpath if they're 3255 hardware devices discovered by the kernel, not synthetic devices (that 3256 we pick the name of anyway). 3257 3258 So maybe we don't need to rewrite ifwait, we just do it after renaming 3259 the device 3260 3261 Wed Nov 29 21:28:37 GMT 2023 3262 3263 How do we name outputs? 3264 3265 fileystem image 3266 with-boot filesystem image (e.g. ubifs for belkin) 3267 tarball 3268 with-boot tarball (e.g. omnia) 3269 flashable combined image of kernel + filesystem (e.g. gl-mt*) 3270 kernel + filesystem image + dtb + tftpboot glue 3271 kernel + filesystem image + qemu script 3272 3273 we could add initramfs as a separate thing for tftpboot and qemu 3274 (and FIT images) but it would mean not sharing a kernel with 3275 the outputs that require embedded initramfs 3276 3277 we can enable with-boot variants of outputs by adding a 3278 boot.loader config option. if we go that route, can we 3279 use config options to drive the whole output thingy? 3280 We could have a config option that just changes "defaultOutput" 3281 but is that useful? 3282 3283 Maybe the question is: we can choose a different output at build time 3284 rather than editing configuration - how often is this useful? I think 3285 tftpboot vs installable is about the only case. 3286 3287 adding a /boot to a filesystem differs from making a combined 3288 flashable image because it is a config change and not a composition 3289 of two other already-built outputs. 3290 3291 we could have done tftpboot that way as well, but we chose to unpack 3292 and repack the fdt so we don't have to build two kernels - and also so 3293 that we can have both outputs from the same configuration without 3294 editing any files. 3295 3296 for tftpboot we don't want to make the filesystem embed the kernel 3297 if we need a separate kernel for booting (guessing we can't usually make 3298 u-boot loopback mount a downloaded filesystem image). so that points to 3299 not making it a config option, _or_ to making the inclusion logic 3300 (hardware wants a kernel in filesystem) && !(output == tftpboot) 3301 which itself means the output somehow needs to be injected into the 3302 config 3303 3304 nix-build -I liminix-config=./examples/hello-from-mt300.nix --arg device "import ./devices/my-device" --arg output=tftpboot 3305 3306 let's see if we can not do that? 3307 3308 repacking a ubifs to add /boot is awkward and unpleasant 3309 3310 Thu Nov 30 14:33:08 GMT 2023 3311 3312 ~~We need a new boot-in-rootfs output which calls rootfs with 3313 (config.filesystem // { /boot ... }) when the device 3314 boot type is extlinux~~ 3315 3316 ~~Do we need to put it in systemConfiguration as well? Yes, 3317 otherwise liminix-rebuild won't install it~~ 3318 3319 We may have a problem here actually: if /boot is only set up after 3320 reboot, by adding a link while running the initramfs, how did the 3321 bootloader find the kernel to boot in the first place? So 3322 we need /boot to exist and to point to the new kernel before rebooting 3323 into it, so we need to create it as a real directory along with /nix/store 3324 when making the filesystem, 3325 instead of relying on activate which will be too late. 3326 3327 maybe we could extract the root directory structure creation 3328 as a separate output from rootfs, then there is a single place 3329 to put "and also add /boot" 3330 3331 we will need to update pkgs/min-copy-closure/liminix-rebuild.sh 3332 to add /boot 3333 3334 we could make the contents of /boot a derivation and then 3335 /boot itself is just a symlink to it. we would need to ensure that 3336 the derivation is part of the system closure, though 3337 3338 Sat Dec 2 15:33:07 GMT 2023 3339 3340 - make rootfs the directory structure 3341 3342 Sun Dec 3 23:31:35 GMT 2023 3343 3344 Spent too much of the weekend first fighting run-liminix-vm.sh and 3345 then rewriting it in Fennel, but we are now at the point that we can 3346 boot u-boot in qemu. However, it maps the rootfs into high memory 3347 where phram can find it, instead of putting it into a flash that 3348 _qemu_ can see as flash, so u-boot is not able to boot the kernel or 3349 at least not in a similar-to-hardware fashion. Once we've added that, 3350 we need to write a test for boots-a-kernel-in-the-filesystem 3351 3352 Mon Dec 4 19:46:58 GMT 2023 3353 3354 We wanted a test that we are creating an image that u-boot can boot 3355 using extlinux. Turns out that u-boot only has scripts to do this in 3356 the case that the storage device has a partition table. Which is 3357 representative of the Omnia mmc, but maybe not going to work for 3358 jffs2/ubifs 3359 3360 (For ubifs it might be OK, there's some concept of partitions 3361 3362 ubifs_boot=if ubi part ${bootubipart} ${bootubioff} && ubifsmount ubi0:${bootubivol}; then devtype=ubi; devnum=ubi0; bootfstype=ubifs; distro_bootpart=${bootubivol}; run scan_dev_for_boot; ubifsumount; fi 3363 3364 ) 3365 3366 So what do we need? a disk image with a partition table and an ext4fs 3367 image in the only partition, and that partition to be bootable. Then 3368 run-liminix-vm gets a --disk-image option which causes it to use 3369 U-Boot instead of direct load (can we wrap it with something that sets 3370 up the paths so it can find u-boot and qemu?) 3371 3372 ok, we're going to define outputs.diskimage which is like 3373 outputs.flashimage but it has a partition table. Then we can make a 3374 qemu configuration with an ext4 filesystem and defaultOutput="diskimage" 3375 and config.boot.loader.extlinux.enable = true 3376 3377 sfdisk default behaviour for GPT partitioned disk is to start at sector 2048 3378 (sectors are 512 bytes) 3379 3380 Device Start End Sectors Size Type 3381 disk.bin1 2048 14335 12288 6M Linux filesystem 3382 3383 Tue Dec 5 23:54:22 GMT 2023 3384 3385 Need mbr not gpt. At least, it takes up less space and it doesn't 3386 inveigle us into EFI boot. 3387 3388 This is close to working except that it doesn't want to boot a uimage 3389 3390 Enter choice: 1 3391 1: Liminix 3392 Retrieving file: /boot/initramfs 3393 Retrieving file: /boot/kernel.gz 3394 append: console=ttyAMA0 panic=10 oops=panic init=/bin/init loglevel=8 root=/dev/mtdblock0 rootfstype=ext4 fw_devlink=off 3395 zimage: Bad magic! 3396 3397 Thu Dec 7 19:33:02 GMT 2023 3398 3399 virtio devices don't have standard major/minor so we can't create 3400 device nodes for them at build time. Either we mount devtmpfs in the 3401 initramfs (do we then have to move it to /target?) or we parse the 3402 /sys/block/vda/vda1/dev node to get 253:1 or whatever 3403 3404 Fri Dec 8 16:36:07 GMT 2023 3405 3406 We'd like to remove the ugly special handling of qemu dtb. Here are 3407 some thoughts 3408 3409 1) qemu provides its guest the correct DTB for the configured hardware. 3410 This is a desirable thing and we wish more platforms did it, so would 3411 like not to replace it with a static dtb if we can avoid that 3412 3413 2) so we need some kind of config option that says "platform provides the 3414 device tree" (or alternatively, "we need a static dtb, platform doesn't 3415 provide it"). 3416 3417 config.boot.platformProvidesDeviceTree 3418 3419 3420 3421 Monday 3422 3423 so where are we? we've removed the need for every hardware device to 3424 be able to build flashimage, because not every hw device (looking at you, 3425 bellkin/turris) works like that. 3426 3427 for the belkin we can have imports = [ modules/outputs/ubimage ] 3428 and extlinux enabled 3429 3430 for the nwa from Raito we'd like to have imports = [ modules/outputs/ubimage ] 3431 but the bootloader is mtd partition-based (or ubi volume? check?) - 3432 so ubimage needs to know how to do that 3433 3434 perhaps we need an output for "smash together a kernel and a 3435 filesystem image that does not also contain a kernel, and don't 3436 put a partition table on the front" 3437 3438 diskimage { 3439 partitionType = "mtd" ; # or "mbr" or maybe "gpt" 3440 partitions = [ o.uimage o.rootfs ]; 3441 } 3442 3443 3444 3445 3446 for the turris we need to check but proceeding on the assumption 3447 it wants a tarball with extlinux enabled 3448 3449 https://docs.turris.cz/geek/schnapps/schnapps/#export-and-import 3450 https://wiki.turris.cz/en/howto/omnia_booting_from_external_storage 3451 3452 if we adopt this as our installation format then we are not 3453 reformatting the flash and will keep the btrfs that the device 3454 was shipped with. 3455 3456 https://forum.turris.cz/t/update-to-5-1-x-by-medkit/13986/12 3457 suggests that we could install a custom medkit from the 3458 vendor OS 3459 3460 => btrsubvol mmc 0:1 3461 ID 257 parent 5 name /@ 3462 ID 259 parent 5 name /@factory 3463 3464 there don't seem to be any other btr commands in u-boot 3465 3466 Tue Dec 12 14:38:53 GMT 2023 3467 3468 from the source code, to get to the various omnia revovery modes 3469 3470 uboot> setenv omnia_reset 3 # or 1..n 3471 uboot> setenv boot_targets rescue 3472 uboot> boot 3473 3474 // reset boot_targets to default value. 3475 3476 Tue Dec 12 22:44:34 GMT 2023 3477 3478 The hold-down-reset-until-n-leds-flash support depends quite heavily 3479 on the post-boot Linux environment, in that it appears to be passing 3480 omniarescue=3 rescue_mode=3 to the kernel command line -> pid 1 3481 cmdline 3482 3483 On the other hand, it is described as being able to boot from usb 3484 stick if there's a boot.scr on the usb stick, so maybe we just do 3485 that. The installation process could then be "boot usb, dd the 3486 disk image to mmc, reboot, remove usb, realise we got the wrong root=". 3487 Hmm. 3488 3489 * Could we edit extlinux.conf for first boot? But bear in mind it's a 3490 link to a store file. 3491 3492 * Could we have extlinux.conf point at mmc0 and somehow override it for the 3493 usb stick boot? 3494 3495 * Could preinit try multiple root mounts until it gets one that works? 3496 3497 * maybe we could detect omniarescue on kernel command line and switch to 3498 usb root? 3499 3500 * maybe outputs.usbstick could generate a customised rootfs image? 3501 it might be unworkable to 3502 3503 (narrator: it boots from mmc0 first and usb stick second, so that's not 3504 particularly useful) 3505 3506 3507 3508 3509 Device 0: Vendor: SanDisk Rev: 1.00 Prod: Cruzer Blade 3510 Type: Removable Hard Disk 3511 Capacity: 7632.0 MB = 7.4 GB (15630336 x 512) 3512 ... is now current device 3513 Scanning usb 0:1... 3514 No EFI system partition 3515 fdt_find_or_add_subnode: chosen: FDT_ERR_BADSTRUCTURE 3516 ERROR: /chosen node create failed 3517 - must RESET the board to recover. 3518 3519 Thu Dec 14 15:32:39 GMT 2023 3520 3521 from the omnia rescue image, we have 3522 3523 ## Loading kernel from FIT Image at 01700000 ... 3524 3525 Load Address: 0x00800000 3526 Entry Point: 0x00800000 3527 3528 3529 int lzmaBuffToBuffDecompress(unsigned char *outStream, SizeT *uncompressedSize, 3530 const unsigned char *inStream, SizeT length) 3531 3532 err = image_decomp(os.comp, load, os.image_start, os.type, 3533 load_buf, image_buf, image_len, 3534 CONFIG_SYS_BOOTM_LEN, &load_end); 3535 3536 configs/mvebu_db_armada8k_defconfig:CONFIG_SYS_BOOTM_LEN=0x800000 3537 default 0x4000000 if PPC || ARM64 3538 default 0x1000000 if X86 || ARCH_MX6 || ARCH_MX7 3539 default 0x800000 3540 3541 Fri Dec 15 19:21:53 GMT 2023 3542 3543 Let's put some English words on the page to explain the above 3544 gibberish. Since I upgraded the U-Boot on my Turris Omnia, it has 3545 stopped being able to tftpboot. 3546 3547 Uncompressing Kernel Image 3548 lzma compressed: uncompress error 7 3549 Must RESET board to recover 3550 3551 "uncompress error 7" means there is not enough space in the output 3552 buffer, and the output buffer is set by CONFIG_SYS_BOOTM_LEN which is 3553 8192k, smaller than the uncompressed 12104200 of our kernel. 3554 3555 So how can we fix? 3556 3557 * one possibility is to do what the turris rescue mode does: build an 3558 uncompressed uimage and then lzma the result. u-boot can uncompress 3559 the received file using lzmadec command. we'd want to do this without 3560 breaking tftpboot on every other device that might not have an lzmadec 3561 command 3562 3563 * is there bloat in the kernel we could trim? probably not 4MB of it 3564 3565 * we could build a custom u-boot with a bigger buffer. this _might_ 3566 not be a completely stupid idea as it's only the people prepared to 3567 open the box that would be doing tftp workflows anyway, so provided 3568 it's possible to replace u-boot without bricking it 3569 3570 * we could try building zimage instead of uimage and use bootz to 3571 start it 3572 3573 Sat Dec 16 11:15:56 GMT 2023 3574 3575 there is another use case for weird tftpboot derivation, which is the 3576 device Raito has ported to where you need to wave a magic chicken at 3577 u-boot on each command line 3578 3579 Sat Dec 16 23:32:11 GMT 2023 3580 3581 Turns out that even when using an uncompressed uimage, u-boot runs the 3582 code to check the decompressed size, so that doesn't help at all. But 3583 booting a zImage works fine. I am committing a first pass of 3584 modules/outputs/tftpbootlz.nix which does this using a lot of 3585 copy-paste and (ironically) no lzma stuff at all. 3586 3587 Sun Dec 17 16:25:30 GMT 2023 3588 3589 it's started failing to mount root on arm32 because it's not recognising 3590 the reserved-memory and something is trashing the phram filesystem 3591 3592 reserved-memory { 3593 3594 phram-rootfs { 3595 reg = <0x1400000 0x1900000>; 3596 compatible = "phram"; 3597 }; 3598 }; 3599 3600 Sun Dec 17 17:13:54 GMT 2023 3601 3602 * We need to write the fdt phram differently on 64 bit vs 32 bit 3603 (address-cells and size-cells should be 2 or 1) 3604 3605 * this might be why it wasn't working on mips (can we test this 3606 somehow in qemu or do we need to plug a device in?) 3607 3608 qemu user-mode networking has a builtin tftp server. 3609 3610 so we need a test that builds the tftpboot target for each qemu arch, 3611 and then does run-liminix-vm with the --lan and --u-boot options, then 3612 drives it with expect 3613 3614 3615 * maybe tftpboot[lz] could be reintegrated with the regular one somehow 3616 3617 Fri Dec 22 15:11:35 GMT 2023 3618 3619 We have a working test for tftpboot, on all platforms, which took a 3620 while. 3621 3622 * tftpbootlz needs to be updated with what we learned, or merged 3623 back into it 3624 3625 * omnia install 3626 3627 - build a stripped-down installer image which can be put on a 3628 usb stick 3629 - from openwrt on the device, use fw_setenv to set boot order 3630 - boot into the installer image- 3631 reformat the emmc as per requirements 3632 - PREFIX=/mnt liminix-rebuild 3633 - profit 3634 3635 Could we liminix-rebuild into /some/prefix/nix/store this would 3636 actually be useful both for this boot-from-usb scenario and for 3637 levitate. Looks like min-copy-closure doesn't need anything much on 3638 the destination system except a working sshd and maybe an empty 3639 /nix/store and /persist. Potentially we could even do it without 3640 chroot (which would save running a second sshd), just add a prefix on 3641 the paths 3642 3643 what's the fallback? we're not touching the turris rescue 3644 system (which is in nor flash) so we can expect all the 3645 knightrider modes to continue to workto be able to 3646 boot back into that and restore the vendor os? I think so 3647 3648 Fri Dec 22 16:56:40 GMT 2023 3649 3650 If we're going to use fw_setenv to change boot order, 3651 we could equally well boot from tftp and not need the 3652 usb stick 3653 3654 fw_setenv boot_targets "tftp mmc0 nvme0 scsi0 usb0 pxe dhcp" 3655 setenv bootcmd_tftp "echo TFTP BOOT" 3656 3657 how can we get a tftp boot into few enough characters to reasonably 3658 put it in an environment variable? 3659 - use dhcp? 3660 - embed bootargs into the fdt 3661 3662 Fri Dec 22 21:10:53 GMT 2023 3663 3664 * dtb needs size and offset of uncompressed root filesystem to add 3665 reserved-memory and cmdline params 3666 3667 * setting these in the dtb will change the size of the dtb 3668 3669 * am assuming that we don't want the kernel to relocate into 3670 ram that clashes with the root fs 3671 3672 * should we care about phys mem fragmentation? 3673 3674 conclusion: 3675 3676 hardware.loadAddress 3677 <uncompressed/relocated kernel> 3678 tftp.loadAddress 3679 <space for uncompressed root> 3680 uimage or zimage 3681 dtb 3682 compressed root 3683 3684 3685 [ should we rename hardware.loadAddress to something that expresses 3686 more clearly it's the _kernel_ load address? ] 3687 3688 [ another thing we need to do is stop building two kernels 3689 because the uimage and zimage derivations are different ] 3690 3691 Sat Dec 23 18:07:43 GMT 2023 3692 3693 Addendum: for a zimage we need the compressed kernel to be at the 3694 highest address, otherwise it prints "Starting" and then hangs 3695 indefinitely. 3696 3697 I believe this to be because the kernel decompressor sets up a stack 3698 directly after the compressed payload, so will trash the fdt if it was 3699 also there. The bug didn't exhibit on Turris Omnia with the same 3700 layout, but maybe that was just luck. 3701 3702 Sat Dec 23 18:11:04 GMT 2023 3703 3704 Here is scope of work for Turris: 3705 3706 (I) we need to build a suitable tftpboot image for 3707 recovery/install. 3708 3709 - disk partitioning tools and mkfs stuff 3710 - kernel with all the filesystems 3711 - dhcp client for connecting to wired network 3712 3713 (II) we need instructions for building the real system 3714 and using min-copy-closure to copy and install the system 3715 configuration of the real one into /mnt 3716 3717 (III) probably try the same recovery image as a USB stick 3718 3719 (IV) I've lost track of what we're doing with /boot, does that work? 3720 3721 (V) gpio thingy for SFP switching 3722 3723 (VI) iperf, performance testing 3724 3725 (VII) put device name and usefulness tiers ("stable", "experimental", "wip") in the docs 3726 3727 (VIII) params for ubi(fs) are a mess 3728 3729 (IX) wlan country code 3730 3731 Tue Dec 26 16:23:37 GMT 2023 3732 3733 I seem to have lost a chunk of notes here. Have added 3734 systemConfiguration/bin/install which does the stuff to copy the right 3735 files into /bin and wherever. There is currently no test for it though 3736 3737 We could further simplify liminix-rebuild by adding --reboot as a flag 3738 to install 3739 3740 Tue Dec 26 21:38:43 GMT 2023 3741 3742 To be any use, the test needs to be end-to-end - as in, rather than 3743 just checking some files are copied, test that the machine rebooted 3744 successfully 3745 3746 Fri Dec 29 18:36:16 GMT 2023 3747 3748 Our test for liminix-rebuild uses qemu block device and ext4 instead 3749 of phram because -device loader doesn't seem to survive a reboot. 3750 And it needs some free space in the ext4 partition inside the 3751 mbr image so that it can install new stuff. However, the 3752 filesystem is sized to be near-full. 3753 3754 If the mbrimage output is to be much use, probably there should be 3755 some way of telling it how big the disk is. Maybe it should use 3756 hardware.flash.size? 3757 3758 UBI also does a bad job of integrating into the hardware.flash hierarchy 3759 (but ubi is also more complicated as the ubi volumes are "nested" inside 3760 an MTD partition) 3761 3762 To move forwards with this test I think I will make it not depend on 3763 mbrimage for now, but we have to come back to this. Maybe importing 3764 the mbrimage module provides new hardware.disk = { partitions, size etc} 3765 config options. 3766 3767 Sun Dec 31 23:52:04 GMT 2023 3768 3769 https://developer.ridgerun.com/wiki/index.php/Setting_up_fw_printenv_to_modify_u-boot_environment_variables#Preparing_the_fw_env.config_file 3770 3771 can we extract the fw_env config data somehow to produce an appropriate 3772 file for the device? 3773 3774 the device config needs to specify partition name and offset at minimum, 3775 possibly also size. 3776 3777 we can create a service that writes the config based on those values. but 3778 if we are to be using fw_setenv from the shell, there is no service 3779 which depends on that service. whatever defines the service also needs 3780 to add it to system.services so that the recovery system can specify it 3781 3782 Sat Jan 6 12:30:27 GMT 2024 3783 3784 How do we min-copy-closure to the device when we don't have anything 3785 hooked to the LAN port? It's rather easy to break the WAN connection 3786 when it involves going out to the internet and back 3787 3788 * Don't want to plug it into the actual lan because it's doing dhcp service 3789 and that is going to confuse 3790 3791 * the machine we're copying from is loaclhost 3792 3793 * we could do some kind of port forwarding thing? maybe a port forward on 3794 run-border-vm qemu user networking ... 3795 3796 * static route on loaclhost? 3797 3798 512 sudo ip netns add test-lan 3799 514 sudo ip link set dev enp1s0 netns test-lan 3800 3801 525 sudo ip link add veth-test-lan type veth peer veth1 netns test-lan 3802 533 sudo ip netns exec test-lan ip link add name br0 type bridge 3803 536 sudo ip netns exec test-lan ip link set veth1 master br0 3804 537 sudo ip netns exec test-lan ip link set enp1s0 master br0 3805 sudo ip netns exec test-lan /nix/store/dh66q9k402pwpmmgc983xwmwb3vvvjbr-busybox-1.36.1/bin/busybox udhcpc -i br0 3806 3807 then we could add a route to 10.8.0.1/32 with dev veth-test-lan ? 3808 3809 Sat Jan 6 20:52:45 GMT 2024 3810 3811 This is all beside the point right now because the _recovery_ system 3812 does not run all this stuff - it just has a dhcp client on the lan 3813 interface. We could plug it straight into the switch. 3814 3815 3816 As we already just plugged it into enp1s0 on loaclhost, could we 3817 do somethin to put it on the lan from there? add it to vbridge0? 3818 3819 Sun Jan 7 15:30:57 GMT 2024 3820 3821 Turns out we should have used a working ethernet cable. 3822 3823 Sun Jan 7 15:31:14 GMT 2024 3824 3825 OK, so 3826 3827 # on device 3828 mount /dev/mmcblk0p1 /mnt 3829 [ take a snapshot if needed ] 3830 [ clear out the turrisos files ] 3831 ls /mnt/@ 3832 3833 # on build 3834 3835 $ nix-build -I liminix-config=./examples/rotuer.nix --arg device "import ./devices/turris-omnia" -A outputs.systemConfiguration 3836 $ nix-shell --run "min-copy-closure -r /mnt/@ root@recovery.lan result " 3837 3838 # on device 3839 3840 $ mkdir /mnt/@/persist 3841 $ /mnt/@/nix/store/swf3vn9bzx198c0cwp6naq0glqa9192n-make-stuff-armv7l-unknown-linux-musleabihf/bin/install /mnt/@/ 3842 3843 this fails because it tries to copy from the unprefixed nix 3844 store. Also probably it should mkdir $prefix/persist. Also it needs to 3845 create $prefix/boot: it's too late to do that with `activate` 3846 because u-boot will need it to exist in order to load the initramfs 3847 that runs activate 3848 3849 Thu Jan 11 23:36:47 GMT 2024 3850 3851 squashfs rootfsType doesn't rebuild when the kernel config is changed 3852 3853 Mon Jan 22 19:04:45 GMT 2024 3854 3855 setenv serverip 10.0.0.1 3856 setenv ipaddr 10.0.0.8 3857 compraddr=0x01000000 3858 tftpboot ${compraddr} recovery.img.lzma 3859 setexpr writeaddr ${filesize} + $compraddr 3860 lzmadec ${compraddr} $writeaddr 3861 usb start 3862 usb dev 0 3863 wdt dev watchdog@20300 3864 wdt stop 3865 usb write ${writeaddr} 0 ${filesize} 3866 3867 3868 Thu Jan 25 11:55:36 GMT 2024 3869 3870 openwrt: 3871 CONFIG_BROADCOM_PHY=m 3872 CONFIG_FIXED_PHY=y 3873 CONFIG_GENERIC_PHY=y 3874 CONFIG_IP17XX_PHY=m ? 3875 CONFIG_MARVELL_PHY=y 3876 CONFIG_MVSW61XX_PHY=y ? 3877 CONFIG_RTL8366RB_PHY=m ? 3878 CONFIG_RTL8366S_PHY=m ? 3879 CONFIG_RTL8367B_PHY=m ? 3880 CONFIG_SWPHY=y 3881 CONFIG_USB_PHY=y 3882 3883 CONFIG_FIXED_PHY=y 3884 CONFIG_GENERIC_PHY=y 3885 CONFIG_MARVELL_PHY=y 3886 CONFIG_PHY_MVEBU_A3700_COMPHY=y 3887 CONFIG_PHY_MVEBU_A38X_COMPHY=y 3888 CONFIG_SWPHY=y 3889 # 3890 3891 Sat Jan 27 18:14:13 GMT 2024 3892 3893 To make the recovery system (and tftpboot generally) more useful, it 3894 would be good to resize the root fs on boot. Need to do this before 3895 anything that writes to it 3896 3897 Mon Jan 29 21:50:59 GMT 2024 3898 3899 something is corrupted in the uncompressed rootfs 3900 3901 3902 $ head -c $(printf "%d" 0x2be0000) rootfs | sha1sum 3903 142571fe0436c18191727d1d4c2fd32163c1f2e1 - 3904 => sha1sum 0x1000000 2be0000 3905 sha1 for 01000000 ... 03bdffff ==> 142571fe0436c18191727d1d4c2fd32163c1f2e1 3906 3907 but! 3908 3909 $ head -c $(printf "%d" 0x2bf0000) rootfs | sha1sum 3910 7aa004ba87c6772bade491fbade164e2dfe100f9 - 3911 => sha1sum 0x1000000 2bf0000 3912 sha1 for 01000000 ... 03beffff ==> 1a0923a94784d0c0b86006c5e6fff1649770dad3 3913 3914 something is trashing something in the range 03be0000 - 03beffff 3915 or else it's not being decompressed properly 3916 3917 pxefile_addr_r=0x1900000 3918 ramdisk_addr_r=0x2200000 3919 scriptaddr=0x1800000 3920 fdt_addr_r=0x2000000 3921 fdtcontroladdr=7fb19b30 3922 fdtfile=armada-385-turris-omnia.dtb 3923 fdt_high=0x10000000 3924 initrd_high=0x10000000 3925 kernel_addr_r=0x1000000 3926 0x1700000; 3927 0x10000000 3928 3929 Sun Feb 4 11:55:00 GMT 2024 3930 3931 restructuredtext headings: 3932 3933 https://devguide.python.org/documentation/markup/#sections 3934 3935 3936 ####### chapter (one per filename) 3937 ******* 3938 ======= 3939 ------- 3940 3941 Mon Feb 5 09:57:52 GMT 2024 3942 3943 Before calling the Omnia "done" I'd like to get it to the point that 3944 I can actually use it as a CPE. This means 3945 3946 - writing something down about how we handle static addresses 3947 - hosts that need static ipv6 can configure it themselves as ::n 3948 where n is a small number. this won't clash with slaac 3949 - the `hosts` param to dnsmasq can specify static ipv4 3950 3951 - dealing with port forwards and allowed incoming in the firewall 3952 3953 - would be quite cool to run sniproxy instead of forwarding to 3954 loaclhost (extra credit) 3955 3956 Sat Feb 10 18:23:54 GMT 2024 3957 3958 ARGH KERNEL 3959 3960 You can't define CONFIG_NETFILTER=y in a monolithic kernel and expect 3961 later to separately build some modules that use it, because there are 3962 a bunch of symbols that only get defined if certain other CONFIG 3963 options are set at the time that the monolithic kernel is built. 3964 3965 https://github.com/torvalds/linux/blob/master/net/netfilter/core.c#L689 3966 3967 Another example is 3968 https://github.com/torvalds/linux/blob/master/include/linux/netdevice.h#L160 3969 - if you decide after building the kernel that you're going to build 3970 some wireless modules, you can't do that without rebuilding the kernel 3971 so that it knows to expect them 3972 3973 The moral of the story seems to be: if you have a compiled Linux kernel source tree and you change some symbol from "is not set" to m and then run make modules, you cannot in general expect that newly compiled module to work. 3974 3975 AP advertised VHT without HT, disabling HT/VHT/HE 3976 3977 TODO 3978 3979 - [done] support kernel version as parameter to builder pkgs/kernel/default.nix 3980 - [done] extract the change in how module loading works from omnia device config, 3981 and fix the other thing that uses it 3982 - [axed] wlan module to take 'backported' as a parameter 3983 half of the omnia conditionalConfig can go into the module 3984 - [done] upgrade omnia to kernel v6 3985 - figure out what mdns we need for local hostname resolution 3986 (maybe bridging lan/wlan)? 3987 - [DONE] slow wifi because "AP advertised VHT without HT, disabling HT/VHT/HE" 3988 - [DONE] add local domain to secrets 3989 - run sniproxy instead of forwarding 3990 - [test] forward some port to loaclhost 22 for inbound ipv4 ssh 3991 3992 3993 Mon Feb 12 21:50:35 GMT 2024 3994 3995 # find /run/service-state/dhcp6c.wan.link.pppoe/address/ 3996 /run/service-state/dhcp6c.wan.link.pppoe/address/ 3997 /run/service-state/dhcp6c.wan.link.pppoe/address/2001-8b0-1111-1111-0-ffff-51bb-4cf2_LFoo015bSsM 3998 /run/service-state/dhcp6c.wan.link.pppoe/address/2001-8b0-1111-1111-0-ffff-51bb-4cf2_LFoo015bSsM/valid 3999 /run/service-state/dhcp6c.wan.link.pppoe/address/2001-8b0-1111-1111-0-ffff-51bb-4cf2_LFoo015bSsM/preferred 4000 /run/service-state/dhcp6c.wan.link.pppoe/address/2001-8b0-1111-1111-0-ffff-51bb-4cf2_LFoo015bSsM/len 4001 /run/service-state/dhcp6c.wan.link.pppoe/address/2001-8b0-1111-1111-0-ffff-51bb-4cf2_LFoo015bSsM/address 4002 # 4003 4004 valid 7199 preferred 3599 4005 4006 Tue Feb 13 19:44:57 GMT 2024 4007 4008 Before we put this back live, would be good to 4009 4010 [done] 1) move the leases file into /persist 4011 4012 I think we'll do /persist/service/<name>/ and change ssh to use the same 4013 scheme. 4014 4015 we could put mkpersist() in serviceFns which would check for /persist 4016 and return a directory in /persist/service/ or /run/service-state 4017 4018 (will something bad happen if we use /run/service-state? it will also 4019 expose the thingy as an output, but whether it's accessible that way 4020 will depend on whether there's a writable fs or not, which is unexpected) 4021 4022 : rename service-state to /run/services/outputs 4023 : on boot 4024 : if /persist 4025 : create /persist/services/state and symlink /run/services/state to it 4026 : else create /run/services/state 4027 4028 4029 [done] 2) maybe change the local domain back to .lan? setting up 4030 systemd-networkd with search domains is an awful faff 4031 4032 [done] 3) work out what to do with incoming ssh from wan 4033 4034 - For noetbook and thinkpad we have a vpn anyway so can expect to 4035 reach loaclhost directly using ipv6 4036 4037 - stop ssh from ever trying to get to our ipv4 address. 4038 - we could get rid of A record for loaclhost.telent.net but 4039 there are a bunch of CNAMES pointing at it for web servers. 4040 - we could reject incoming connections to tcp4 port 22 in firewall 4041 and then there is a clear signal to Dont Do That Then 4042 4043 - for emergency use, dnat ipv4 2200 and 2201 to rotuer and loaclhost 4044 4045 Tue Feb 13 22:31:03 GMT 2024 4046 4047 * the reason we can't reboot is that there is a service to add each 4048 lan device to the bridge which does ifwait $dev running, which doesn't 4049 return until there's something plugged in. So s6-rc hangs indefinitely 4050 until the lan switch is fully populated. This is definitely a "next 4051 milestone" thing. 4052 4053 * another example of "thing that depends on other thing but which it 4054 is actually OK if neither of them happen" might be "mount a 4055 filesystem if there is a usb mass storage device attached" 4056 4057 * I don't know if failover also fits into the model we don't quite 4058 have. LTE route depends on pppoe not being healthy 4059 4060 we can have services (or bundles) that aren't part of the default target, 4061 and plumb them into events of some kind (netlink?) to bring them up/down? 4062 4063 we can use s6-rc instanced services: 4064 https://skarnet.org/software/s6/instances.html 4065 4066 "s6-instance-create and s6-instance-delete are relatively expensive operations, because they have to recursively copy or delete directories and use the synchronization mechanism with the instance supervisor, compared to s6-instance-control which only has to send commands to already existing supervisors. If you are going to turn instances on and off on a regular basis, it is more efficient to keep the instance existing and control it with s6-instance-control than it is to repeatedly create and delete it. " 4067 4068 Probably we need something that reads netlink messages and converts 4069 them to a format that we can use to control services. Is there a 4070 benefit to using services here and not just running commands? it means 4071 the system state change we desire will stay changed. 4072 4073 TODO items not to lose track of 4074 4075 - speed testing (iperf) 4076 - make gl-ar750 tftpboot build again 4077 - finish belkin 4078 - install sniproxy 4079 - is there something simple we can do to make it reboot again? 4080 - turn rotuer,extneder examples into "profiles" that don't embed 4081 hardware specifics 4082 4083 Thu Feb 15 11:50:56 GMT 2024 4084 4085 1) to make tftpboot work with old bootm implementations we need 4086 4087 - compressed root 4088 - uncompressed root 4089 - kernel with dtb 4090 dtb needs to know where uncompressed rootfs is and how big 4091 4092 2) if the image is a zImage (arm32) or an Image (arm64) we have to stick 4093 with the three-arg bootz, and the dtb has to be lower in ram than the kernel 4094 4095 Fri Feb 16 15:43:32 GMT 2024 4096 4097 DHCP6c refresh is still wrong. We get updates for an address that 4098 hasn't changed prefix or length, when the expiry times have changed, 4099 and we can't action that by remove;add because remove will wipe out 4100 any routes through the interface but add won't put them back 4101 4102 We can use "change" for both adds and changes, but we need to know that 4103 a change is not a delete 4104 4105 The "identity" of an address is the address itself: kernel won't 4106 let you add the same address with two different prefixes. 4107 4108 Keeping it simple, we could call "change" on every address in the 4109 new-addresses list and "del" on every address in old-addresses 4110 that is no longer in new-addresses 4111 4112 If the upstream has changed length, "ip addr change" is ignored, 4113 so it needs to be in deleted as well as added/changed