https://guix.gnu.org/feeds/blog/arm.atomGNU Guix — Blog — ARMfeed author nameGNU Guixhttps://guix.gnu.org/themes/initial/img/icon.png2024-03-15T23:01:37Zhttps://guix.gnu.org/blog/2019/guix-on-an-arm-board//Guix on an ARM BoardJulien Lepiller2019-11-27T12:00:00Z2019-11-27T12:00:00Z 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…<p>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.</p><p>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
<a href="https://guix.gnu.org/blog/2017/porting-guixsd-to-armv7/">mentioned</a> it is
possible to generate an installation image yourself, if your board is supported.</p><p>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 <a href="http://guix.gnu.org/manual/en/html_node/Binary-Installation.html">installer script</a>.
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.</p><p>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.</p><h2>Writing a configuration file for an ARM board</h2><p>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.</p><h3>The root file system</h3><p>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:</p><pre><code class="language-scheme">(file-systems
(cons* (file-system
(mount-point "/")
(device "/dev/sda1")
(type "ext4"))
%base-file-systems))</code></pre><p>If you instead want to install the root file system on an SD card, you'll need
to find its device name, usually <code>/dev/mmcblk0</code> and the partition number. The
device corresponding to the first partition should be <code>/dev/mmcblk0p1</code>. In that
case, you would have:</p><pre><code class="language-scheme">(file-systems
(cons* (file-system
(mount-point "/")
(device "/dev/mmcblk0p1")
(type "ext4"))
%base-file-systems))</code></pre><h3>The bootloader</h3><p>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.</p><p>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.</p><p>Guix already define a few u-boot based bootloaders, such as <code>u-boot-a20-olinuxino-lime-bootloader</code>
or <code>u-boot-pine64-plus-bootloader</code> among others. If your board already has a <code>u-boot-*-bootloader</code>
defined in <code>(gnu bootloader u-boot)</code>, you're lucky and you can skip this part of the article!</p><p>Otherwise, maybe the bootloader package is defined in <code>(gnu packages bootloaders)</code>, such as
the <code>u-boot-cubietruck</code> package. If so, you're a bit lucky and you can skip creating your
own package definition.</p><p>If your board doesn't have a <code>u-boot-*</code> package defined, you can create one. It could be
as simple as <code>(make-u-boot-package "Cubietruck" "arm-linux-gnueabihf")</code>. 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 <code>u-boot-puma-rk3399</code> for instance: it needs additional phases to install
firmware.</p><p>You can add the package definition to your operating system configuration file like so,
before the operating-system declaration:</p><pre><code class="language-scheme">(use-modules (gnu packages bootloaders))
(define u-boot-my-board
(make-u-boot-package "Myboard" "arm-linux-gnueabihf"))
(operating-system
[...])</code></pre><p>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.</p><p>The Cubietruck happens to be based on an allwinner core, for which there is already a
u-boot bootloader definition <code>u-boot-allwinner-bootloader</code>. 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:</p><pre><code class="language-scheme">(define u-boot-cubietruck-bootloader
(bootloader
(inherit u-boot-allwinner-bootloader)
(package u-boot-cubietruck)))</code></pre><p>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 <code>/dev/mmcblk0</code> on my device.</p><p>We can now put everything together like so:</p><pre><code class="language-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)))
[...])</code></pre><h3>The kernel modules</h3><p>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 <code>ahci_sunxi</code> for that
device on any sunxi board. The SD card itself also requires two drivers: <code>sunxi-mmc</code> and
<code>sd_mod</code>.</p><p>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 <code>dmesg</code>. You'll find messages such as:</p><pre><code>[ 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</code></pre><p>or</p><pre><code>[ 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)</code></pre><p>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:</p><pre><code>find `guix build linux-libre`/lib/modules -name '*mmc*'</code></pre><p>Here, I could find a file named "kernel/drivers/mmc/host/sunxi-mmc.ko", hence the module
name <code>sunxi-mmc</code>. For the other driver, I found a "kernel/drivers/ata/ahci_sunxi.ko",
hence the name <code>ahci_sunxi</code>, even if dmesg suggested <code>ahci-sunxi</code>.</p><p>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:</p><pre><code class="language-scheme">(initrd-modules (cons* "sunxi-mmc" "sd_mod" "ahci_sunxi" %base-initrd-modules))</code></pre><h2>Installing the Guix System</h2><h3>Installing on another drive</h3><p>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.</p><p>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:</p><pre><code class="language-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</code></pre><p>You can now reboot and enjoy your new Guix System!</p><h3>Installing on the same drive</h3><p>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:</p><pre><code class="language-bash">$EDITOR /etc/config.scm # create the configuration file
guix system init /etc/config.scm /</code></pre><p>Make sure to remove the files from the old system. You should at least get rid of the
old <code>/etc</code> directory, like so:</p><pre><code class="language-bash">mv /etc{,.bak}
mkdir /etc</code></pre><p>Make sure there is an empty /etc, or the new system won't boot properly. You can
copy your config.scm to the new <code>/etc</code> directory. You can now reboot and enjoy your
new Guix System!</p><h4>About GNU Guix</h4><p><a href="https://www.gnu.org/software/guix">GNU Guix</a> is a transactional package
manager and an advanced distribution of the GNU system that <a href="https://www.gnu.org/distros/free-system-distribution-guidelines.html">respects
user
freedom</a>.
Guix can be used on top of any system running the kernel Linux, or it
can be used as a standalone operating system distribution for i686,
x86_64, ARMv7, and AArch64 machines.</p><p>In addition to standard package management features, Guix supports
transactional upgrades and roll-backs, unprivileged package management,
per-user profiles, and garbage collection. When used as a standalone
GNU/Linux distribution, Guix offers a declarative, stateless approach to
operating system configuration management. Guix is highly customizable
and hackable through <a href="https://www.gnu.org/software/guile">Guile</a>
programming interfaces and extensions to the
<a href="http://schemers.org">Scheme</a> language.</p>https://guix.gnu.org/blog/2019/guix-days-bootstrapping-arm//Guix Days: Bootstrapping ARMChris Marusich2019-02-22T00:00:00Z2019-02-22T00:00:00Z During the Guix
Days before
FOSDEM , some of us discussed bootstrapping
on ARM architectures. We focused on how to port Mes to ARM. This
post consists of notes from that discussion. Recap: i686/x86_64 Reduced Binary Seed We started our discussion by reviewing the current status for
i686-linux and x86_64-linux. Jan (janneke) Nieuwenhuizen gave a
similar summary a few
days later at FOSDEM, and you can read the slides
online . Previously, the size of Guix's binary seed totaled about 250 MB. Now,
on the
core-updates
branch, it's been reduced to about 130 MB.…<p>During the <a href="https://libreplanet.org/wiki/Group:Guix/FOSDEM2019">Guix
Days</a> before
<a href="https://fosdem.org/2019/">FOSDEM</a>, some of us discussed bootstrapping
on ARM architectures. We focused on how to port Mes to ARM. This
post consists of notes from that discussion.</p><h4>Recap: i686/x86_64 Reduced Binary Seed</h4><p>We started our discussion by reviewing the current status for
i686-linux and x86_64-linux. Jan (janneke) Nieuwenhuizen gave <a href="https://fosdem.org/2019/schedule/event/gnumes/">a
similar summary</a> a few
days later at FOSDEM, and you can <a href="https://fosdem.org/2019/schedule/event/gnumes/attachments/slides/2848/export/events/attachments/gnumes/slides/2848/gnu_mes_fosdem19_v2.pdf">read the slides
online</a>.</p><p>Previously, the size of Guix's binary seed totaled about 250 MB. Now,
on the
<a href="http://git.savannah.gnu.org/cgit/guix.git/log/?h=core-updates">core-updates</a>
branch, it's been reduced to about 130 MB. This is nearly a 50%
reduction in size, which is great progress! Using this 130 MB reduced
binary seed, it's currently possible to bootstrap Guix for both
i686-linux and x86_64-linux.</p><p>To bootstrap x86_64-linux, we actually "cheat" and bootstrap from the
i686-linux bootstrap binaries. This is possible because an
x86_64-linux system can natively run i686-linux executables, and also
because Guix automatically <a href="http://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages/commencement.scm?id=63d4ef52ebad4157817d56ccbe974da8fff81929#n1562">cross-compiles for the host
platform</a>
during the bootstrap process. In other words, on an x86_64-linux
system, Guix uses the i686-linux bootstrap binaries to build a
cross-compilation toolchain, which it then uses to build a final,
normal x86_64-linux toolchain. Guix then uses this final toolchain to
build everything else for the x86_64-linux system.</p><p>That's great news for owners of i686 and x86_64 machines! But what
about ARM? Although we could cross-compile the bootstrap binaries for
ARM from an x86_64 machine, this isn't great because it would increase
the number of things a person or organization would have to verify in
order to audit the system. Perhaps more importantly, it would force
owners of ARM machines to implicitly trust an x86_64 machine. The
dominant vendors of CPUs implementing the x86_64 architecture, Intel
and AMD, both include a management engine in many of their products,
which represents a <a href="https://www.fsf.org/blogs/sysadmin/the-management-engine-an-attack-on-computer-users-freedom">serious risk to user
freedom</a>.</p><p>In the short term, cross-compilation is better than nothing, but in
the long term, we'd prefer to bootstrap ARM without cross-compiling
from another architecture. Concretely, we'll need to complete at
least the following tasks.</p><h4>TODO: Implement a Mes backend for ARM</h4><p>We need to implement a new Mes backend for an ARM architecture. We
should choose an ARM instruction set that can work on a variety of ARM
platforms with minimal fuss. The following candidates were suggested:</p><ul><li><p>ARMv4. We would need to avoid unaligned memory accesses because
they can behave in different ways depending on the CPU. This is the
latest version of ARM that GCC 2.95 supports, which matters because
<a href="http://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages/commencement.scm?id=63d4ef52ebad4157817d56ccbe974da8fff81929#n510">GCC 2.95 is the latest version that the Mes C Library
supports</a>.</p></li><li><p>ARMv7. If we avoid extensions and unaligned memory accesses, it
might still work for our needs. It was mentioned in the session
that TinyCC will probably work with either ARMv4 or ARMv7. In
TinyCC, as a first step, it's probably fine to depend on ARMv7 since
it's the most common recent architecture version (and it is more
forgiving). Later, if we remove unaligned accesses, it will also
work on ARMv4 and thus on basically all ARM CPUs.</p></li></ul><p>After the session concluded, Danny Milosavljevic committed some
changes to <a href="http://git.savannah.gnu.org/cgit/mes.git/log/?h=wip-arm">the wip-arm branch of
mes</a> which
enabled many of the tests to pass - but some tests still fail, and you
can help finish the work!</p><h4>TODO: Port mescc-tools to ARM, also</h4><p>The mes project depends upon the
<a href="https://savannah.nongnu.org/projects/mescc-tools">mescc-tools</a>
project, which also must be ported. The mescc-tools project contains
an M1 macro assembler, which would need to be extended to support ARM
branches. Currently, ARM branches are very broken.</p><h4>TODO: Improve Guix integration and merge core-updates</h4><p>Even if we had a new Mes backend and mescc-tools for ARM, there would
still be more to do. The Guix integration is not quite complete - the
<a href="http://git.savannah.gnu.org/cgit/guix.git/log/?h=core-updates">core-updates</a>
branch still needs to be merged with
<a href="http://git.savannah.gnu.org/cgit/guix.git/log/?h=master">master</a>, and
we'll need to fix any problems that arise. Even on i686-linux, the
bottom of the bootstrap path is incomplete. Preliminary Guix code
exists on the
<a href="http://git.savannah.gnu.org/cgit/guix.git/log/?h=wip-bootstrap">wip-bootstrap</a>
branch to achieve a scheme-only bootstrap, but help would be welcome!</p><h4>You can help!</h4><p>In summary, you can help the Mes project by doing any of the following
things:</p><ul><li><p>Help implement an ARMv7 (or ARMv4) backend for Mes! This entails
machine code and assembly. It should be fun for anyone who wants to
play around close to the metal.</p></li><li><p>Help port mescc-tools to ARM. This entails <a href="http://git.savannah.nongnu.org/cgit/mescc-tools.git/tree/HACKING?id=0a930aa47389ec842bcbe8a270ab2921a36f62d9#n33">writing an assembler in
M1 macro
code</a>
and probably goes hand-in-hand with work on Mes itself.</p></li><li><p>Help firm up
<a href="http://git.savannah.gnu.org/cgit/guix.git/log/?h=core-updates">core-updates</a>
and merge it to
<a href="http://git.savannah.gnu.org/cgit/guix.git/log/?h=master">master</a>!
This involves Guix package definitions and troubleshooting build
failures. It should be fun for anyone who wants to learn more about
the bigger picture of how Guix bootstraps all of its software from
the new reduced binary seed.</p></li><li><p>Help complete the i686-linux and x86_64-linux bootstrap. You can
hack on the bleeding edge scheme code in the
<a href="http://git.savannah.gnu.org/cgit/guix.git/log/?h=wip-bootstrap">wip-bootstrap</a>
branch, or maybe you can help extend the bootstrap path all the way
down to <a href="https://github.com/oriansj/stage0">approximately 500 bytes of auditable assembly
code</a>!</p></li></ul><p>There's still plenty of meaty work left to be done! If you're
interested, <a href="http://bootstrappable.org/who.html">get in touch</a> and
we'll help you get started.</p><h4>Think Big: Bootstrapping without an OS</h4><p>In addition to the immediate tasks necessary for porting Mes to ARM,
we also took some time to think about the long term hopes and dreams
of the bootstrappable project.</p><p>We discussed how in the long term, in parallel with the aforementioned
tasks, it should be possible to investigate how to bootstrap an entire
system without relying on a OS or even a kernel running on the
machine. For example, one can imagine loading the transitive closure
of source (including a tiny, human-readable machine code program to
kick off the entire process) into a computer as a kind of "firmware
image". When the computer runs, it would execute this "firmware
image" and eventually produce a fully bootstrapped system.</p><h4>Think Bigger: Bootstrapping Hardware</h4><p>We also briefly talked about how even after we achieve full source
software bootstrap, we will still need to tackle the problem of
"hardware bootstrap". It isn't clear what form this will eventually
take, but surely <a href="https://www.gnu.org/philosophy/free-hardware-designs.en.html">free hardware
design</a>
will play an important role in ensuring that we can trust our
hardware, too.</p><h4>About Bootstrappable Builds and Mes</h4><p>Software is bootstrappable when it does not depend on a binary seed
that cannot be built from source. Software that is not
bootstrappable - even if it is free software - is a serious security
risk
<a href="https://www.ece.cmu.edu/~ganger/712.fall02/papers/p761-thompson.pdf">for</a>
<a href="https://manishearth.github.io/blog/2016/12/02/reflections-on-rusting-trust/">a</a>
<a href="https://www.quora.com/What-is-a-coders-worst-nightmare/answer/Mick-Stute">variety</a>
<a href="http://blog.regehr.org/archives/1241">of</a>
<a href="https://www.alchemistowl.org/pocorgtfo/pocorgtfo08.pdf">reasons</a>.
The <a href="https://bootstrappable.org/">Bootstrappable Builds</a> project aims
to reduce the number and size of binary seeds to a bare minimum.</p><p><a href="https://www.gnu.org/software/mes/">GNU Mes</a> is closely related to the
Bootstrappable Builds project. Mes aims to create an entirely
source-based bootstrapping path for the Guix System and other
interested GNU/Linux distributions. The goal is to start from a
minimal, easily inspectable binary (which should be readable as
source) and bootstrap into something close to R6RS Scheme.</p><p>Currently, Mes consists of a mutual self-hosting scheme interpreter
and C compiler. It also implements a C library. Mes, the scheme
interpreter, is written in about 5,000 lines of code of simple C.
MesCC, the C compiler, is written in scheme. Together, Mes and MesCC
can compile <a href="http://gitlab.com/janneke/tinycc">a lightly patched
TinyCC</a> that is self-hosting. Using
this TinyCC and the Mes C library, it is possible to bootstrap the
entire Guix System for i686-linux and x86_64-linux.</p><h4>About GNU Guix</h4><p><a href="https://www.gnu.org/software/guix">GNU Guix</a> is a transactional package
manager and an advanced distribution of the GNU system that <a href="https://www.gnu.org/distros/free-system-distribution-guidelines.html">respects
user
freedom</a>.
Guix can be used on top of any system running the kernel Linux, or it
can be used as a standalone operating system distribution for i686,
x86_64, ARMv7, and AArch64 machines.</p><p>In addition to standard package management features, Guix supports
transactional upgrades and roll-backs, unprivileged package management,
per-user profiles, and garbage collection. When used as a standalone
GNU/Linux distribution, Guix offers a declarative, stateless approach to
operating system configuration management. Guix is highly customizable
and hackable through <a href="https://www.gnu.org/software/guile">Guile</a>
programming interfaces and extensions to the
<a href="http://schemers.org">Scheme</a> language.</p>https://guix.gnu.org/blog/2019/qa-on-non-intel-at-guix-days//QA on non-Intel at Guix DaysEfraim Flashner2019-02-07T09:30:00Z2019-02-07T09:30:00Z During the second day of Guix Days (a FOSDEM fringe
event ) we split up into smaller working groups
based on our areas of interest. I led a group which aimed to address some of
the package issues which exist on non-Intel architectures. Of course not
everyone has access to an ARM board, but with the
qemu-binfmt-service
service it is possible to use QEMU and the binfmt_misc functionality of the
Linux kernel to emulate these systems. Many have reported that this system
emulation is comparable in speed to many of the available ARM boards on the
market. Yet another possibility…<p>During the second day of Guix Days (a FOSDEM <a href="https://fosdem.org/2019/fringe">fringe
event</a>) we split up into smaller working groups
based on our areas of interest. I led a group which aimed to address some of
the package issues which exist on non-Intel architectures. Of course not
everyone has access to an ARM board, but with the
<a href="https://www.gnu.org/software/guix/manual/en/html_node/Virtualization-Services.html#index-binfmt_005fmisc"><code>qemu-binfmt-service</code></a>
service it is possible to use QEMU and the <code>binfmt_misc</code> functionality of the
Linux kernel to emulate these systems. Many have reported that this system
emulation is comparable in speed to many of the available ARM boards on the
market. Yet another possibility would be to do the hacking on an x86_64 system
and, when we had a working prototype, to test it with QEMU or on actual ARM
hardware.</p><p>Our group decided to tackle Go, which was lacking support in Guix on armhf and
aarch64. Upon checking the build logs from Cuirass and the source code for Go we
determined that Go did indeed require the <code>gold</code> linker from the GNU Binutils. We
didn't want to modify the copy of Binutils in Guix since it is part of our
bootstrap story, so we quickly put together a new package definition which added
the configure flag to enable <code>gold</code>.</p><pre><code class="language-scheme">(define-public binutils-gold
(package
(inherit binutils)
(name "binutils-gold")
(arguments
(substitute-keyword-arguments (package-arguments binutils)
((#:configure-flags flags)
`(cons "--enable-gold=default" ,flags))))))</code></pre><p>This was an obvious first step, and one which we knew would fail. Had it been
this easy <code>gold</code> would have been enabled back in 2012 when it was first added.
Our error came in the form of one of the binaries not being able to link against
<code>libstdc++.so</code>, which is in the <code>gcc:lib</code> output. This was quickly added and we
were off and building again.</p><pre><code class="language-scheme">(define-public binutils-gold
(package
(inherit binutils)
(name "binutils-gold")
(arguments
(substitute-keyword-arguments (package-arguments binutils)
((#:configure-flags flags)
`(cons "--enable-gold=default" ,flags))))
(inputs
`(("gcc:lib" ,gcc "lib")))))</code></pre><p>Once again this failed. What were we missing? The correct paths were included,
the file was indeed in the <code>gcc:lib</code> output. We inspected the original
<code>binutils</code> package again noticed that it was built against a static libgcc, so
of course it wouldn't find the shared library. In order to work quickly we
copied the configure flags rather than inheriting them from <code>binutils</code> and
tried our build again.</p><pre><code class="language-scheme">(define-public binutils-gold
(package
(inherit binutils)
(name "binutils-gold")
(arguments
(substitute-keyword-arguments (package-arguments binutils)
((#:configure-flags flags)
`(cons* "--enable-gold=default"
"--enable-new-dtags"
"--with-lib-path=/no-ld-lib-path"
"--enable-install-libbfd"
"--enable-deterministic-archives"))))
(inputs
`(("gcc:lib" ,gcc "lib")))))</code></pre><p>This time we made it through the full build phase and we knew we were almost
there. Our enthusiasm was quickly dampened when we got the error during the
tests: <code>unable to find the 'dc' program</code>. What is this <code>dc</code> program? This isn't
any package any of us had heard of before. It definitely wasn't packaged in
Guix. A quick <code>apt-cache search dc</code> search in Ubuntu showed they didn't have
package either. A second search of Ubuntu, <code>apt-file search dc | grep '/bin/dc'</code>
quickly showed us it was in the <code>bc</code> package, and soon we were building
<code>binutils-gold</code> again.</p><pre><code class="language-scheme">(define-public binutils-gold
(package
(inherit binutils)
(name "binutils-gold")
(arguments
(substitute-keyword-arguments (package-arguments binutils)
((#:configure-flags flags)
`(cons* "--enable-gold=default"
"--enable-new-dtags"
"--with-lib-path=/no-ld-lib-path"
"--enable-install-libbfd"
"--enable-deterministic-archives"))))
(native-inputs
`(("bc" ,bc)))
(inputs
`(("gcc:lib" ,gcc "lib")))))</code></pre><p>Approaching the end of the <code>check</code> phase we soon ran into another error, there
was an unpatched <code>/bin/sh</code> somewhere in the source code which was generated
during the check phase. Based on the build logs we were able to track down
approximately where the code should be, so we downloaded the source <code>tar xf $(guix build --source binutils)</code> and started looking. There were many obvious
<code>/bin/sh</code> calls which we cross-referenced with the build logs and the
<code>patch-source-shebangs</code> phase, and this left us with some code in
<code>gold/Makefile.in</code>, which by default is not included in the
<code>patch-source-shebangs</code> and would need to be fixed manually.</p><pre><code class="language-scheme">(define-public binutils-gold
(package
(inherit binutils)
(name "binutils-gold")
(arguments
`(#:phases
(modify-phases %standard-phases
(add-after 'patch-source-shebangs 'patch-more-shebangs
(lambda _
(substitute* "gold/Makefile.in"
(("/bin/sh") (which "sh")))
#t)))
,@(substitute-keyword-arguments (package-arguments binutils)
((#:configure-flags flags)
`(cons* "--enable-gold=default"
"--enable-new-dtags"
"--with-lib-path=/no-ld-lib-path"
"--enable-install-libbfd"
"--enable-deterministic-archives")))))
(native-inputs
`(("bc" ,bc)))
(inputs
`(("gcc:lib" ,gcc "lib")))))</code></pre><p>One more build cycle later and we did it! <code>/gnu/store/…-binutils-gold-2.31.1</code>
existed! We now did two things, we copied our patch over to an aarch64 build
machine and we started cleaning up our package definition on our x86_64 build
machine, where we knew we had a working package definition.</p><pre><code class="language-scheme">(define-public binutils-gold
(package
(inherit binutils)
(name "binutils-gold")
(arguments
`(#:phases
(modify-phases %standard-phases
(add-after 'patch-source-shebangs 'patch-more-shebangs
(lambda _
(substitute* "gold/Makefile.in"
(("/bin/sh") (which "sh")))
#t)))
,@(substitute-keyword-arguments (package-arguments binutils)
((#:configure-flags flags)
`(cons* "--enable-gold=default"
(delete "LDFLAGS=-static-libgcc" ,flags))))))
(native-inputs
`(("bc" ,bc)))
(inputs
`(("gcc:lib" ,gcc "lib")))))</code></pre><p>Fortunately for us the changes in the code worked on x86_64 and we still got a
working <code>binutils-gold</code> output. On our aarch64 side the build was progressing
nicely and everything seemed fine... until we suddenly were presented with big
red errors about unrelocatable code. How could it? Everything was working so
well! Undeterred, we built the source again, this time targeting armhf and were
unfortunately presented with similar errors. Deciding to address the test
failures later (It's ARM! It's not as well tested as other architectures!
Right?) we disabled the tests and unsurprisingly <code>binutils-gold</code> built on both
aarch64 and armhf.</p><pre><code class="language-scheme">(define-public binutils-gold
(package
(inherit binutils)
(name "binutils-gold")
(arguments
`(#:phases
(modify-phases %standard-phases
(add-after 'patch-source-shebangs 'patch-more-shebangs
(lambda _
(substitute* "gold/Makefile.in"
(("/bin/sh") (which "sh")))
#t)))
,@(substitute-keyword-arguments (package-arguments binutils)
((#:tests? _ #f) #f)
((#:configure-flags flags)
`(cons* "--enable-gold=default"
(delete "LDFLAGS=-static-libgcc" ,flags))))))
(native-inputs
`(("bc" ,bc)))
(inputs
`(("gcc:lib" ,gcc "lib")))))</code></pre><p>Now for the real test. Due to bootstrapping issues with Go and aarch64, aarch64
uses Go@1.4 built for armhf. Go@1.11 failed to build until now because it was
missing the <code>gold</code> linker. Surely using the <code>gold</code> linker would be a good test
if our package worked. Since Go for aarch64 is 'more complex' due to the
bootstrapping using armhf's Go, we decided to test armhf first. <code>binutils-gold</code>
was added and our build started.</p><pre><code class="language-diff"> (native-inputs
`(("go" ,go-1.4)
+ ,@(match (%current-system)
+ ((or "armhf-linux" "aarch64-linux")
+ `(("gold" ,binutils-gold)))
+ (_ `()))
,@(package-native-inputs go-1.4)))</code></pre><p>First build, success! <code>/gnu/store/…-go-1.11.5</code> exists! OK, but does it
actually work? <code>guix build syncthing --system=armhf-linux</code>.
<code>/gnu/store/…-syncthing-1.0.0</code> exists too! A quick check of <code>guix refresh --list-dependent go@1.4</code> showed that we had unlocked 176 new packages for armhf.
Even better, since they had all failed by default due to go@1.11 failing to
build, for each package that did build meant one fewer package which failed to
build which should take a big bite out of our build failures.</p><p>Our next test was syncthing for aarch64. <code>/gnu/store/…-go-1.11.5</code> exists!
<code>/gnu/store/…-syncthing-1.0.0</code> ... does not. "<code>unknown architecture 'armv7-a'</code>."
It seems that Go is confused which architecture it is building for.
Unfortunately we were reaching the end of our time for hacking, so that will
have to wait for another day. All that was left now was the test failures on
<code>binutils-gold</code> for the ARM systems. Some attempts at cargo-culting other code
failed (per-architecture tests we had and overriding flags in
<code>substitute-keyword-arguments</code> we had, but not together), but after some attempts
we were able to create a working package definition we were happy with.</p><pre><code class="language-scheme">(define-public binutils-gold
(package
(inherit binutils)
(name "binutils-gold")
(arguments
`(#:phases
(modify-phases %standard-phases
(add-after 'patch-source-shebangs 'patch-more-shebangs
(lambda _
(substitute* "gold/Makefile.in"
(("/bin/sh") (which "sh")))
#t)))
,@(substitute-keyword-arguments (package-arguments binutils)
; Upstream is aware of unrelocatable test failures on arm*.
((#:tests? _ #f)
(if (any (cute string-prefix? <> (or (%current-target-system)
(%current-system)))
'("i686" "x86_64"))
'#t '#f))
((#:configure-flags flags)
`(cons* "--enable-gold=default"
(delete "LDFLAGS=-static-libgcc" ,flags))))))
(native-inputs
`(("bc" ,bc)))
(inputs
`(("gcc:lib" ,gcc "lib")))))</code></pre><p>This patch was pushed to the master branch as
<a href="https://git.savannah.gnu.org/cgit/guix.git/commit/?id=28317d499034b00cf1f08a9efd39bd2bc3425b19">28317d499034b00cf1f08a9efd39bd2bc3425b19</a>,
and the
<a href="https://git.savannah.gnu.org/cgit/guix.git/commit/?id=1009e6e7ecc00b72a51778e90b0212ccc33bfa7a">commit</a>
following uses it as a native-input for Go@1.9 and Go@1.11. Go@1.4 was added in
<a href="https://git.savannah.gnu.org/cgit/guix.git/commit/?id=7a2941a83ee8ecac9ca7a3a076b1231805b39bbd">June
2016</a>
and Go@1.6 that
<a href="https://git.savannah.gnu.org/cgit/guix.git/commit/?id=ec91bcb500a2540b91fca6fd2a93a0562c427712">August</a>,
with our first go packages being added in <a href="https://git.savannah.gnu.org/cgit/guix.git/commit/?id=56a37713c3fada3010666278eb37873980746572">October
2017</a>.
That same
<a href="https://git.savannah.gnu.org/cgit/guix.git/commit/?id=dda785f66081871501236722f68c8eaa31103186">October</a>
Go@1.4 had support limited to Intel and armhf and in October 2018, in an effort
to work toward a resolution, a
<a href="https://git.savannah.gnu.org/cgit/guix.git/commit/?id=2ab321ca37d1c00c1540d78d587226d3d487b2d4">patch</a>
was added to have aarch64 use Go@1.4 built for armhf for it's bootstrap path.
Basically since the addition of the Go language support into Guix there was not
a time when it was usable on armhf or aarch64. Hopefully we will soon finish
getting full Go support on aarch64 and we can move all 352 dependents of Go@1.4
from "failing" to "succeeding" and have these architectures better supported.</p><h4>About GNU Guix</h4><p><a href="https://www.gnu.org/software/guix">GNU Guix</a> is a transactional package
manager and an advanced distribution of the GNU system that <a href="https://www.gnu.org/distros/free-system-distribution-guidelines.html">respects
user
freedom</a>.
Guix can be used on top of any system running the kernel Linux, or it
can be used as a standalone operating system distribution for i686,
x86_64, ARMv7, and AArch64 machines.</p><p>In addition to standard package management features, Guix supports
transactional upgrades and roll-backs, unprivileged package management,
per-user profiles, and garbage collection. When used as a standalone
GNU/Linux distribution, Guix offers a declarative, stateless approach to
operating system configuration management. Guix is highly customizable
and hackable through <a href="https://www.gnu.org/software/guile">Guile</a>
programming interfaces and extensions to the
<a href="http://schemers.org">Scheme</a> language.</p>https://guix.gnu.org/blog/2018/guix-on-android//Guix on Android!Julien Lepiller2018-04-24T10:00:00Z2018-04-24T10:00:00Z Last year I thought to myself: since my phone is just a computer running
an operating system called Android (or Replicant !),
and that Android is based on a Linux
kernel, it's just another foreign distribution I could install GNU Guix
on ,
right? It turned out it was absolutely the case. Today I was
reminded on IRC of my attempt last year at installing GNU Guix on my
phone. Hence this blog post. I'll try to give you all the knowledge and
commands required to install it on your own Android device. Requirements First of all, you will need an Android…<p>Last year I thought to myself: since my phone is just a computer running
an operating system called Android (or <a href="https://replicant.us/">Replicant</a>!),
and that Android is based on a Linux
kernel, it's just <a href="https://www.gnu.org/software/guix/manual/en/html_node/Installation.html">another foreign distribution I could install GNU Guix
on</a>,
right? It turned out it was absolutely the case. Today I was
reminded on IRC of my attempt last year at installing GNU Guix on my
phone. Hence this blog post. I'll try to give you all the knowledge and
commands required to install it on your own Android device.</p><h4>Requirements</h4><p>First of all, you will need an Android or Replicant device. Just like any
installation of GNU Guix, you will need root access on that device.
Unfortunately, in the Android world this is not very often the case by
default. Then, you need a cable to connect your computer to your phone.
Once the hardware is in place, you will need <code>adb</code> (the Android
Debugging Bridge):</p><pre><code>guix package -i adb</code></pre><h4>Exploring the device</h4><p>Every Android device has its own partioning layout, but basically it
works like this:</p><ol><li>A boot partition for booting the device</li><li>A recovery partition for booting the device in recovery mode</li><li>A data partition for user data, including applications, the user
home, etc</li><li>A system partition with the base system and applications. This is the
place where phone companies put their own apps so you can't remove
them</li><li>A vendor partition for drivers</li><li>Some other partitions</li></ol><p>During the boot process, the bootloader looks for the boot partition.
It doesn't contain a filesystem, but only a gzipped cpio archive (the
initramfs) and the kernel. The bootloader loads them in memory and
the kernel starts using the initramfs. Then, the init system from this
initramfs loads partitions in their respective directories: the system
partition in <code>/system</code>, the vendor partition in <code>/vendor</code> and the data
partition in <code>/data</code>. Other partitions may be loaded.</p><p>And that's it. Android's root filesystem is actually the initramfs so
any modification to its content will be lost after a reboot.
Thankfully(?), Android devices are typically not rebooted often.</p><p>Another issue is the Android C library (libc), called Bionic: it has
less functionality and works completely differently from the GNU libc.
Since Guix is built with the Glibc, we will need to do something to
make it work on our device.</p><h4>Installing the necessary files</h4><p>We will follow the <a href="https://www.gnu.org/software/guix/manual/en/html_node/Binary-Installation.html">binary installation
guide</a>.
My hardware is aarch64, so I download the corresponding binary release.</p><p>Now it's time to start using adb. Connect your device and obtain root
priviledges for adb. You may have to authorize root access to the
computer from your phone:</p><pre><code class="language-bash">adb root</code></pre><p>Now, we will transfer some necessary files:</p><pre><code class="language-bash">adb push guix-binary-* /data
# Glibc needs these two files for networking.
adb push /etc/protocols /system/etc/
adb push /etc/services /system/etc/
# … and this one to perform DNS queries. You probably need
# to change nameservers if you use mobile data.
adb push /etc/resolv.conf /system/etc/</code></pre><p>Note that some devices may not have <code>/system/etc</code> available. In that
case, <code>/etc</code> may be available. If none is available, create the
directory by using <code>adb shell</code> to get a shell on your device, then
push the files to that new directory.</p><h4>Installing Guix itself</h4><p>Now all the necessary files are present on the device, so we can connect
to a shell on the device:</p><pre><code class="language-bash">adb shell</code></pre><p>From that shell, we will install Guix. The root filesystem is mounted
read-only as it doesn't make sense to modify it. Remember: it's a RAM
filesystem. Remount-it read-write and create necessary directories:</p><pre><code class="language-bash">mount -o remount,rw /
mkdir /gnu /var
mount -o remount,ro /</code></pre><p>Now, we can't just copy the content of the binary archive to these
folders because the initramfs has a limited amount of space. Guix
complains when <code>/gnu</code> or <code>/gnu/store</code> is a symlink. One solution consists in
installing the content of the binary tarball on an existing partition
(because you can't modify the partition layout easily) that has enough
free space, typically the data partition. Then this partition is mounted
on <code>/var</code> and <code>/gnu</code>.</p><p>Before that, you will need to find out what the data partition is in
your system. Simply run <code>mount | grep /data</code> to see what partition
was mounted.</p><p>We mount the partition, extract the tarball and move the contents to
their final location:</p><pre><code class="language-bash">mount /dev/block/bootdevice/by-name/userdata /gnu
mount /dev/block/bootdevice/by-name/userdata /var
cd /data
tar xf guix-binary-...
mv gnu/store .
mv var/guix .
rmdir gnu
rmdir var</code></pre><p>Finally, we need to <a href="https://www.gnu.org/software/guix/manual/en/html_node/Build-Environment-Setup.html">create users and groups</a> for Guix to work
properly. Since Bionic doesn't use <code>/etc/passwd</code> or <code>/etc/group</code>
to store the users, we need to create them from scratch. Note
the addition of the root user and group, as well as the <code>nobody</code>
user.</p><pre><code class="language-bash"># create guix users and root for glibc
cat > /etc/passwd << EOF
root:x:0:0:root:/data:/sbin/sh
nobody:x:99:99:nobody:/:/usr/bin/nologin
guixbuilder01:x:994:994:Guix build user 01:/var/empty:/usr/bin/nologin
guixbuilder02:x:993:994:Guix build user 02:/var/empty:/usr/bin/nologin
guixbuilder03:x:992:994:Guix build user 03:/var/empty:/usr/bin/nologin
guixbuilder04:x:991:994:Guix build user 04:/var/empty:/usr/bin/nologin
guixbuilder05:x:990:994:Guix build user 05:/var/empty:/usr/bin/nologin
guixbuilder06:x:989:994:Guix build user 06:/var/empty:/usr/bin/nologin
guixbuilder07:x:988:994:Guix build user 07:/var/empty:/usr/bin/nologin
guixbuilder08:x:987:994:Guix build user 08:/var/empty:/usr/bin/nologin
guixbuilder09:x:986:994:Guix build user 09:/var/empty:/usr/bin/nologin
guixbuilder10:x:985:994:Guix build user 10:/var/empty:/usr/bin/nologin
EOF
cat > /etc/group << EOF
root:x:0:root
guixbuild:x:994:guixbuilder01,guixbuilder02,guixbuilder03,guixbuilder04,guixbuilder05,guixbuilder06,guixbuilder07,guixbuilder08,guixbuilder09,guixbuilder10
EOF</code></pre><h4>Running Guix</h4><p>First, we install the root profile somewhere:</p><pre><code class="language-bash">export HOME=/data
ln -sf /var/guix/profiles/per-user/root/guix-profile \
$HOME/.guix-profile</code></pre><p>Now we can finally run the Guix daemon. Chrooting is impossible on
my device so I had to disable it:</p><pre><code class="language-bash">export PATH="$HOME/.guix-profile/bin:$HOME/.guix-profile/sbin:$PATH"
guix-daemon --build-users-group=guixbuild --disable-chroot &</code></pre><p>To finish with, it's a good idea to allow substitutes from hydra:</p><pre><code class="language-bash">mkdir /etc/guix
guix archive --authorize < \
$HOME/.guix-profile/share/guix/hydra.gnu.org.pub</code></pre><h4>Enjoy!</h4><pre><code class="language-bash">guix pull</code></pre><p><img src="https://www.gnu.org/software/guix/static/blog/img/android.jpg" alt="Mobile phone running 'guix pull'." /></p><h4>Future work</h4><p>So, now we can enjoy the Guix package manager on Android! One of the
drawbacks is that after a reboot we will have to redo half of the
steps: recreate <code>/var</code> and <code>/gnu</code>, mount the partitions to them. Everytime
you launch a shell, you will have to export the <code>PATH</code> to be able to run
<code>guix</code>. You will have to run <code>guix-daemon</code> manually. To solve all of these
problems at once, you should modify the boot image. That's tricky and I
already put some effort to it, but the phone always ends up in a boot
loop after I flash a modified boot image. The nice folks at <code>#replicant</code>
suggested that I soldered some cable to access a serial console where
debug messages may be dropped. Let's see how many fingers I burn before
I can boot a custom boot image!</p><h4>About GNU Guix</h4><p><a href="https://www.gnu.org/software/guix">GNU Guix</a> 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
<a href="https://www.gnu.org/distros/free-system-distribution-guidelines.html">respects the user's
freedom</a>.</p><p>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 <a href="https://www.gnu.org/software/guile">Guile</a> modules,
using extensions to the <a href="http://schemers.org">Scheme</a> language. GuixSD
offers a declarative approach to operating system configuration
management, and is highly customizable and hackable.</p><p>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.</p>https://guix.gnu.org/blog/2018/aarch64-build-machines-donated//aarch64 build machines donatedLudovic Courtès2018-01-25T22:00:00Z2018-01-25T22:00:00Z Good news! We got a present for our build farm in the form of two
SoftIron OverDrive 1000 aarch64 machines donated by ARM Holdings. One
of them is already running behind our new build farm, which distributes
binaries from https://berlin.guixsd.org , and the other one should be
operational soon. The OverDrive has 4 cores and 8 GiB of RAM. It comes in a fancy
VCR-style case, which looks even more fancy with the obligatory
stickers: A few months ago we reported on the status of the aarch64
port ,
which was already looking good. The latest
…<p>Good news! We got a present for our build farm in the form of two
SoftIron OverDrive 1000 aarch64 machines donated by ARM Holdings. One
of them is already running behind our new build farm, which distributes
binaries from <code>https://berlin.guixsd.org</code>, and the other one should be
operational soon.</p><p>The OverDrive has 4 cores and 8 GiB of RAM. It comes in a fancy
VCR-style case, which looks even more fancy with the obligatory
stickers:</p><p><img src="https://www.gnu.org/software/guix/static/blog/img/overdrive.jpg" alt="An OverDrive 1000 with its fancy Guix stickers." /></p><p>A few months ago we reported on the <a href="https://www.gnu.org/software/guix/blog/2017/state-of-aarch64-on-guix/">status of the aarch64
port</a>,
which was already looking good. The latest
<a href="https://www.gnu.org/software/guix/blog/2017/gnu-guix-and-guixsd-0.14.0-released/">releases</a>
include a pre-built binary tarball of Guix for aarch64.</p><p>Until now though, the project’s official build farms were not building
aarch64 binaries. Consequently, Guix on aarch64 would build everything
from source. We are glad that this is about to be fixed. We will need
to expand our build capacity for this architecture and for ARMv7 as
well, and <a href="https://www.gnu.org/software/guix/donate/">you too can help</a>!</p><p>Thanks to ARM Holdings and in particular to Richard Henwood for
contributing to our build infrastructure!</p><h4>About GNU Guix</h4><p><a href="https://www.gnu.org/software/guix">GNU Guix</a> 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
<a href="https://www.gnu.org/distros/free-system-distribution-guidelines.html">respects the user's
freedom</a>.</p><p>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 <a href="https://www.gnu.org/software/guile">Guile</a> modules,
using extensions to the <a href="http://schemers.org">Scheme</a> language. GuixSD
offers a declarative approach to operating system configuration
management, and is highly customizable and hackable.</p><p>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.</p>https://guix.gnu.org/blog/2017/porting-guixsd-to-armv7//Porting GuixSD to ARMv7Mathieu Othacehe2017-12-22T14:00:00Z2017-12-22T14:00:00Z GuixSD porting to ARMv7 is a difficult topic. There are plenty of
different machines, with specific hardware configurations and
vendor-tuned bootloaders, and ACPI support is still experimental. For
those reasons it is currently impossible to provide a GuixSD image
that runs on most ARMv7 machines like on x86_64 targets. The GuixSD port on ARMv7 has to be done machine by machine and the
first supported one is the BeagleBone Black. It was choosen mainly
because it runs with mainline U-Boot and Linux-libre kernel. As Guix already supported armv7, only three things were missing: A rework of the GuixSD bootloader layer…<p>GuixSD porting to ARMv7 is a difficult topic. There are plenty of
different machines, with specific hardware configurations and
vendor-tuned bootloaders, and ACPI support is still experimental. For
those reasons it is currently impossible to provide a GuixSD image
that runs on most ARMv7 machines like on x86_64 targets.</p><p>The GuixSD port on ARMv7 has to be done machine by machine and the
first supported one is the BeagleBone Black. It was choosen mainly
because it runs with mainline U-Boot and Linux-libre kernel.</p><p>As Guix already supported armv7, only three things were missing:</p><ol><li>A rework of the GuixSD bootloader layer to support not just GRUB but
also U-Boot and Extlinux. This has been integrated in the <a href="https://www.gnu.org/software/guix/blog/2017/gnu-guix-and-guixsd-0.14.0-released/">0.14
release</a>.</li><li>Some developments and fixes on Guix scripts to support image generation,
system reconfiguration and installation on ARMv7 in the same way as it is
already possible on i686 and x86_64 machines.</li><li>The definition on an installation image for the BeagleBone Black.</li></ol><p>Points 2 and 3 were addressed recently so we are now ready to show you
how to run GuixSD on your BeagleBone Black board!</p><h4>Installing GuixSD on a BeagleBone Black</h4><p>Let's try to install GuixSD on the 4GB eMMC (built-in flash memory) of
a BeagleBone Black.</p><p>Future Guix releases will provide pre-built installer images for the
BeagleBone Black. For now, as support just landed on "master", we need
to build this image by ourselves.</p><p>This can be done this way:</p><pre><code>guix system disk-image --system=armhf-linux -e "(@ (gnu system install) beaglebone-black-installation-os)"</code></pre><p>Note that it is not yet possible to cross-compile a disk image. So you
will have to either run this command on an armhf-linux system where
you have previously installed Guix manually, or offload the build to such a
system.</p><p>You will eventually get something like:</p><pre><code>installing bootloader...
[ 7710.782381] reboot: Restarting system
/gnu/store/v33ccp7232gj5wdahdgpjcw4nvh14d7s-disk-image</code></pre><p>Congrats! Let's flash this image onto a microSD card with the command:</p><pre><code>dd if=/gnu/store/v33ccp7232gj5wdahdgpjcw4nvh14d7s-disk-image of=/dev/mmcblkX bs=4M</code></pre><p>where mmcblkX is the name of your microSD card on your GNU/Linux machine.</p><p>You can now insert the microSD card into you BeagleBone Black, plug in a
UART cable and power-on your device while pressing the "S2" button to
force the boot from microSD instead of eMMC.</p><p><img src="https://www.gnu.org/software/guix/static/blog/img/guixsd-bbb1.jpg" alt="GuixSD installer on BeagleBone Black" /></p><p>Let's follow the <a href="https://www.gnu.org/software/guix/manual/en/html_node/Preparing-for-Installation.html#Preparing-for-Installation">Guix documentation
here</a>
to install GuixSD on eMMC.</p><p>First of all, let's plug in an ethernet cable and set up SSH access in order to
be able to get rid of the UART cable.</p><pre><code>ifconfig eth0 up
dhclient eth0
herd start ssh-daemon</code></pre><p>Let's partition the eMMC (/dev/mmcblk1) as a 4GB ext4 partition,
mount it, and launch the cow-store service, still following the
documentation.</p><pre><code>cfdisk
mkfs.ext4 -L my-root /dev/mmcblk1p1
mount LABEL=my-root /mnt
herd start cow-store /mnt</code></pre><p>We have reached the most important part of this whole process. It is now
time to write the configuration file of our new system.
The best thing to do here is to start from the template
<code>beaglebone-black.scm</code>:</p><pre><code>mkdir /mnt/etc
cp /etc/configuration/beaglebone-black.scm /mnt/etc/config.scm
zile /mnt/etc/config.scm</code></pre><p>Once you are done preparing the configuration file, the new system must be initialized
with this command:</p><pre><code>guix system init /mnt/etc/config.scm /mnt</code></pre><p>When this is over, you can turn off the board and remove the microSD card. When you'll
power it on again, it will boot a bleeding edge GuixSD---isn't that nice?</p><h4>Preparing a dedicated system configuration</h4><p>Installing GuixSD on eMMC is great but you can also use Guix
to prepare a portable microSD card image for your favorite server configuration. Say
you want to run an mpd server on a BeagleBone Black directly from microSD card,
with a minimum of configuration steps.</p><p>The system configuration could look like this:</p><pre><code class="language-scheme">(use-modules (gnu) (gnu bootloader extlinux))
(use-service-modules audio networking ssh)
(use-package-modules screen ssh)
(operating-system
(host-name "my-mpd-server")
(timezone "Europe/Berlin")
(locale "en_US.utf8")
(bootloader (bootloader-configuration
(bootloader u-boot-beaglebone-black-bootloader)
(target "/dev/sda")))
(initrd (lambda (fs . rest)
(apply base-initrd fs
;; This module is required to mount the sd card.
#:extra-modules (list "omap_hsmmc")
rest)))
(file-systems (cons (file-system
(device "my-root")
(title 'label)
(mount-point "/")
(type "ext4"))
%base-file-systems))
(users (cons (user-account
(name "mpd")
(group "users")
(home-directory "/home/mpd"))
%base-user-accounts))
(services (cons* (dhcp-client-service)
(service mpd-service-type)
(agetty-service
(agetty-configuration
(extra-options '("-L"))
(baud-rate "115200")
(term "vt100")
(tty "ttyO0")))
%base-services)))</code></pre><p>After writing this configuration to a file called <code>mpd.conf</code>, it's possible to
forge a disk image from it, with the following command:</p><pre><code>guix system disk-image --system=armhf-linux mpd.conf</code></pre><p>Like in the previous section, the resulting image should be copied to a microSD card.
Then, booting from it on the BeagleBone Black, you should get:</p><pre><code>...
Service mpd has been started.
This is the GNU system. Welcome.
my-mpd-server login:</code></pre><p>With only two commands you can build a system image from a configuration file, flash it
and run it on a BeagleBone Black!</p><h4>Next steps</h4><ul><li>Porting GuixSD to other ARMv7 machines.</li></ul><p>While most of the work for supporting ARMv7 machines is done, there's
still work left to create specific installers for other machines.
This mostly consists of specifying the right bootloader and initrd
options, and testing the whole thing.</p><p>One of the next supported systems might be the
<a href="https://www.crowdsupply.com/eoma68/micro-desktop">EOMA68-A20</a> as we
should get a pre-production unit soon. Feel free to add
support for your favorite machine!</p><p>This topic will be discussed in a future post.</p><ul><li>Allow system cross-compilation.</li></ul><p>This will be an interesting feature to allow producing a disk image from
a desktop machine on x86_64 for instance. More development work is needed,
but we'll keep you informed.</p><h4>About GNU Guix</h4><p><a href="https://www.gnu.org/software/guix">GNU Guix</a> 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
<a href="https://www.gnu.org/distros/free-system-distribution-guidelines.html">respects the user's
freedom</a>.</p><p>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 <a href="https://www.gnu.org/software/guile">Guile</a> modules,
using extensions to the <a href="http://schemers.org">Scheme</a> language. GuixSD
offers a declarative approach to operating system configuration
management, and is highly customizable and hackable.</p><p>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.</p>https://guix.gnu.org/blog/2017/state-of-aarch64-on-guix//State of aarch64 on GuixEfraim Flashner2017-07-24T15:30:00Z2017-07-24T15:30:00Z Since the recent 0.13.0 release, Guix supports building software for
aarch64 (64-bit ARM architecture). Here’s the current status. Currently aarch64 support in Guix is pretty good, as long as you don't
mind compiling for yourself :). Potential downfalls are too little RAM
(I limited my boards to 2GB minimum) and using an SD card. For building
packages I made sure that between RAM and swap I have at least 6 GB,
which I don't recall giving me any issues. There were problems with actually building the Guix binary in time for
the 0.13 release. It has since been fixed and I…<p>Since the recent 0.13.0 release, Guix supports building software for
aarch64 (64-bit ARM architecture). Here’s the current status.</p><p>Currently aarch64 support in Guix is pretty good, as long as you don't
mind compiling for yourself :). Potential downfalls are too little RAM
(I limited my boards to 2GB minimum) and using an SD card. For building
packages I made sure that between RAM and swap I have at least 6 GB,
which I don't recall giving me any issues.</p><p>There were problems with actually building the Guix binary in time for
the 0.13 release. It has since been fixed and I have an unoffical
aarch64 binary install tarball at http://flashner.co.il/~efraim/. Also there is
the signing key for my odroid running
<a href="https://www.gnu.org/software/guix/manual/en/html_node/Invoking-guix-publish.html"><code>guix publish</code></a>.
The URL of my <code>guix publish</code> server is <code>http://git.flashner.co.il:8181</code>.</p><p>General problem points/packages:</p><ul><li>Java is currently out, <code>sablevm-classpath</code> doesn't compile, so currently
there is no path for Java. A quick check showed about 140 packages
depend on <code>sablevm-classpath</code>.</li><li>Go: go-1.4.x doesn't support aarch64 (or mips). I have a patch against
our GCC to build gccgo, and it produces a <code>go</code> binary, but it fails to
actually build anything. When I checked Debian I saw they cross-compile
their arm64 <code>go</code> binary from amd64. I believe there may be an issue with
using gccgo and linking against glibc.</li><li>OCaml 4.01.0: Doesn't build on aarch64, haven't investigated.</li><li>Julia: aarch64 is officially supported, but it has only been tested on
superpowerful boards, like the ThunderX. I haven't gotten it to build
yet. The issue is related to <code>__fp16</code>.</li><li>clisp: our current version doesn't build on aarch64, there isn't
support yet. There are newer builds but no offical release yet, and I
haven't tested those yet.</li><li>gprolog: No upstream support and AFAICT no one is working on it.</li><li>LDC: 1.x is supposed to support aarch64, 0.17.x, aka ldc-bootstrap,
doesn't, it fails while compiling phobos, which has no aarch64 support
in that version.</li><li>Rust: Has upstream support, our package uses the i686 version as a
bootstrap, so only i686 and x86_64 have support in guix ATM.</li><li>Haskell: There is no upstream aarch64 binary to use for bootstrapping.
I'm thinking of trying to use qemu-system-x86_64 as the shell and
emulate x86_64 on my aarch64 board to cross-compile it to aarch64. <code>guix package -A ghc | wc -l</code> shows 293 packages.</li><li>Qt 4: does not build, I've hardly put any time into it.</li><li>Gnucash: The ancient WebKit version they use didn't build on aarch64,
I haven't tried to fix it.</li><li>Linux-libre: While many boards do require specific patches and
versions of the kernel, there have been great increases in recent
kernel versions for many ARM boards. It remains to be seen how much
support these boards have after the kernel has been deblobbed.</li></ul><p>It sounds like its all doom and gloom, but its not too bad. <code>guix package -A | wc -l</code> shows me 5,341 (5,208 without <code>sablevm-classpath</code>),
compared with ~5,600 on x86_64. Most of the difference is Haskell. In
addition, I personally believe that aarch64 actually has fewer
packages that fail to build than armhf.</p><p>Currently the project’s build farm lacks aarch64 build machines. If you
would like to help,
please <a href="https://gnu.org/software/guix/donate/">get in touch with us</a>!</p><h4>About GNU Guix</h4><p><a href="https://www.gnu.org/software/guix">GNU Guix</a> 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
<a href="https://www.gnu.org/distros/free-system-distribution-guidelines.html">respects the user's
freedom</a>.</p><p>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 <a href="https://www.gnu.org/software/guile">Guile</a> modules,
using extensions to the <a href="http://schemers.org">Scheme</a> language. GuixSD
offers a declarative approach to operating system configuration
management, and is highly customizable and hackable.</p><p>GuixSD can be used on an i686 or x86_64 machine. It is also possible to
use Guix on top of an already installed GNU/Linux system, including on
mips64el, armv7, and aarch64.</p>https://guix.gnu.org/blog/2015/gnu-guix-ported-to-arm-and-other-niceties-of-the-new-year//GNU Guix ported to ARM and other niceties of the new yearLudovic Courtès2015-01-09T00:00:00+01002015-01-09T00:00:00+0100 A new port of GNU Guix to ARM using the "hard float" ABI has just landed , thanks to the hard work of Mark H Weaver and John Darrington. This makes it the fourth supported architecture after x86_64, i686, and mips64el. We are looking for ARM hardware donations that would allow us to add this architecture to our continuous integration build farm ; your help is welcome! In other news, there has been work to improve Linux module handling , the addition of session support in the login…<div><p>A new port of GNU Guix to ARM using the "hard float" ABI <a href="http://git.savannah.gnu.org/cgit/guix.git/commit/?h=core-updates&id=aa1e19477b2d78884fc500fef497cd6677604d9b">has just landed</a>, thanks to the hard work of Mark H Weaver and John Darrington. This makes it the fourth supported architecture after x86_64, i686, and mips64el. We are looking for ARM hardware donations that would allow us to add this architecture to our <a href="http://hydra.gnu.org">continuous integration build farm</a>; your help is welcome!<br /></p><p>In other news, there has been work to <a href="http://lists.gnu.org/archive/html/guix-devel/2014-11/msg00670.html">improve Linux module handling</a>, the addition of <a href="http://lists.gnu.org/archive/html/guix-devel/2014-12/msg00300.html">session support</a> in the login manager, <a href="http://lists.gnu.org/archive/html/guix-devel/2014-12/msg00413.html">more tooling</a> in 'guix lint', an <a href="http://lists.gnu.org/archive/html/guix-devel/2014-12/msg00278.html">nscd configuration interface</a>, many new <a href="https://www.gnu.org/software/guix/package-list.html">packages</a> (Xfce, NumPy, SciPy, and Clang, to name a few), and <a href="http://debbugs.gnu.org/cgi/pkgreport.cgi?archive=both;package=guix">many bug fixes</a>. Getting closer to a new release!<br /></p><h4>About GNU Guix</h4><p><a href="http://www.gnu.org/software/guix">GNU Guix</a> is the functional package manager for the GNU system, and a distribution thereof.<br /></p><p>In addition to standard package management features, Guix supports transactional upgrades and roll-backs, unprivileged package management, per-user profiles, and garbage collection. It also offers a declarative approach to operating system configuration management. Guix uses low-level mechanisms from the Nix package manager, except that packages are defined as native <a href="http://www.gnu.org/software/guile">Guile</a> modules, using extensions to the <a href="http://schemers.org">Scheme</a> language.<br /></p><p>At this stage the distribution can be used on an i686 or x86_64 machine. It is also possible to use Guix on top of an already installed GNU/Linux system, including on mips64el and armhf.<br /></p></div>