guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

01/01: website: Add post about Guix System on ARM.


From: julien lepiller
Subject: 01/01: website: Add post about Guix System on ARM.
Date: Mon, 25 Nov 2019 15:01:25 -0500 (EST)

roptat pushed a commit to branch master
in repository guix-artwork.

commit e2ccd5f44be9954878e2e073adff0fa906a94bc8
Author: Julien Lepiller <address@hidden>
Date:   Mon Nov 25 20:58:53 2019 +0100

    website: Add post about Guix System on ARM.
    
    * website/posts/guix-system-arm.md: New file.
---
 website/posts/guix-system-arm.md | 285 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 285 insertions(+)

diff --git a/website/posts/guix-system-arm.md b/website/posts/guix-system-arm.md
new file mode 100644
index 0000000..87fff57
--- /dev/null
+++ b/website/posts/guix-system-arm.md
@@ -0,0 +1,285 @@
+title: Guix on an ARM Board
+date: 2019-10-25 21:00
+author: Julien Lepiller
+tags: ARM
+---
+
+Increasingly people discovering Guix want to try it on an ARM board, instead of
+their x86 computer.  There might be various reasons for that, from power 
consumption
+to security.  In my case, I found these ARM boards practical for self-hosting,
+and I think the unique properties of GNU Guix are making it very suitable for 
that
+purpose.  I have installed GNU Guix on a Cubietruck, so my examples below will 
be
+about that board.  However, you should be able to change the examples for your
+own use case.
+
+Installing the Guix System on an ARM board is not as easy as installing it on 
an
+x86 desktop computer: there is no installation image.  However, Guix supports
+ARM and can be installed on a foreign distribution running on that 
architecture.
+The trick is to use the Guix installed on that foreign distribution to 
initialize
+the Guix System.  This article will show you how to install the Guix System on
+your board, without using an installer image.  As we have previously
+[mentionned](https://guix.gnu.org/blog/2017/porting-guixsd-to-armv7/) it is
+possible to generate an installation image yourself, if your board is 
supported.
+
+Most boards can be booted from an existing GNU+Linux distribution.  You will
+need to install a distribution (any of them) and install GNU Guix on it, using
+e.g. the [installer 
script](http://guix.gnu.org/manual/en/html_node/Binary-Installation.html).
+Then, my plan was to install the Guix System on an external SSD drive, instead
+of the SD card, but we will see that both are perfectly possible.
+
+The first part of the article will focus on creating a proper u-boot 
configuration
+and an operating system declaration that suits your board. The second part of 
this
+article will focus on the installation procedure, when there is no installer 
working
+for your system.
+
+Writing a configuration file for an ARM board
+---------------------------------------------
+
+A configuration file for an ARM board is not very different from a 
configuration file
+for a desktop or a server running on another architecture.  However, most 
boards use
+the u-boot bootloader and require some less common modules to be available at 
boot time.
+
+### The root file system
+
+First of all, you should decide where your root file system is going to be 
installed. In
+my case, I wanted to install is on the external SSD, so I chose it:
+
+```scheme
+(file-systems
+  (cons* (file-system
+           (mount-point "/")
+           (device "/dev/sda1")
+           (type "ext4"))
+         %base-file-systems))
+```
+
+If you instead want to install the root file system on an SD card, you'll need
+to find its device name, usually `/dev/mmcblk0` and the partition number.  The
+device corresponding to the first partition should be `/dev/mmcblk0p1`.  In 
that
+case, you would have:
+
+```scheme
+(file-systems
+  (cons* (file-system
+           (mount-point "/")
+           (device "/dev/mmcblk0p1")
+           (type "ext4"))
+         %base-file-systems))
+```
+
+### The bootloader
+
+Because of the way the Guix System is designed, you cannot use an already 
existing bootloader
+to boot your system: it wouldn't know where to look for the kernel, because it 
doesn't know
+its store path.  It wouldn't be able to let you boot older generations either. 
 Most boards
+use the u-boot bootloader, so we will focus on that bootloader here.
+
+Contrary to grub, there are multiple variants of u-boot, one per board type.  
The installation
+procedure for u-boot is also somewhat specific to the board, so there are two 
things that you
+need to take care of: the u-boot package and the bootloader declaration.
+
+Guix already define a few u-boot based bootloaders, such as 
`u-boot-a20-olinuxino-lime-bootloader`
+or `u-boot-pine64-plus-bootloader` among others.  If your board already has a 
`u-boot-*-bootloader`
+defined in `(gnu bootloader u-boot)`, you're lucky and you can skip this part 
of the article!
+
+Otherwise, maybe the bootloader package is defined in `(gnu packages 
bootloaders)`, such as
+the `u-boot-cubietruck` package.  If so, you're a bit lucky and you can skip 
creating your
+own package definition.
+
+If your board doesn't have a `u-boot-*` package defined, you can create one.  
It could be
+as simple as `(make-u-boot-package "Cubietruck" "arm-linux-gnueabihf")`.  The 
first argument
+is the board name, as expected by the u-boot build sysetem.  The second 
argument is the
+target triplet that corresponds to the architecture of the board.  You should 
refer to the
+documentation of your board for selecting the correct values.  If you're 
really unlucky,
+you'll need to do some extra work to make the u-boot package you just created 
work, as is
+the case for the `u-boot-puma-rk3399` for instance: it needs additional phases 
to install
+firmware.
+
+You can add the package definition to your operating system configuration file 
like so,
+before the operating-system declaration:
+
+```scheme
+(use-modules (gnu packages bootloaders))
+
+(define u-boot-my-board
+  (make-u-boot-package "Myboard" "arm-linux-gnueabihf"))
+
+(operating-system
+  [...])
+```
+
+Then, you need to define the bootloader.  A bootloader is a structure that has 
a name,
+a package, an installer, a configuration file and a configuration file 
generator.  Fortunately,
+Guix already defines a base u-boot bootloader, so we can inherit from it and 
only redefine a few
+things.
+
+The Cubietruck happens to be based on an allwinner core, for which there is 
already a
+u-boot bootloader definition `u-boot-allwinner-bootloader`.  This bootloader 
is not
+usable as is for the Cubietruck, but it defines most of what we need.  In 
order to get
+a proper bootloader for the Cubietruck, we define a new bootloader based on the
+Allwinner bootloader definition:
+
+```scheme
+(define u-boot-cubietruck-bootloader
+  (bootloader
+    (inherit u-boot-allwinner-bootloader)
+    (package u-boot-cubietruck)))
+```
+
+Now that we have our definitions, we can choose where to install the 
bootloader.  In the
+case of the Cubietruck, I decided to install it on the SD card, because it 
cannot boot from
+the SSD directly.  Refer to your board documentation to make sure you install 
u-boot on
+a bootable device.  As we said earlier, the SD card is `/dev/mmcblk0` on my 
device.
+
+We can now put everything together like so:
+
+```scheme
+(use-modules (gnu packages bootloaders))
+
+(define u-boot-cubietruck
+  (make-u-boot-package "Cubietruck" "arm-linux-gnueabihf"))
+
+;; u-boot-allwinner-bootloader is not exported by (gnu bootloader u-boot) so
+;; we use @@ to get it.  (@ (module) variable) means: get the value of 
"variable"
+;; as defined (and exported) in (module).  (@@ (module) variable) is the same, 
but
+;; it doesn't care whether it is exported or not.
+(define u-boot-allwinner-bootloader
+  (@@ (gnu bootloader u-boot) u-boot-allwinner-bootloader))
+
+(define u-boot-cubietruck-bootloader
+  (bootloader
+    (inherit u-boot-allwinner-bootloader)
+    (package u-boot-cubietruck)))
+
+(operating-system
+  [...]
+  (bootloader
+    (bootloader-configuration
+      (target "/dev/mmcblk0")
+      (bootloader u-boot-cubietruck-bootloader)))
+  [...])
+```
+
+### The kernel modules
+
+In order for Guix to be able to load the system from the initramfs, it will 
probably need
+to load some modules, especially to access the root file system.  In my case, 
the SSD is
+on an ahci device, so I need a driver for it.  The kernel defines `ahci_sunxi` 
for that
+device on any sunxi board.  The SD card itself also requires two drivers: 
`sunxi-mmc` and
+`sd_mod`.
+
+Your own board may need other kernel modules to boot properly, however it is 
hard to discover
+them.  Guix can tell you when a module is missing in your configuration file 
if it is loaded
+as a module.  Most distros however build these modules in the kernel directly, 
so Guix cannot
+detect them reliably.  Another way to find what drivers might be needed is to 
look at the output
+of `dmesg`.  You'll find messages such as:
+
+```
+[    5.193684] sunxi-mmc 1c0f000.mmc: Got CD GPIO
+[    5.219697] sunxi-mmc 1c0f000.mmc: initialized, max. request size: 16384 KB
+[    5.221819] sunxi-mmc 1c12000.mmc: allocated mmc-pwrseq
+[    5.245620] sunxi-mmc 1c12000.mmc: initialized, max. request size: 16384 KB
+[    5.255341] mmc0: host does not support reading read-only switch, assuming 
write-enable
+[    5.265310] mmc0: new high speed SDHC card at address 0007
+[    5.268723] mmcblk0: mmc0:0007 SD32G 29.9 GiB
+```
+
+or
+
+```
+[    5.614961] ahci-sunxi 1c18000.sata: controller can't do PMP, turning off 
CAP_PMP
+[    5.614981] ahci-sunxi 1c18000.sata: forcing PORTS_IMPL to 0x1
+[    5.615067] ahci-sunxi 1c18000.sata: AHCI 0001.0100 32 slots 1 ports 3 Gbps 
0x1 impl platform mode
+[    5.615083] ahci-sunxi 1c18000.sata: flags: ncq sntf pm led clo only pio 
slum part ccc 
+[    5.616840] scsi host0: ahci-sunxi
+[    5.617458] ata1: SATA max UDMA/133 mmio [mem 0x01c18000-0x01c18fff] port 
0x100 irq 37
+[    5.933494] ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
+```
+
+Also note that module names are not consistent between what Guix expects and 
what is printed by
+dmesg, especially when the contain a "-" or a "_".  You will find the correct 
file name by building
+(or using a substitute for) linux-libre beforehand:
+
+```
+find `guix build linux-libre`/lib/modules -name '*mmc*'
+```
+
+Here, I could find a file named "kernel/drivers/mmc/host/sunxi-mmc.ko", hence 
the module
+name `sunxi-mmc`.  For the other driver, I found a 
"kernel/drivers/ata/ahci_sunxi.ko",
+hence the name `ahci_sunxi`, even if dmesg suggested `ahci-sunxi`.
+
+Once you have found the modules you want to load before mounting the root 
partition, you can
+add them to your operating-system declaration file:
+
+```scheme
+(initrd-modules (cons* "sunxi-mmc" "sd_mod" "ahci_sunxi" %base-initrd-modules))
+```
+
+Installing the Guix System
+--------------------------
+
+### Installing on another drive
+
+In my case, I wanted to install the system on an external SSD, while the 
currently running
+foreign distribution was running from the SD card.  What is nice with this 
setup is that,
+in case of real trouble (you SSD caught fire or broke), you can still boot 
from the old
+foreign system with an installed Guix and all your tools by re-flashing only 
the bootloader.
+
+In this scenario, we use the foreign system as we would the installer iso, 
using the manual
+installation procedures described in the manual.  Essentially, you have to 
partition your SSD
+to your liking, format your new partations and make sure to reference the 
correct partition
+for the root file system in your configuration file.  Then, initialize the 
system with:
+
+```bash
+mount /dev/sda1 /mnt
+mkdir /mnt/etc
+$EDITOR /mnt/etc/config.scm # create the configuration file
+guix system init /mnt/etc/config.scm /mnt
+```
+
+You can now reboot and enjoy your new Guix System!
+
+### Installing on the same drive
+
+Another option is to install the Guix System over the existing foreign 
distribution, replacing
+it entirely.  Note that the root filesystem for the new Guix System is the 
current root filesystem,
+so no need to mount it.  The following will initialize your system:
+
+```bash
+$EDITOR /etc/config.scm # create the configuration file
+guix system init /etc/config.scm /
+```
+
+Make sure to remove the files from the old system.  You should at least get 
rid of the
+old `/etc` directory, like so:
+
+```bash
+mv /etc{,.bak}
+mkdir /etc
+```
+
+Make sure there is an empty /etc, or the new system won't boot properly.  You 
can
+copy your config.scm to the new `/etc` directory.  You can now reboot and 
enjoy your
+new Guix System!
+
+About GNU Guix
+--------------
+
+[GNU Guix](https://www.gnu.org/software/guix) is a transactional package
+manager for the GNU system.  The Guix System Distribution or GuixSD is
+an advanced distribution of the GNU system that relies on GNU Guix and
+[respects the user's
+freedom](https://www.gnu.org/distros/free-system-distribution-guidelines.html).
+
+In addition to standard package management features, Guix supports
+transactional upgrades and roll-backs, unprivileged package management,
+per-user profiles, and garbage collection.  Guix uses low-level
+mechanisms from the Nix package manager, except that packages are
+defined as native [Guile](https://www.gnu.org/software/guile) modules,
+using extensions to the [Scheme](http://schemers.org) language.  GuixSD
+offers a declarative approach to operating system configuration
+management, and is highly customizable and hackable.
+
+GuixSD can be used on an i686, x86_64 and armv7 machines.  It is also
+possible to use Guix on top of an already installed GNU/Linux system,
+including on mips64el and aarch64.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]