|
1 | 1 | # SPDX-FileCopyrightText: 2022-2026 TII (SSRC) and the Ghaf contributors |
2 | 2 | # SPDX-License-Identifier: Apache-2.0 |
3 | 3 | # |
4 | | -# Module which provides partition template for NVIDIA Jetson AGX Orin |
5 | | -# flash-script |
| 4 | +# Module which provides partition template for NVIDIA Jetson AGX Orin flash-script. |
| 5 | +# |
| 6 | +# This module configures legacyFlashScript to extract ESP and root partitions |
| 7 | +# from the compressed sdImage at flash time, then patches the partition sizes |
| 8 | +# into flash.xml before running NVIDIA's flash.sh. |
| 9 | +# |
6 | 10 | { |
7 | 11 | pkgs, |
8 | 12 | config, |
9 | 13 | lib, |
10 | 14 | ... |
11 | 15 | }: |
12 | 16 | let |
13 | | - # Using the same config for all orin boards (for now) |
14 | | - # TODO should this be changed when NX added |
15 | 17 | cfg = config.ghaf.hardware.nvidia.orin; |
16 | 18 |
|
| 19 | + # sdImage containing ESP and root partitions (compressed) |
17 | 20 | images = config.system.build.${config.formatAttr}; |
| 21 | + |
| 22 | + # Partition XML with placeholders (substituted at flash time by preFlashCommands) |
18 | 23 | partitionsEmmc = pkgs.writeText "sdmmc.xml" '' |
19 | 24 | <partition name="master_boot_record" type="protective_master_boot_record"> |
20 | 25 | <allocation_policy> sequential </allocation_policy> |
|
66 | 71 | <percent_reserved> 0 </percent_reserved> |
67 | 72 | </partition> |
68 | 73 | ''; |
69 | | - # When updating jetpack-nixos version, if the flash_t234_qspi_sdmmc.xml |
70 | | - # changes (usually if the underlying BSP-version changes), you might need to |
71 | | - # update the magical numbers to match the latest flash_t234_qspi_sdmmc.xml if |
72 | | - # it has changed. The point is to replace content between |
73 | | - # `partitionTemplateReplaceRange.firstLineCount` first lines and |
74 | | - # `partitionTemplateReplaceRange.lastLineCount` last lines (i.e. the content |
75 | | - # of the <device type="sdmmc_user" ...> </device> XML-tag), from the |
76 | | - # NVIDIA-supplied flash_t234_qspi_sdmmc.xml, with the partitions specified in |
77 | | - # the above partitionsEmmc variable. |
78 | | - # Orin AGX Industrial has a slightly different flash XML template, so we |
79 | | - # need to handle that separately. |
80 | | - # it uses flash_t234_qspi_sdmmc_industrial.xml as a base and the sdmmc section |
81 | | - # starts and ends at different lines. |
| 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. |
| 77 | + # |
| 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 | 82 | partitionTemplateReplaceRange = |
83 | 83 | if (config.hardware.nvidia-jetpack.som == "orin-agx-industrial") then |
84 | 84 | if (!cfg.flashScriptOverrides.onlyQSPI) then |
|
88 | 88 | } |
89 | 89 | else |
90 | 90 | { |
91 | | - # If we don't flash anything to eMMC, then we don't need to have the |
92 | | - # <device type="sdmmc_user" ...> </device> XML-tag at all. |
| 91 | + # QSPI-only: remove entire sdmmc_user device section |
93 | 92 | firstLineCount = 630; |
94 | 93 | lastLineCount = 1; |
95 | 94 | } |
|
100 | 99 | } |
101 | 100 | else |
102 | 101 | { |
103 | | - # If we don't flash anything to eMMC, then we don't need to have the |
104 | | - # <device type="sdmmc_user" ...> </device> XML-tag at all. |
| 102 | + # QSPI-only: remove entire sdmmc_user device section |
105 | 103 | firstLineCount = 617; |
106 | 104 | lastLineCount = 1; |
107 | 105 | }; |
108 | | - partitionTemplate = pkgs.runCommand "flash.xml" { } ( |
109 | | - lib.optionalString (config.hardware.nvidia-jetpack.som != "orin-agx-industrial") '' |
110 | | - head -n ${toString partitionTemplateReplaceRange.firstLineCount} ${pkgs.nvidia-jetpack.bspSrc}/bootloader/generic/cfg/flash_t234_qspi_sdmmc.xml >"$out" |
111 | 106 |
|
112 | | - '' |
113 | | - + lib.optionalString (config.hardware.nvidia-jetpack.som == "orin-agx-industrial") '' |
114 | | - head -n ${toString partitionTemplateReplaceRange.firstLineCount} ${pkgs.nvidia-jetpack.bspSrc}/bootloader/generic/cfg/flash_t234_qspi_sdmmc_industrial.xml >"$out" |
| 107 | + # Build the final flash.xml by splicing our partition layout into NVIDIA's template |
| 108 | + partitionTemplate = |
| 109 | + let |
| 110 | + inherit (pkgs.nvidia-jetpack) bspSrc; |
| 111 | + isIndustrial = config.hardware.nvidia-jetpack.som == "orin-agx-industrial"; |
| 112 | + xmlFile = |
| 113 | + if isIndustrial then |
| 114 | + "${bspSrc}/bootloader/generic/cfg/flash_t234_qspi_sdmmc_industrial.xml" |
| 115 | + else |
| 116 | + "${bspSrc}/bootloader/generic/cfg/flash_t234_qspi_sdmmc.xml"; |
| 117 | + 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" |
| 127 | + '' |
| 128 | + ); |
| 129 | + |
| 130 | + # preFlashCommands: Extract images from sdImage and patch flash.xml |
| 131 | + preFlashCommands = '' |
| 132 | + echo "============================================================" |
| 133 | + echo "Ghaf flash script for NVIDIA Jetson" |
| 134 | + echo "============================================================" |
| 135 | + echo "Version: ${config.ghaf.version}" |
| 136 | + echo "SoM: ${config.hardware.nvidia-jetpack.som}" |
| 137 | + echo "Carrier board: ${config.hardware.nvidia-jetpack.carrierBoard}" |
| 138 | + echo "============================================================" |
| 139 | + echo "" |
| 140 | + mkdir -pv "$WORKDIR/bootloader" |
| 141 | + rm -fv "$WORKDIR/bootloader/esp.img" |
| 142 | + '' |
| 143 | + + lib.optionalString (!cfg.flashScriptOverrides.onlyQSPI) '' |
| 144 | +
|
| 145 | + # Read partition offsets and sizes from sdImage metadata |
| 146 | + ESP_OFFSET=$(cat "${images}/esp.offset") |
| 147 | + ESP_SIZE=$(cat "${images}/esp.size") |
| 148 | + ROOT_OFFSET=$(cat "${images}/root.offset") |
| 149 | + ROOT_SIZE=$(cat "${images}/root.size") |
115 | 150 |
|
116 | | - '' |
117 | | - + lib.optionalString (!cfg.flashScriptOverrides.onlyQSPI) '' |
| 151 | + img="${images}/sd-image/${config.image.fileName}" |
| 152 | + echo "Source image: $img" |
| 153 | + echo "ESP: offset=$ESP_OFFSET sectors, size=$ESP_SIZE sectors" |
| 154 | + echo "Root: offset=$ROOT_OFFSET sectors, size=$ROOT_SIZE sectors" |
| 155 | + echo "" |
118 | 156 |
|
119 | | - # Replace the section for sdmmc-device with our own section |
120 | | - cat ${partitionsEmmc} >>"$out" |
| 157 | + echo "Extracting ESP partition..." |
| 158 | + dd if=<("${pkgs.pkgsBuildBuild.zstd}/bin/pzstd" -d "$img" -c) \ |
| 159 | + of="$WORKDIR/bootloader/esp.img" \ |
| 160 | + bs=512 iseek="$ESP_OFFSET" count="$ESP_SIZE" status=progress |
121 | 161 |
|
122 | | - '' |
123 | | - + lib.optionalString (config.hardware.nvidia-jetpack.som != "orin-agx-industrial") '' |
| 162 | + echo "Extracting root partition..." |
| 163 | + dd if=<("${pkgs.pkgsBuildBuild.zstd}/bin/pzstd" -d "$img" -c) \ |
| 164 | + of="$WORKDIR/bootloader/root.img" \ |
| 165 | + bs=512 iseek="$ROOT_OFFSET" count="$ROOT_SIZE" status=progress |
124 | 166 |
|
125 | | - tail -n ${toString partitionTemplateReplaceRange.lastLineCount} ${pkgs.nvidia-jetpack.bspSrc}/bootloader/generic/cfg/flash_t234_qspi_sdmmc.xml >>"$out" |
126 | | - '' |
127 | | - + lib.optionalString (config.hardware.nvidia-jetpack.som == "orin-agx-industrial") '' |
| 167 | + echo "" |
| 168 | + echo "Patching flash.xml with image paths and sizes..." |
| 169 | + "${pkgs.pkgsBuildBuild.gnused}/bin/sed" -i \ |
| 170 | + -e "s#bootloader/esp.img#$WORKDIR/bootloader/esp.img#" \ |
| 171 | + -e "s#root.img#$WORKDIR/bootloader/root.img#" \ |
| 172 | + -e "s#ESP_SIZE#$((ESP_SIZE * 512))#" \ |
| 173 | + -e "s#ROOT_SIZE#$((ROOT_SIZE * 512))#" \ |
| 174 | + flash.xml |
| 175 | + '' |
| 176 | + + lib.optionalString cfg.flashScriptOverrides.onlyQSPI '' |
128 | 177 |
|
129 | | - tail -n ${toString partitionTemplateReplaceRange.lastLineCount} ${pkgs.nvidia-jetpack.bspSrc}/bootloader/generic/cfg/flash_t234_qspi_sdmmc_industrial.xml >>"$out" |
130 | | - '' |
131 | | - ); |
| 178 | + echo "QSPI-only mode: skipping ESP and root partition extraction." |
| 179 | + '' |
| 180 | + + '' |
| 181 | +
|
| 182 | + echo "" |
| 183 | + echo "Ready to flash!" |
| 184 | + echo "============================================================" |
| 185 | + ''; |
132 | 186 | in |
133 | 187 | { |
134 | 188 | config = lib.mkIf cfg.enable { |
135 | 189 | hardware.nvidia-jetpack.flashScriptOverrides.partitionTemplate = partitionTemplate; |
136 | | - hardware.nvidia-jetpack.flashScriptOverrides.preFlashCommands = '' |
137 | | - echo "============================================================" |
138 | | - echo "ghaf flashing script" |
139 | | - echo "============================================================" |
140 | | - echo "ghaf version: ${config.ghaf.version}" |
141 | | - echo "som: ${config.hardware.nvidia-jetpack.som}" |
142 | | - echo "carrierBoard: ${config.hardware.nvidia-jetpack.carrierBoard}" |
143 | | - echo "============================================================" |
144 | | - echo "" |
145 | | - echo "Working dir: $WORKDIR" |
146 | | - echo "Removing bootlodaer/esp.img if it exists ..." |
147 | | - rm -fv "$WORKDIR/bootloader/esp.img" |
148 | | - mkdir -pv "$WORKDIR/bootloader" |
149 | | -
|
150 | | - # See https://developer.download.nvidia.com/embedded/L4T/r35_Release_v4.1/docs/Jetson_Linux_Release_Notes_r35.4.1.pdf |
151 | | - # and https://developer.download.nvidia.com/embedded/L4T/r35_Release_v5.0/docs/Jetson_Linux_Release_Notes_r35.5.0.pdf |
152 | | - # |
153 | | - # In Section: Adaptation to the Carrier Board with HDMI for the Orin |
154 | | - # NX/Nano Modules |
155 | | - #"${pkgs.pkgsBuildBuild.patch}/bin/patch" -p0 < ${./tegra2-mb2-bct-scr.patch} |
156 | | - '' |
157 | | - + lib.optionalString (!cfg.flashScriptOverrides.onlyQSPI) '' |
158 | | - ESP_OFFSET=$(cat "${images}/esp.offset") |
159 | | - ESP_SIZE=$(cat "${images}/esp.size") |
160 | | - ROOT_OFFSET=$(cat "${images}/root.offset") |
161 | | - ROOT_SIZE=$(cat "${images}/root.size") |
162 | | -
|
163 | | - img="${images}/sd-image/${config.image.fileName}" |
164 | | - echo "Extracting ESP partition to $WORKDIR/bootloader/esp.img ..." |
165 | | - dd if=<("${pkgs.pkgsBuildBuild.zstd}/bin/pzstd" -d "$img" -c) of="$WORKDIR/bootloader/esp.img" bs=512 iseek="$ESP_OFFSET" count="$ESP_SIZE" |
166 | | - echo "Extracting root partition to $WORKDIR/root.img ..." |
167 | | - dd if=<("${pkgs.pkgsBuildBuild.zstd}/bin/pzstd" -d "$img" -c) of="$WORKDIR/bootloader/root.img" bs=512 iseek="$ROOT_OFFSET" count="$ROOT_SIZE" |
168 | | -
|
169 | | - echo "Patching flash.xml with absolute paths to esp.img and root.img ..." |
170 | | - "${pkgs.pkgsBuildBuild.gnused}/bin/sed" -i \ |
171 | | - -e "s#bootloader/esp.img#$WORKDIR/bootloader/esp.img#" \ |
172 | | - -e "s#root.img#$WORKDIR/root.img#" \ |
173 | | - -e "s#ESP_SIZE#$((ESP_SIZE * 512))#" \ |
174 | | - -e "s#ROOT_SIZE#$((ROOT_SIZE * 512))#" \ |
175 | | - flash.xml |
176 | | -
|
177 | | - '' |
178 | | - + lib.optionalString cfg.flashScriptOverrides.onlyQSPI '' |
179 | | - echo "Flashing QSPI only, boot and root images not included." |
180 | | - '' |
181 | | - + '' |
182 | | - echo "Ready to flash!" |
183 | | - echo "============================================================" |
184 | | - echo "" |
185 | | - ''; |
| 190 | + hardware.nvidia-jetpack.flashScriptOverrides.preFlashCommands = preFlashCommands; |
186 | 191 | }; |
187 | 192 | } |
0 commit comments