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 }