@@ -18,10 +18,12 @@ Usage:
1818 $0 [OPTIONS] <board-name>
1919
2020Options:
21+ -b boot-dir Path to bootloader build directory (default: O= or output/)
22+ -d Download bootloader files from latest-boot release
23+ -f Force re-download of bootloader even if cached
2124 -h This help text
2225 -l List available boards
2326 -o Override auto-detection of genimage.sh, use host installed version
24- -b boot-dir Path to bootloader build directory (default: O= or output/)
2527 -r root-dir Path to rootfs build directory or rootfs.squashfs file (default: O= or output/)
2628
2729Arguments:
@@ -44,8 +46,11 @@ Examples:
4446 # Standalone with separate boot/rootfs builds:
4547 $0 -b x-boot -r output raspberrypi-rpi64
4648
47- # With downloaded rootfs:
48- $0 -b x-boot -r ~/Downloads/rootfs.squashfs friendlyarm-nanopi-r2s
49+ # With downloaded rootfs and bootloader:
50+ $0 -d -r ~/Downloads/rootfs.squashfs friendlyarm-nanopi-r2s
51+
52+ # Download bootloader and compose with Linux image in output directory:
53+ $0 -od bananapi-bpi-r3
4954
5055EOF
5156}
@@ -153,6 +158,83 @@ find_build_dir()
153158 return 1
154159}
155160
161+ # Map board name to bootloader identifier
162+ # Returns bootloader name used in artifact naming
163+ get_bootloader_name ()
164+ {
165+ board=" $1 "
166+ case " $board " in
167+ raspberrypi-rpi64)
168+ echo " rpi64_boot"
169+ ;;
170+ bananapi-bpi-r3)
171+ echo " bpi_r3_boot"
172+ ;;
173+ friendlyarm-nanopi-r2s)
174+ echo " nanopi_r2s_boot"
175+ ;;
176+ * )
177+ err " Unknown bootloader for board: $board "
178+ return 1
179+ ;;
180+ esac
181+ }
182+
183+ # Download and extract bootloader from latest-boot release
184+ # Downloads to dl/bootloader/ cache and extracts to temporary build directory
185+ # Returns the temporary directory path in SDCARD_TEMP_DIR variable
186+ download_bootloader ()
187+ {
188+ board=" $1 "
189+ build_dir=" $2 "
190+
191+ bootloader=$( get_bootloader_name " $board " ) || return 1
192+
193+ if ! command -v gh > /dev/null 2>&1 ; then
194+ die " gh CLI not found. Install it or build bootloader locally."
195+ fi
196+
197+ # Set up download cache directory
198+ dl_dir=" ${BR2_EXTERNAL_INFIX_PATH} /dl/bootloader"
199+ mkdir -p " $dl_dir "
200+
201+ # Convert underscores to dashes for filename pattern matching
202+ bootloader_pattern=$( echo " $bootloader " | tr ' _' ' -' )
203+
204+ # Find or download bootloader tarball
205+ tarball=$( ls " $dl_dir " /${bootloader_pattern} * .tar.gz 2> /dev/null | head -n1)
206+
207+ if [ -z " $tarball " ] || [ -n " $FORCE_DOWNLOAD " ]; then
208+ if [ -n " $FORCE_DOWNLOAD " ] && [ -n " $tarball " ]; then
209+ log " Force re-downloading bootloader..."
210+ rm -f " $tarball " " $tarball .sha256"
211+ else
212+ log " Downloading bootloader $bootloader from latest-boot release..."
213+ fi
214+
215+ if ! gh release download latest-boot \
216+ --repo kernelkit/infix \
217+ --pattern " *${bootloader_pattern} *.tar.gz" \
218+ --dir " $dl_dir " ; then
219+ die " Failed downloading bootloader from latest-boot release. Check gh authentication and network connectivity."
220+ fi
221+
222+ tarball=$( ls " $dl_dir " /${bootloader_pattern} * .tar.gz 2> /dev/null | head -n1)
223+ [ -n " $tarball " ] || die " Downloaded tarball not found in $dl_dir "
224+ else
225+ log " Using cached bootloader: $( basename " $tarball " ) "
226+ fi
227+
228+ # Create temporary directory for SD card composition
229+ SDCARD_TEMP_DIR=" ${build_dir} /sdcard-${board} -$$ "
230+ mkdir -p " $SDCARD_TEMP_DIR "
231+
232+ log " Extracting bootloader to $SDCARD_TEMP_DIR ..."
233+ tar -xzf " $tarball " --strip-components=1 -C " $SDCARD_TEMP_DIR /"
234+
235+ log " Bootloader ready in temporary directory"
236+ }
237+
156238# Discover boot files for Raspberry Pi boot partition
157239# Scans rpi-firmware directory and builds file list for genimage
158240discover_rpi_boot_files ()
@@ -189,8 +271,19 @@ discover_rpi_boot_files()
189271 echo " $files "
190272}
191273
192- while getopts " hlob :r:" opt; do
274+ while getopts " hldfob :r:" opt; do
193275 case $opt in
276+ b)
277+ BOOT_DIR=" $OPTARG "
278+ STANDALONE=1
279+ ;;
280+ d)
281+ DOWNLOAD_BOOT=1
282+ STANDALONE=1
283+ ;;
284+ f)
285+ FORCE_DOWNLOAD=1
286+ ;;
194287 h)
195288 usage
196289 exit 0
@@ -199,10 +292,6 @@ while getopts "hlob:r:" opt; do
199292 list_boards
200293 exit 0
201294 ;;
202- b)
203- BOOT_DIR=" $OPTARG "
204- STANDALONE=1
205- ;;
206295 o)
207296 OVERRIDE=1
208297 ;;
225314
226315# Standalone mode: set up environment from build directories
227316if [ -n " $STANDALONE " ]; then
228- if [ -z " $BOOT_DIR " ]; then
229- BOOT_DIR=$( find_build_dir) || die " Could not find boot directory. Use -b option"
230- fi
317+ # In download mode without explicit dirs, default to same location for both
318+ if [ -n " $DOWNLOAD_BOOT " ]; then
319+ default_dir=$( find_build_dir) || die " Could not find build directory. Set O= or use -b/-r option"
320+ : " ${BOOT_DIR:= $default_dir } "
321+ : " ${ROOT_DIR:= $default_dir } "
322+ else
323+ if [ -z " $BOOT_DIR " ]; then
324+ BOOT_DIR=$( find_build_dir) || die " Could not find boot directory. Use -b option"
325+ fi
231326
232- if [ -z " $ROOT_DIR " ]; then
233- ROOT_DIR=$( find_build_dir) || die " Could not find rootfs directory. Set O= or use -r option"
327+ if [ -z " $ROOT_DIR " ]; then
328+ ROOT_DIR=$( find_build_dir) || die " Could not find rootfs directory. Set O= or use -r option"
329+ fi
234330 fi
235331
236332 # Set up environment variables, some required by genimage.sh
@@ -248,22 +344,33 @@ if [ -n "$STANDALONE" ]; then
248344 fi
249345 done
250346
251- # Copy rootfs and partition images to BINARIES_DIR
347+ # Copy rootfs and partition images to BINARIES_DIR (skip if same directory)
252348 mkdir -p " $BINARIES_DIR "
349+
350+ # Normalize paths for comparison
351+ boot_images=$( cd " $BOOT_DIR " && pwd) /images
352+ root_images=" "
353+
253354 if [ -f " $ROOT_DIR " ]; then
254355 # Direct path to rootfs.squashfs file
255356 log " Copying rootfs from $ROOT_DIR to $BINARIES_DIR /rootfs.squashfs"
256357 cp " $ROOT_DIR " " $BINARIES_DIR /rootfs.squashfs"
257358 elif [ -f " $ROOT_DIR /images/rootfs.squashfs" ]; then
258- # Build directory with images/ - copy rootfs and partition images
259- log " Copying artifacts from $ROOT_DIR /images/ to $BINARIES_DIR /"
260- cp " $ROOT_DIR /images/rootfs.squashfs" " $BINARIES_DIR /"
261- # Copy partition images if they exist
262- for img in aux.ext4 cfg.ext4 var.ext4; do
263- if [ -f " $ROOT_DIR /images/$img " ]; then
264- cp " $ROOT_DIR /images/$img " " $BINARIES_DIR /"
265- fi
266- done
359+ root_images=$( cd " $ROOT_DIR " && pwd) /images
360+ # Only copy if different directories
361+ if [ " $boot_images " != " $root_images " ]; then
362+ # Build directory with images/ - copy rootfs and partition images
363+ log " Copying artifacts from $ROOT_DIR /images/ to $BINARIES_DIR /"
364+ cp " $ROOT_DIR /images/rootfs.squashfs" " $BINARIES_DIR /"
365+ # Copy partition images if they exist
366+ for img in aux.ext4 cfg.ext4 var.ext4; do
367+ if [ -f " $ROOT_DIR /images/$img " ]; then
368+ cp " $ROOT_DIR /images/$img " " $BINARIES_DIR /"
369+ fi
370+ done
371+ else
372+ log " Rootfs already in place at $BINARIES_DIR /"
373+ fi
267374 elif [ -f " $ROOT_DIR /rootfs.squashfs" ]; then
268375 # Directory directly containing rootfs.squashfs
269376 log " Copying rootfs from $ROOT_DIR /rootfs.squashfs"
292399: " ${RELEASE:= " " } "
293400: " ${INFIX_ID:= " infix" } "
294401
402+ # Download bootloader if requested
403+ if [ -n " $DOWNLOAD_BOOT " ]; then
404+ # Save original output location
405+ ORIGINAL_BINARIES_DIR=" $BINARIES_DIR "
406+
407+ download_bootloader " $BOARD " " $BUILD_DIR "
408+
409+ # Now use the temporary directory for composition
410+ BINARIES_DIR=" $SDCARD_TEMP_DIR "
411+
412+ log " Linking rootfs files to $BINARIES_DIR ..."
413+ # Link rootfs and partition images to temp directory
414+ if [ -f " $ROOT_DIR " ]; then
415+ # Direct path to rootfs.squashfs file
416+ ln -sf " $( realpath " $ROOT_DIR " ) " " $BINARIES_DIR /rootfs.squashfs"
417+ elif [ -f " $ROOT_DIR /images/rootfs.squashfs" ]; then
418+ ln -sf " $( realpath " $ROOT_DIR /images/rootfs.squashfs" ) " " $BINARIES_DIR /rootfs.squashfs"
419+ # Link partition images if they exist
420+ for img in aux.ext4 cfg.ext4 var.ext4; do
421+ if [ -f " $ROOT_DIR /images/$img " ]; then
422+ ln -sf " $( realpath " $ROOT_DIR /images/$img " ) " " $BINARIES_DIR /$img "
423+ fi
424+ done
425+ elif [ -f " $ROOT_DIR /rootfs.squashfs" ]; then
426+ ln -sf " $( realpath " $ROOT_DIR /rootfs.squashfs" ) " " $BINARIES_DIR /rootfs.squashfs"
427+ # Link partition images if they exist
428+ for img in aux.ext4 cfg.ext4 var.ext4; do
429+ if [ -f " $ROOT_DIR /$img " ]; then
430+ ln -sf " $( realpath " $ROOT_DIR /$img " ) " " $BINARIES_DIR /$img "
431+ fi
432+ done
433+ else
434+ die " Could not find rootfs.squashfs in $ROOT_DIR "
435+ fi
436+ fi
437+
295438# Template expansion
296439log " Generating genimage configuration for $BOARD ..."
297440
@@ -343,6 +486,25 @@ else
343486 run_genimage " $GENIMAGE_CFG "
344487fi
345488
489+ # Post-processing: move images and cleanup if using download mode
490+ if [ -n " $DOWNLOAD_BOOT " ]; then
491+ log " Moving SD card images to $ORIGINAL_BINARIES_DIR ..."
492+ mkdir -p " $ORIGINAL_BINARIES_DIR "
493+
494+ for img in " ${BINARIES_DIR} " /* -sdcard.img* ; do
495+ if [ -f " $img " ]; then
496+ mv " $img " " $ORIGINAL_BINARIES_DIR /"
497+ log " $( basename " $img " ) "
498+ fi
499+ done
500+
501+ log " Cleaning up temporary directory..."
502+ rm -rf " $SDCARD_TEMP_DIR "
503+
504+ # Update BINARIES_DIR for final output message
505+ BINARIES_DIR=" $ORIGINAL_BINARIES_DIR "
506+ fi
507+
346508log " SD card image created successfully:"
347509for img in " ${BINARIES_DIR} " /* -sdcard.img* ; do
348510 if [ -f " $img " ]; then
0 commit comments