liminix

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

default.nix (7424B)


      1 {
      2   system = {
      3     crossSystem = {
      4       config = "mips-unknown-linux-musl";
      5       gcc = {
      6         abi = "32";
      7         arch = "24kc";          # maybe mips_24kc-
      8       };
      9     };
     10   };
     11 
     12   description = ''
     13     GL.iNet GL-AR750
     14     ****************
     15 
     16     Hardware summary
     17     ================
     18 
     19     The GL-AR750 "Creta" travel router features:
     20 
     21      - QCA9531 @650Mhz SoC
     22      - dual band wireless: IEEE 802.11a/b/g/n/ac
     23      - two 10/100Mbps LAN ports and one WAN
     24      - 128MB DDR2 RAM
     25      - 16MB NOR Flash
     26      - supported in OpenWrt by the "ath79" SoC family
     27 
     28     The GL-AR750 has two distinct sets of wifi hardware. The 2.4GHz
     29     radio is part of the QCA9531 SoC, i.e. it's on the same silicon as
     30     the CPU, the Ethernet, the USB etc. The device is connected to the
     31     host via `AHB <https://en.wikipedia.org/wiki/Advanced_Microcontroller_Bus_Architecture>`_ and it is
     32     supported in Linux using the ath9k driver. 5GHz wifi
     33     is provided by a QCA9887 PCIe (PCI embedded) WLAN chip,
     34     supported by the ath10k driver.
     35 
     36     Installation
     37     ============
     38 
     39     As with many GL.iNet devices, the stock vendor firmware
     40     is a fork of OpenWrt, meaning that the binary created by
     41     :ref:`system-outputs-mtdimage` can be flashed using the
     42     vendor web UI or the U-Boot emergency "unbrick" routine.
     43 
     44     For flashing from an existing Liminix system (we believe that) it
     45     is necessary to first boot into a :ref:`system-outputs-kexecboot`
     46     system, otherwise you'll be overwriting flash partitions while
     47     they're in use - and that might not end well.
     48 
     49     Vendor web page: https://www.gl-inet.com/products/gl-ar750/
     50 
     51     OpenWrt web page: https://openwrt.org/toh/gl.inet/gl-ar750
     52 
     53   '';
     54 
     55   module = {pkgs, config, lim, ... }:
     56     let
     57       openwrt = pkgs.openwrt;
     58       firmwareBlobs = pkgs.pkgsBuildBuild.fetchFromGitHub {
     59         owner = "kvalo";
     60         repo = "ath10k-firmware";
     61         rev = "5d63529ffc6e24974bc7c45b28fd1c34573126eb";
     62         sha256 = "1bwpifrwl5mvsmbmc81k8l22hmkwk05v7xs8dxag7fgv2kd6lv2r";
     63       };
     64       firmware = pkgs.stdenv.mkDerivation {
     65         name = "wlan-firmware";
     66         phases = ["installPhase"];
     67         installPhase = ''
     68           mkdir -p $out/ath10k/QCA9887/hw1.0/
     69           blobdir=${firmwareBlobs}/QCA9887/hw1.0
     70           cp $blobdir/10.2.4-1.0/firmware-5.bin_10.2.4-1.0-00047 $out/ath10k/QCA9887/hw1.0/firmware-5.bin
     71           cp $blobdir/board.bin  $out/ath10k/QCA9887/hw1.0/
     72         '';
     73       };
     74       mac80211 = pkgs.mac80211.override {
     75         drivers = ["ath9k" "ath10k_pci"];
     76         klibBuild = config.system.outputs.kernel.modulesupport;
     77       };
     78       ath10k_cal_data =
     79         let
     80           offset = lim.parseInt "0x5000";
     81           size = lim.parseInt "0x844";
     82         in pkgs.liminix.services.oneshot rec  {
     83           name = "ath10k_cal_data";
     84           up = ''
     85             part=$(basename $(dirname $(grep -l art /sys/class/mtd/*/name)))
     86             echo ART partition is ''${part-unset}
     87             test -n "$part" || exit 1
     88             (in_outputs ${name}
     89              dd if=/dev/$part of=data iflag=skip_bytes,fullblock bs=${toString size} skip=${toString offset} count=1
     90             )
     91         '';
     92       };
     93       inherit (pkgs.pseudofile) dir symlink;
     94       inherit (pkgs.liminix.networking) interface;
     95     in {
     96       imports = [
     97         ../../modules/network
     98         ../../modules/arch/mipseb.nix
     99         ../../modules/outputs/tftpboot.nix
    100         ../../modules/outputs/mtdimage.nix
    101         ../../modules/outputs/jffs2.nix
    102       ];
    103 
    104       programs.busybox.options = {
    105         FEATURE_DD_IBS_OBS = "y"; # ath10k_cal_data needs skip_bytes,fullblock
    106       };
    107       hardware = {
    108         defaultOutput = "mtdimage";
    109         loadAddress = lim.parseInt "0x80060000";
    110         entryPoint = lim.parseInt "0x80060000";
    111         flash = {
    112           address = lim.parseInt "0x9F060000";
    113           size = lim.parseInt "0xfa0000";
    114           eraseBlockSize = 65536;
    115         };
    116         rootDevice = "/dev/mtdblock5";
    117         dts = {
    118           src = "${openwrt.src}/target/linux/ath79/dts/qca9531_glinet_gl-ar750.dts";
    119           includes =  [
    120             "${openwrt.src}/target/linux/ath79/dts"
    121           ];
    122         };
    123 
    124         networkInterfaces =
    125           let inherit (config.system.service.network) link;
    126           in {
    127             lan = link.build { ifname = "eth0"; };
    128             wan = link.build { ifname = "eth1"; };
    129             wlan = link.build {
    130               ifname = "wlan0";
    131               dependencies = [ mac80211 ];
    132             };
    133             wlan5 = link.build {
    134               ifname = "wlan1";
    135               dependencies = [ mac80211 ath10k_cal_data ];
    136             };
    137           };
    138       };
    139       filesystem = dir {
    140         lib = dir {
    141           firmware = dir {
    142             ath10k = dir {
    143               QCA9887 = symlink "${firmware}/ath10k/QCA9887";
    144               "cal-pci-0000:00:00.0.bin" = symlink "${ath10k_cal_data}/.outputs/data";
    145             };
    146           };
    147         };
    148       };
    149       boot.tftp = {
    150         loadAddress = lim.parseInt "0x00A00000";
    151       };
    152       kernel = {
    153         src = pkgs.pkgsBuildBuild.fetchurl {
    154           name = "linux.tar.gz";
    155           url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.71.tar.gz";
    156           hash = "sha256-yhO2cXIeIgUxkSZf/4aAsF11uxyh+UUZu6D1h92vCD8=";
    157         };
    158 
    159         # Mainline linux 5.19 doesn't have device-tree support for
    160         # this device or even for the SoC, so we use the extensive
    161         # OpenWrt kernel patches
    162         extraPatchPhase = ''
    163           ${openwrt.applyPatches.ath79}
    164         '';
    165 
    166         config = {
    167           ATH79 = "y";
    168           PCI = "y";
    169           PCI_AR724X = "y";
    170 
    171           SERIAL_8250_CONSOLE = "y";
    172           SERIAL_8250 = "y";
    173           SERIAL_CORE_CONSOLE = "y";
    174 
    175           # need this to open console device at boot. dmesg goes from
    176           # [    0.272934] Warning: unable to open an initial console.
    177           # to
    178           # [    0.247413] printk: console [ttyS0] disabled
    179           # [     0.25200] 18020000.uart: ttyS0 at MMIO 0x1802000 (irq = 10, base_baud = 1562500) is a 16550A
    180           SERIAL_OF_PLATFORM = "y";
    181 
    182           CONSOLE_LOGLEVEL_DEFAULT = "8";
    183           CONSOLE_LOGLEVEL_QUIET = "4";
    184 
    185           NET = "y";
    186           ETHERNET = "y";
    187           NET_VENDOR_ATHEROS = "y";
    188           AG71XX = "y";             # ethernet (qca,qca9530-eth)
    189           MFD_SYSCON = "y";         # ethernet (compatible "syscon")
    190           AR8216_PHY = "y";         # eth1 is behind a switch
    191 
    192           MTD_SPI_NOR = "y";
    193 
    194           SPI_ATH79 = "y";      # these are copied from OpenWrt.
    195           SPI_MASTER= "y";      # At least one of them is necessary
    196           SPI_MEM= "y";
    197           SPI_AR934X= "y";
    198           SPI_BITBANG= "y";
    199           SPI_GPIO= "y";
    200 
    201           GPIO_ATH79 = "y";
    202           GPIOLIB = "y";
    203           EXPERT="y";
    204           GPIO_SYSFS = "y"; # required by patches-5.15/0004-phy-add-ath79-usb-phys.patch
    205           OF_GPIO = "y";
    206           SYSFS = "y";
    207           SPI = "y";
    208           MTD = "y";
    209           MTD_BLOCK = "y";          # fix undefined ref to register_mtd_blktrans_devs
    210 
    211           WATCHDOG = "y";
    212           ATH79_WDT = "y";  # watchdog timer
    213 
    214           # this is all copied from nixwrt ath79 config. Clearly not all
    215           # of it is device config, some of it is wifi config or
    216           # installation method config or ...
    217 
    218           EARLY_PRINTK = "y";
    219 
    220           PRINTK_TIME = "y";
    221         };
    222       };
    223     };
    224 }