liminix

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

default.nix (11495B)


      1 {
      2   description = ''
      3     Belkin RT-3200 / Linksys E8450
      4     ******************************
      5 
      6     This device is based on a 64 bit Mediatek MT7622 ARM platform,
      7     and is mostly feature-complete in Liminix but as of Dec 2024
      8     has seen very little actual use.
      9 
     10     Hardware summary
     11     ================
     12 
     13     - MediaTek MT7622BV (1350MHz)
     14     - 128MB NAND flash
     15     - 512MB	RAM
     16     - b/g/n wireless using MediaTek MT7622BV (MT7615E driver)
     17     - a/n/ac/ax wireless using  MediaTek MT7915E
     18 
     19 
     20     Installation
     21     ============
     22 
     23     Liminix on this device uses the UBI volume management system to
     24     perform wear leveling on the flash. This is not set up from the
     25     factory, so a one-time step is needed to prepare it before Liminix
     26     can be installed.
     27 
     28 
     29     Preparation
     30     -----------
     31 
     32     To prepare the device for Liminix you first need to use the
     33     `OpenWrt UBI Installer
     34     <https://github.com/dangowrt/owrt-ubi-installer>`_ image to
     35     rewrite the flash layout. As of Jan 2025 there are two versions
     36     of the installer available: the release version 1.0.2 and the
     37     pre-release 1.1.3 and for Liminix you nee the pre-relese.
     38     The release version of the installer creates UBI volumes
     39     according to an older layout that is not compatible with
     40     the Linux 6.6.67 kernel used in Liminix.
     41 
     42     You can run the installer in one of two ways:
     43     either follow the instructions to do it through the vendor web
     44     interface, or you can drop to U-Boot and use TFTP
     45 
     46     .. code-block:: console
     47 
     48         MT7622> setenv ipaddr 10.0.0.6
     49         MT7622> setenv serverip 10.0.0.1
     50         MT7622> tftpboot 0x42000000  openwrt-mediatek-mt7622-linksys_e8450-ubi-initramfs-recovery-installer.itb
     51         MT7622> bootm 0x42000000
     52 
     53     This will write the new flash layout and then boot into a
     54     "recovery" OpenWrt installation.
     55 
     56     Building/installing Liminix
     57     ----------------
     58 
     59     The default target for this device is ``outputs.ubimage`` which
     60     makes a ubifs image suitable for use with :command:`ubiupdatevol`.
     61     To write this to the device we use the OpenWrt recovery system
     62     installed in the previous step. In this configuration the
     63     device assigns itself the IP address 192.168.1.1/24 on its LAN
     64     ports and expects the connected computer to have 192.168.1.254
     65 
     66     .. warning:: The `ubi0_7` device in these instructions is correct
     67                  as of Dec 2024 (dangowrt/owrt-ubi-installer commit
     68                  d79e7928). If you are installing some time later, it
     69                  is important to check the output from
     70                  :command:`ubinfo -a` and make sure you are updating
     71                  the "liminix" volume and not some other one which had
     72                  been introduced since I wrote this.
     73 
     74     .. code-block:: console
     75 
     76         $ nix-build -I liminix-config=./my-configuration.nix  --arg device "import ./devices/belkin-rt3200" -A outputs.default
     77         $ cat result/rootfs | ssh root@192.168.1.1 "cat > /tmp/rootfs"
     78         $ ssh root@192.168.1.1
     79         root@OpenWrt:~# ubimkvol /dev/ubi0 --name=liminix --maxavsize
     80         root@OpenWrt:~# ubinfo -a
     81         [...]
     82         Volume ID:   7 (on ubi0)
     83         Type:        dynamic
     84         Alignment:   1
     85         Size:        851 LEBs (108056576 bytes, 103.0 MiB)
     86         State:       OK
     87         Name:        liminix
     88         Character device major/minor: 250:8
     89         root@OpenWrt:~# ubiupdatevol /dev/ubi0_7 /tmp/rootfs
     90 
     91     To make the new system bootable we also need to change some U-Boot variables.
     92     ``boot_production`` needs to mount the filesystem and boot the FIT image
     93     found there, and :code:`bootcmd` needs to be told _not_ to boot the rescue
     94     image if there are records in pstore, because that interferes with
     95     ``config.log.persistent``
     96 
     97     .. code-block:: console
     98 
     99         root@OpenWrt:~# fw_setenv orig_boot_production $(fw_printenv -n boot_production)
    100         root@OpenWrt:~# fw_setenv orig_bootcmd $(fw_printenv -n bootcmd)
    101         root@OpenWrt:~# fw_setenv boot_production 'led $bootled_pwr on ; ubifsmount ubi0:liminix && ubifsload ''${loadaddr} boot/fit && bootm ''${loadaddr}'
    102         root@OpenWrt:~# fw_setenv bootcmd 'run boot_ubi'
    103 
    104     For subsequent Liminix reinstalls, just run the
    105     :command:`ubiupdatevol` command again. You don't need to repeat
    106     the "Preparation" step and in fact should seek to avoid it if
    107     possible, as it will reset the erase counters used for write
    108     levelling.  Using UBI-aware tools is therefore preferred over any
    109     kind of "factory" wipe which will reset them.
    110   '';
    111 
    112   system = {
    113     crossSystem = {
    114       config = "aarch64-unknown-linux-musl";
    115     };
    116   };
    117 
    118   module =
    119     {
    120       pkgs,
    121       config,
    122       lib,
    123       lim,
    124       ...
    125     }:
    126     let
    127       inherit (lib) mkIf;
    128       firmware = pkgs.stdenv.mkDerivation {
    129         name = "wlan-firmware";
    130         phases = [ "installPhase" ];
    131         installPhase = ''
    132           mkdir $out
    133           cp ${pkgs.linux-firmware}/lib/firmware/mediatek/{mt7915,mt7615,mt7622}* $out
    134         '';
    135       };
    136       openwrt = pkgs.openwrt_24_10;
    137     in
    138     {
    139       imports = [
    140         ../../modules/arch/aarch64.nix
    141         ../../modules/outputs/tftpboot.nix
    142         ../../modules/outputs/ubifs.nix
    143       ];
    144       config = {
    145         kernel = {
    146           extraPatchPhase = ''
    147             ${openwrt.applyPatches.mediatek}
    148           '';
    149           src = openwrt.kernelSrc;
    150           version = openwrt.kernelVersion;
    151           config = {
    152             PCI = "y";
    153             ARCH_MEDIATEK = "y";
    154             # ARM_MEDIATEK_CPUFREQ = "y";
    155 
    156             # needed for "Cannot find regmap for /infracfg@10000000"
    157             MFD_SYSCON = "y";
    158             MTK_INFRACFG = "y";
    159 
    160             MTK_PMIC_WRAP = "y";
    161             DMADEVICES = "y";
    162             MTK_HSDMA = "y";
    163             MTK_SCPSYS = "y";
    164             MTK_SCPSYS_PM_DOMAINS = "y";
    165             # MTK_THERMAL="y";
    166             MTK_TIMER = "y";
    167 
    168             COMMON_CLK_MT7622 = "y";
    169             COMMON_CLK_MT7622_ETHSYS = "y";
    170             COMMON_CLK_MT7622_HIFSYS = "y";
    171             COMMON_CLK_MT7622_AUDSYS = "y";
    172             PM_CLK = "y";
    173 
    174             REGMAP_MMIO = "y";
    175             CLKSRC_MMIO = "y";
    176             REGMAP = "y";
    177 
    178             MEDIATEK_GE_PHY = "y";
    179             # MEDIATEK_MT6577_AUXADC = "y";
    180             NET_MEDIATEK_SOC = "y";
    181             NET_MEDIATEK_SOC_WED = "y";
    182             NET_MEDIATEK_STAR_EMAC = "y"; # this enables REGMAP_MMIO
    183             NET_VENDOR_MEDIATEK = "y";
    184             PCIE_MEDIATEK = "y";
    185 
    186             BLOCK = "y"; # move this to base option
    187 
    188             SPI_MASTER = "y";
    189             SPI = "y";
    190             SPI_MEM = "y";
    191             SPI_MTK_NOR = "y";
    192             SPI_MTK_SNFI = "y";
    193 
    194             MTD = "y";
    195             MTD_BLOCK = "y";
    196             MTD_RAW_NAND = "y";
    197             MTD_NAND_MTK = "y";
    198             MTD_NAND_MTK_BMT = "y"; # Bad-block Management Table
    199             MTD_NAND_ECC_MEDIATEK = "y";
    200             MTD_NAND_ECC_SW_HAMMING = "y";
    201             MTD_SPI_NAND = "y";
    202             MTD_OF_PARTS = "y";
    203             MTD_NAND_CORE = "y";
    204             MTD_SPI_NOR = "y";
    205             MTD_SPLIT_FIRMWARE = "y";
    206             MTD_SPLIT_FIT_FW = "y";
    207 
    208             MTD_UBI_NVMEM = "y";
    209             NVMEM_MTK_EFUSE = "y";
    210             NVMEM_BLOCK = "y";
    211             NVMEM_LAYOUT_ADTRAN = "y";
    212 
    213             MMC = "y";
    214             MMC_BLOCK = "y";
    215             MMC_CQHCI = "y";
    216             MMC_MTK = "y";
    217 
    218             # Distributed Switch Architecture is needed
    219             # to make the ethernet ports visible
    220             NET_DSA = "y";
    221             NET_DSA_MT7530 = "y";
    222             NET_DSA_TAG_MTK = "y";
    223             NET_DSA_MT7530_MDIO = "y";
    224 
    225             SERIAL_8250 = "y";
    226             SERIAL_8250_CONSOLE = "y";
    227             SERIAL_8250_MT6577 = "y";
    228             # SERIAL_8250_NR_UARTS="3";
    229             # SERIAL_8250_RUNTIME_UARTS="3";
    230             SERIAL_OF_PLATFORM = "y";
    231 
    232             # Must enble hardware watchdog drivers. Else the device reboots after several seconds
    233             WATCHDOG = "y";
    234             MEDIATEK_WATCHDOG = "y";
    235           };
    236           conditionalConfig = {
    237             WLAN = {
    238               MT7615E = "m";
    239               MT7622_WMAC = "y";
    240               MT7915E = "m";
    241             };
    242           };
    243         };
    244         boot = {
    245           commandLine = [ "console=ttyS0,115200" ];
    246           tftp.loadAddress = lim.parseInt "0x48000000";
    247           imageFormat = "fit";
    248           loader.fit.enable = lib.mkDefault true; # override this if you are building tftpboot
    249         };
    250         rootfsType = lib.mkDefault "ubifs"; # override this if you are building tftpboot
    251         filesystem =
    252           let
    253             inherit (pkgs.pseudofile) dir symlink;
    254           in
    255           dir {
    256             lib = dir {
    257               firmware = dir {
    258                 mediatek = symlink firmware;
    259               };
    260             };
    261           };
    262 
    263         hardware =
    264           let
    265             mac80211 = pkgs.kmodloader.override {
    266               targets = [
    267                 "mt7615e"
    268                 "mt7915e"
    269               ];
    270               inherit (config.system.outputs) kernel;
    271             };
    272           in
    273           {
    274             ubi = {
    275               minIOSize = "2048";
    276               logicalEraseBlockSize = "126976";
    277               physicalEraseBlockSize = "131072";
    278               maxLEBcount = "1024"; # guessing
    279             };
    280 
    281             defaultOutput = "ubimage";
    282             # the kernel expects this to be on a 2MB boundary. U-Boot
    283             # (I don't know why) has a default of 0x41080000, which isn't.
    284             # We put it at the 32MB mark so that tftpboot can put its rootfs
    285             # image and DTB underneath, but maybe this is a terrible waste of
    286             # RAM unless the kernel is able to reuse it later. Oh well
    287             loadAddress = lim.parseInt "0x42000000";
    288             entryPoint = lim.parseInt "0x42000000";
    289             rootDevice = "ubi0:liminix";
    290             dts = {
    291               src = "${openwrt.src}/target/linux/mediatek/dts/mt7622-linksys-e8450-ubi.dts";
    292               includePaths = [
    293                 "${openwrt.src}/target/linux/mediatek/dts"
    294                 "${config.system.outputs.kernel.modulesupport}/arch/arm64/boot/dts/mediatek/"
    295               ];
    296               includes = mkIf config.logging.persistent.enable [
    297                 ./pstore-pmsg.dtsi
    298               ];
    299             };
    300 
    301             # - 0x000000000000-0x000008000000 : "spi-nand0"
    302             #         - 0x000000000000-0x000000080000 : "bl2"
    303             #         - 0x000000080000-0x0000001c0000 : "fip"
    304             #         - 0x0000001c0000-0x0000002c0000 : "factory"
    305             #         - 0x0000002c0000-0x000000300000 : "reserved"
    306             #         - 0x000000300000-0x000008000000 : "ubi"
    307 
    308             networkInterfaces =
    309               let
    310                 inherit (config.system.service.network) link;
    311               in
    312               rec {
    313                 wan = link.build { ifname = "wan"; };
    314                 lan1 = link.build { ifname = "lan1"; };
    315                 lan2 = link.build { ifname = "lan2"; };
    316                 lan3 = link.build { ifname = "lan3"; };
    317                 lan4 = link.build { ifname = "lan4"; };
    318                 lan = lan3;
    319 
    320                 wlan = link.build {
    321                   ifname = "wlan0";
    322                   dependencies = [ mac80211 ];
    323                 };
    324                 wlan5 = link.build {
    325                   ifname = "wlan1";
    326                   dependencies = [ mac80211 ];
    327                 };
    328               };
    329           };
    330       };
    331     };
    332 }