-
Notifications
You must be signed in to change notification settings - Fork 54
Live bootstrap to guix #578
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 211 commits
21ddab3
6fcb8f4
71efe6b
6e19398
0b16d6d
8564386
62078d5
e86bbab
c54da75
2f22444
6022208
548f45e
0a922a2
e727bcc
92afa6f
afd79c2
9515d30
cb1a8a6
bcd3be0
51d4773
fee7d7d
280eaba
d0f7f6f
0066bbd
8f29302
8703b08
6b10401
e821a06
156cd66
55be03a
6c2fd50
0b53827
faeff8a
e931553
636edeb
642ef88
ae840fa
ffce902
685f8ae
3bea5b5
7ed755a
ddbe55b
1933332
494b08c
25b755a
eb9a9f4
33bb0bb
d4d6f6b
ee0f481
ef7127b
a05880e
5d63dc3
8f60091
8300147
bb24692
8b2d63f
95b34d3
6762e8b
1ada5d4
8990eaa
de73fe6
1c75638
e700df3
faf86ef
5c242b0
53223ce
34e201a
c9d129b
7840891
fb146bb
3178f1f
c8a9d23
564ad87
7f6be11
9db4095
d588f4d
57cd56a
11c4dd8
f30c20b
e08abd6
aa36ef0
9fc53eb
1b01d22
500bce6
e20afe6
beb9fb1
5e4c887
5eac7ed
17e88a8
45ba6a3
6b37393
c37acaa
25f8311
de83785
96765e2
38f8769
e821482
197f175
e19f13f
f2a151e
6dfc8d5
afec884
9192004
85c3890
95b25af
b1642d6
d1b466c
1009bfa
4e67035
7253e3f
b733cf2
35a570b
8440096
f11bbe6
1d9c9b9
9d1870c
f21234e
1d73a27
d344675
2778fe4
82124df
0669db4
893a320
ea69ae9
4f0f503
8160430
c29c92b
74ff570
886d5a5
d5fc082
6d8c5da
8ad179e
c90d9da
af44f12
3d35277
4abc97d
5cea0ba
bd208bf
3f01d14
451fdc6
9205c2b
ac79f9e
75e153d
51019e2
d150b48
bbd4804
c2ecd88
56f5154
2cb4ec5
7783577
a3acfbe
9055660
bbe8099
442e3a2
079b6fd
913ebb3
f812212
e9c2946
29695ad
ba7aec9
65314bc
c4666a1
567f4af
786844a
a1881ad
a1f3068
c55f989
c921403
666d979
5d12893
be9b32b
076a709
b18cba4
adcd73b
c124c08
aea0e5c
6d0db68
bab05bb
74da573
49537b4
aa72935
2b16d6d
4e12d7a
f8b6d25
754aa8c
66a6665
6b8aa73
d0c97c1
7715b0b
62478d4
173db71
a3878a9
132a43d
0a00b29
7c42824
fc1cf31
f786342
85a0ff7
1950175
96c2cfb
4324f23
20eb963
b8785e3
c742563
c0e84ad
8779eb4
c75e951
4dc0135
8917b7b
81815f3
962bc74
277de65
67384bf
80f4061
3583176
6c83ef3
8bed6f4
6a5ba94
a20351b
2816e89
00e3f91
4f66a58
8c41939
ef6abd5
ea9c3d6
d709331
4af0359
3dcc4ec
8bb3da9
4674fc5
c55fd54
a170296
eb44754
3817181
c0e18b0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,108 @@ | ||
| # live-bootstrap | ||
|
|
||
| This repository uses [`README.rst`](./README.rst) as the canonical main documentation. | ||
|
|
||
| ## Kernel-bootstrap raw `external.img` | ||
|
|
||
| `external.img` is a raw container disk used in kernel-bootstrap mode when | ||
| `--external-sources` is set and `--repo` is unset. | ||
|
|
||
| ### Why not put everything in the initial image? | ||
|
|
||
| In kernel-bootstrap mode, the first boot image is consumed by very early | ||
| runtime code before the system reaches the normal bash-based build stage. | ||
| That early stage has tight assumptions about memory layout and file table usage. | ||
|
|
||
| When too many distfiles are packed into the initial image, those assumptions can | ||
| be exceeded, which leads to unstable handoff behavior (for example, failures | ||
| around the Fiwix transition in QEMU or on bare metal). | ||
|
|
||
| So the design is intentionally split: | ||
|
|
||
| - Initial image: only what is required to reach `improve: import_payload` | ||
| - `external.img`: the rest of distfiles | ||
|
|
||
| This is not a patch-style workaround. It is a two-phase transport design that | ||
| keeps early boot deterministic and moves bulk data import to a stage where the | ||
| runtime is robust enough to process it safely. | ||
|
|
||
| ### Why import from an external image and copy into main filesystem? | ||
|
|
||
| Because the bootstrap still expects distfiles to end up under the normal local | ||
| path (`/external/distfiles`) for later steps. `external.img` is used as a | ||
| transport medium only. | ||
|
|
||
| The flow is: | ||
|
|
||
| 1. Boot minimal initial image. | ||
| 2. Reach `improve: import_payload`. | ||
| 3. Detect the external container disk by magic (`LBPAYLD1`) across detected block devices. | ||
| 4. Copy payload files into `/external/distfiles`. | ||
| 5. Continue the build exactly as if files had been present locally all along. | ||
|
|
||
| ### Format | ||
|
|
||
| - Magic: `LBPAYLD1` (8 bytes) | ||
| - Then: little-endian `u64` file count | ||
| - Repeated entries: | ||
| - little-endian `u64` name length | ||
| - little-endian `u64` file size | ||
| - file name string, encoded as UTF-8 bytes (no terminator) | ||
| - file bytes | ||
|
|
||
| `name length` is the number of bytes in the UTF-8 encoded file name (not the number of Unicode code points). | ||
|
|
||
| The importer probes detected block devices and selects the one with magic `LBPAYLD1`. | ||
|
|
||
| ### Manual creation without Python | ||
|
|
||
| Prepare `external.list` as: | ||
|
|
||
| ```text | ||
| <archive-name> <absolute-path-to-archive> | ||
| ``` | ||
|
|
||
| Then: | ||
|
|
||
| ```sh | ||
| cat > make-payload.sh <<'SH' | ||
| #!/bin/sh | ||
| set -e | ||
| out="${1:-external.img}" | ||
| list="${2:-external.list}" | ||
|
|
||
| write_u64le() { | ||
| v="$1" | ||
| printf '%016x' "$v" | sed -E 's/(..)(..)(..)(..)(..)(..)(..)(..)/\8\7\6\5\4\3\2\1/' | xxd -r -p | ||
| } | ||
|
|
||
| count="$(wc -l < "${list}" | tr -d ' ')" | ||
| : > "${out}" | ||
| printf 'LBPAYLD1' >> "${out}" | ||
| write_u64le "${count}" >> "${out}" | ||
|
|
||
| while read -r name path; do | ||
| [ -n "${name}" ] || continue | ||
| size="$(wc -c < "${path}" | tr -d ' ')" | ||
| name_len="$(printf '%s' "${name}" | wc -c | tr -d ' ')" | ||
| write_u64le "${name_len}" >> "${out}" | ||
| write_u64le "${size}" >> "${out}" | ||
| printf '%s' "${name}" >> "${out}" | ||
| cat "${path}" >> "${out}" | ||
| done < "${list}" | ||
| SH | ||
| chmod +x make-payload.sh | ||
| ./make-payload.sh external.img external.list | ||
| ``` | ||
|
|
||
| Attach `external.img` as an extra raw disk in QEMU, or as the second disk on bare metal. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we support this as a partition on the same disk as the srcfs, rather than requiring a second physical disk?
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This would be a fairly invasive change, and should certainly not be in this PR. (I think this can/should be done, but it will require a fair bit of careful effort) |
||
|
|
||
| ### When it is used | ||
|
|
||
| - Used in kernel-bootstrap with `--external-sources` and without `--repo`. | ||
| - Not used with `--repo` (that path still uses an ext filesystem disk). | ||
| - Without `--external-sources` and without `--repo`, there is no second disk: | ||
| the initial image only includes distfiles needed before `improve: get_network`, | ||
| and later distfiles are downloaded from mirrors. | ||
| - `--extra-builds=guix` increases container contents (includes post-early `steps-guix` | ||
| sources), but does not change the mechanism. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why a custom format, rather than tar, wim or something similar?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reduce TCB, therefore, a pure byte stream is used
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's TCB?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trusted Computing Base, Google's explanation: refers to the totality of hardware, firmware, and software components critical to a system's security, enforcing its security policy. If any TCB component is compromised, the system's integrity is jeopardized. It includes kernels, memory, and trusted processes, shielded by a security perimeter
So, clearly, this includes file systems and the tools used to create them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above - we already have a dependency on tar, so I don't see how having the payload be a tarball would be TCB-relevant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's our dependency on
tar?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The source code we use comes in tarballs, the repo package format is tar-based, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, yes, but the system preparing live-bootstrap doesn't need
tar, and theoretically we could not use tarballs...