1919 # sdImage containing ESP and root partitions (compressed)
2020 images = config . system . build . sdImage ;
2121
22- # Partition XML with placeholders (substituted at flash time by preFlashCommands)
23- partitionsEmmc = pkgs . writeText "sdmmc.xml" ''
24- <partition name="master_boot_record" type="protective_master_boot_record">
25- <allocation_policy> sequential </allocation_policy>
26- <filesystem_type> basic </filesystem_type>
27- <size> 512 </size>
28- <file_system_attribute> 0 </file_system_attribute>
29- <allocation_attribute> 8 </allocation_attribute>
30- <percent_reserved> 0 </percent_reserved>
31- </partition>
32- <partition name="primary_gpt" type="primary_gpt">
33- <allocation_policy> sequential </allocation_policy>
34- <filesystem_type> basic </filesystem_type>
35- <size> 19968 </size>
36- <file_system_attribute> 0 </file_system_attribute>
37- <allocation_attribute> 8 </allocation_attribute>
38- <percent_reserved> 0 </percent_reserved>
39- </partition>
40- <partition name="esp" id="2" type="data">
41- <allocation_policy> sequential </allocation_policy>
42- <filesystem_type> basic </filesystem_type>
43- <size> ESP_SIZE </size>
44- <file_system_attribute> 0 </file_system_attribute>
45- <allocation_attribute> 0x8 </allocation_attribute>
46- <percent_reserved> 0 </percent_reserved>
47- <filename> bootloader/esp.img </filename>
48- <partition_type_guid> C12A7328-F81F-11D2-BA4B-00A0C93EC93B </partition_type_guid>
49- <description> EFI system partition with systemd-boot. </description>
50- </partition>
51- <partition name="APP" id="1" type="data">
52- <allocation_policy> sequential </allocation_policy>
53- <filesystem_type> basic </filesystem_type>
54- <size> ROOT_SIZE </size>
55- <file_system_attribute> 0 </file_system_attribute>
56- <allocation_attribute> 0x8 </allocation_attribute>
57- <align_boundary> 16384 </align_boundary>
58- <percent_reserved> 0x808 </percent_reserved>
59- <unique_guid> APPUUID </unique_guid>
60- <filename> root.img </filename>
61- <description> **Required.** Contains the rootfs. This partition must be assigned
62- the "1" for id as it is physically put to the end of the device, so that it
63- can be accessed as the fixed known special device `/dev/mmcblk0p1`. </description>
64- </partition>
65- <partition name="secondary_gpt" type="secondary_gpt">
66- <allocation_policy> sequential </allocation_policy>
67- <filesystem_type> basic </filesystem_type>
68- <size> 0xFFFFFFFFFFFFFFFF </size>
69- <file_system_attribute> 0 </file_system_attribute>
70- <allocation_attribute> 8 </allocation_attribute>
71- <percent_reserved> 0 </percent_reserved>
72- </partition>
73- '' ;
74-
75- # Line counts for replacing the sdmmc_user device section in NVIDIA's flash XML.
76- # These numbers specify where to splice our custom partition layout.
22+ # eMMC partition layout as structured Nix data.
23+ # Serialized to JSON and spliced into NVIDIA's flash XML by
24+ # splice-flash-xml.py, which replaces the <device type="sdmmc_user">
25+ # children. This avoids fragile line-count splicing.
7726 #
78- # WARNING: When updating jetpack-nixos/BSP version, verify these line counts
79- # still match the <device type="sdmmc_user"> section boundaries in:
80- # - flash_t234_qspi_sdmmc.xml (standard)
81- # - flash_t234_qspi_sdmmc_industrial.xml (industrial variant)
82- partitionTemplateReplaceRange =
83- if ( config . hardware . nvidia-jetpack . som == "orin-agx-industrial" ) then
84- if ( ! cfg . flashScriptOverrides . onlyQSPI ) then
85- {
86- firstLineCount = 631 ;
87- lastLineCount = 2 ;
88- }
89- else
90- {
91- # QSPI-only: remove entire sdmmc_user device section
92- firstLineCount = 630 ;
93- lastLineCount = 1 ;
94- }
95- else if ! cfg . flashScriptOverrides . onlyQSPI then
96- {
97- firstLineCount = 618 ;
98- lastLineCount = 2 ;
99- }
100- else
101- {
102- # QSPI-only: remove entire sdmmc_user device section
103- firstLineCount = 617 ;
104- lastLineCount = 1 ;
27+ # Partition sizes are injected at build time from the sdImage metadata
28+ # via --set (sectors * 512 → bytes).
29+ partitionsEmmc = [
30+ {
31+ name = "master_boot_record" ;
32+ type = "protective_master_boot_record" ;
33+ children = {
34+ allocation_policy = "sequential" ;
35+ filesystem_type = "basic" ;
36+ size = "512" ;
37+ file_system_attribute = "0" ;
38+ allocation_attribute = "8" ;
39+ percent_reserved = "0" ;
40+ } ;
41+ }
42+ {
43+ name = "primary_gpt" ;
44+ type = "primary_gpt" ;
45+ children = {
46+ allocation_policy = "sequential" ;
47+ filesystem_type = "basic" ;
48+ size = "19968" ;
49+ file_system_attribute = "0" ;
50+ allocation_attribute = "8" ;
51+ percent_reserved = "0" ;
52+ } ;
53+ }
54+ {
55+ name = "esp" ;
56+ type = "data" ;
57+ children = {
58+ allocation_policy = "sequential" ;
59+ filesystem_type = "basic" ;
60+ size = "0" ; # overridden by --set from sdImage metadata at build time
61+ file_system_attribute = "0" ;
62+ allocation_attribute = "0x8" ;
63+ percent_reserved = "0" ;
64+ filename = "bootloader/esp.img" ;
65+ partition_type_guid = "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" ;
66+ description = "EFI system partition with systemd-boot." ;
67+ } ;
68+ }
69+ {
70+ name = "APP" ;
71+ type = "data" ;
72+ children = {
73+ allocation_policy = "sequential" ;
74+ filesystem_type = "basic" ;
75+ size = "0" ; # overridden by --set from sdImage metadata at build time
76+ file_system_attribute = "0" ;
77+ allocation_attribute = "0x8" ;
78+ align_boundary = "16384" ;
79+ percent_reserved = "0x808" ;
80+ unique_guid = "APPUUID" ;
81+ filename = "root.img" ;
82+ description = "Contains the rootfs, placed at the end of the device as /dev/mmcblk0p1." ;
10583 } ;
84+ }
85+ {
86+ name = "secondary_gpt" ;
87+ type = "secondary_gpt" ;
88+ children = {
89+ allocation_policy = "sequential" ;
90+ filesystem_type = "basic" ;
91+ size = "0xFFFFFFFFFFFFFFFF" ;
92+ file_system_attribute = "0" ;
93+ allocation_attribute = "8" ;
94+ percent_reserved = "0" ;
95+ } ;
96+ }
97+ ] ;
10698
107- # Build the final flash.xml by splicing our partition layout into NVIDIA's template
99+ # Build the final flash.xml by replacing the sdmmc_user partitions
100+ # in NVIDIA's template with our layout using XML-aware splicing.
108101 partitionTemplate =
109102 let
110103 inherit ( pkgs . nvidia-jetpack ) bspSrc ;
@@ -115,17 +108,19 @@ let
115108 else
116109 "${ bspSrc } /bootloader/generic/cfg/flash_t234_qspi_sdmmc.xml" ;
117110 in
118- pkgs . runCommand "flash.xml" { } (
119- ''
120- head -n ${ toString partitionTemplateReplaceRange . firstLineCount } ${ xmlFile } >"$out"
121- ''
122- + lib . optionalString ( ! cfg . flashScriptOverrides . onlyQSPI ) ''
123- cat ${ partitionsEmmc } >>"$out"
124- ''
125- + ''
126- tail -n ${ toString partitionTemplateReplaceRange . lastLineCount } ${ xmlFile } >>"$out"
111+ pkgs . runCommand "flash.xml"
112+ {
113+ nativeBuildInputs = [ pkgs . buildPackages . python3 ] ;
114+ }
127115 ''
128- ) ;
116+ python3 ${ ./splice-flash-xml.py } \
117+ ${ lib . optionalString cfg . flashScriptOverrides . onlyQSPI "--remove-device" } \
118+ --set "esp.size=$(($(cat ${ images } /esp.size) * 512))" \
119+ --set "APP.size=$(($(cat ${ images } /root.size) * 512))" \
120+ ${ xmlFile } \
121+ ${ pkgs . writeText "sdmmc.json" ( builtins . toJSON partitionsEmmc ) } \
122+ "$out"
123+ '' ;
129124
130125 # preFlashCommands: Extract images from sdImage and patch flash.xml
131126 preFlashScript = pkgs . writeShellApplication {
@@ -171,12 +166,10 @@ let
171166 bs=512 iseek="$ROOT_OFFSET" count="$ROOT_SIZE" status=progress
172167
173168 echo ""
174- echo "Patching flash.xml with image paths and sizes ..."
169+ echo "Patching flash.xml with image paths..."
175170 sed -i \
176171 -e "s#bootloader/esp.img#$WORKDIR/bootloader/esp.img#" \
177172 -e "s#root.img#$WORKDIR/bootloader/root.img#" \
178- -e "s#ESP_SIZE#$((ESP_SIZE * 512))#" \
179- -e "s#ROOT_SIZE#$((ROOT_SIZE * 512))#" \
180173 flash.xml
181174 '' }
182175
0 commit comments