help-guix
[Top][All Lists]
Advanced

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

How does system-disk-image work with embedded-style boot loaders?


From: Richard Sent
Subject: How does system-disk-image work with embedded-style boot loaders?
Date: Sat, 11 May 2024 17:15:17 -0400

Hi Guix!

I'm a bit confused as to how a system image is generated when certain
bootloader types are used. For example, rockpro64-rk3399-u-boot.

In (gnu bootloader u-boot) install-rockpro64-rk3399-u-boot has this
definition:

--8<---------------cut here---------------start------------->8---
(define install-rockpro64-rk3399-u-boot
  #~(lambda (bootloader root-index image)
      (let ((idb (string-append bootloader "/libexec/idbloader.img"))
            (u-boot (string-append bootloader "/libexec/u-boot.itb")))
        (write-file-on-device idb (stat:size (stat idb))
                              image (* 64 512))
        (write-file-on-device u-boot (stat:size (stat u-boot))
                              image (* 16384 512)))))
--8<---------------cut here---------------end--------------->8---

Which makes sense. The onboard ROM bootlaoder looks for u-boot at a
specific offset in flash and loads that.

However, I don't understand how we "orchestrate" that with the rest of
the system image to avoid a collision.

At the end of system-disk-image in (gnu system image), we have this:

--8<---------------cut here---------------start------------->8---
(let* ((image-name (image-name image))
         (name (if image-name
                   (symbol->string image-name)
                   name))
         (format (image-format image))
         (substitutable? (image-substitutable? image))
         (builder
          (with-imported-modules*
           (let ((inputs '#+(list genimage coreutils findutils qemu-minimal))
                 (bootloader-installer
                  #+(bootloader-disk-image-installer bootloader))
                 (out-image (string-append "images/" #$genimage-name)))
             (set-path-environment-variable "PATH" '("bin" "sbin") inputs)
             (genimage #$(image->genimage-cfg image))
             ;; Install the bootloader directly on the disk-image.
             (when bootloader-installer
               (bootloader-installer
                #+(bootloader-package bootloader)
                #$(root-partition-index image)
                out-image))
             (convert-disk-image out-image '#$format #$output)))))
    (computed-file name builder
                   #:local-build? #f              ;too I/O-intensive
                   #:options `(#:substitutable? ,substitutable?)))
--8<---------------cut here---------------end--------------->8---

>From what I can tell this is a 4 step process.

1. Generate a genimage.cfg file via image->genimage-cfg. This does not
appear to take the bootloader into account.

2. Call genimage in (gnu build image) to create the image defined in the
genimage.cfg file.

3. use bootloader-installer to write directly into the image file that
was just created. In this case we write two files at specific offsets.

4. Convert the raw disk image into the desired output format.

How do we avoid "screwing up" the image by writing directly to the
image? What stops genimage from putting important data there that gets
overwritten in step 3? Is it just coincidence? A convention in the image
file to leave a large amount of space at the beginning? Some other
factor? What if another embedded board uses a different offset that
genimage does happen to use?

I'm *guessing* that the answer lies in the image type and
raw-with-offset-disk-image function, but I'd appreciate any
clarification on this! I see that pinebook-pro-image-type, which also
uses Pine64's rk3399 SoC has an offset of 2^20, or 1,048,576. However

1) There isn't a rockpro64-image-type, only a pinebook-pro-image-type.
Why only have one image type but two bootloaders?

2) install-rockpro64-rk3399-u-boot writes u-boot.itb at (* 16384 512),
or 8,388,608, past the 2^20 offset in the image type. (Likely not
coincidentally 8,388,608 / 8 = 1,048,576. I don't know what to make of this
because it feels weird that bytes are used in one situation while
another uses bits.)

Appreciate any clarification on this!

-- 
Take it easy,
Richard Sent
Making my computer weirder one commit at a time.



reply via email to

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