Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F167403253
D58964.id184464.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
45 KB
Referenced Files
None
Subscribers
None
D58964.id184464.diff
View Options
diff --git a/tools/tools/nanobsd/Files/root/change_password b/tools/tools/nanobsd/Files/root/change_password
--- a/tools/tools/nanobsd/Files/root/change_password
+++ b/tools/tools/nanobsd/Files/root/change_password
@@ -30,10 +30,8 @@
passwd root
-cfgslice=`grep '/cfg' /etc/fstab | cut -d \ -f 1`
-
-trap "umount /cfg" 1 2 15 EXIT
mount /cfg
+trap "umount /cfg" 1 2 15 EXIT
cp /etc/master.passwd /etc/passwd /etc/pwd.db /etc/spwd.db /etc/group /cfg
umount /cfg
-trap 1 2 15 EXIT
+trap - 1 2 15 EXIT
diff --git a/tools/tools/nanobsd/Files/root/update b/tools/tools/nanobsd/Files/root/update
--- a/tools/tools/nanobsd/Files/root/update
+++ b/tools/tools/nanobsd/Files/root/update
@@ -35,9 +35,10 @@
. /etc/nanobsd.conf
-if mount | grep ${NANO_DRIVE}s1 > /dev/null ; then
+: "${NANO_DRIVE:?NANO_DRIVE not set in /etc/nanobsd.conf}"
+
+if mount | grep -q -F "${NANO_DRIVE}s1"; then
exec sh /root/updatep2
else
exec sh /root/updatep1
fi
-
diff --git a/tools/tools/nanobsd/Files/root/updatep1 b/tools/tools/nanobsd/Files/root/updatep1
--- a/tools/tools/nanobsd/Files/root/updatep1
+++ b/tools/tools/nanobsd/Files/root/updatep1
@@ -35,19 +35,21 @@
. /etc/nanobsd.conf
-if mount | grep ${NANO_DRIVE}s1 > /dev/null ; then
- echo "You are running partition 1 already"
- echo "you probably want to use 'updatep2' instead"
+: "${NANO_DRIVE:?NANO_DRIVE not set in /etc/nanobsd.conf}"
+
+if mount | grep -q -F "${NANO_DRIVE}s1"; then
+ echo "You are running partition 1 already." >&2
+ echo "You probably want to use 'updatep2' instead." >&2
exit 1
fi
-# Blow away old system.
-dd if=/dev/zero of=/dev/${NANO_DRIVE}s1 bs=1m count=1 > /dev/null 2>&1
+# Blow away old system
+dd if=/dev/zero of="/dev/${NANO_DRIVE}s1" bs=1m count=1 > /dev/null 2>&1
# Copy in new system
-dd of=/dev/${NANO_DRIVE}s1 obs=64k
+dd of="/dev/${NANO_DRIVE}s1" obs=64k
# Check that it worked
-fsck_ffs -n /dev/${NANO_DRIVE}s1a
+fsck_ffs -n "/dev/${NANO_DRIVE}s1a"
-gpart set -a active -i 1 ${NANO_DRIVE}
+gpart set -a active -i 1 "${NANO_DRIVE}"
diff --git a/tools/tools/nanobsd/Files/root/updatep2 b/tools/tools/nanobsd/Files/root/updatep2
--- a/tools/tools/nanobsd/Files/root/updatep2
+++ b/tools/tools/nanobsd/Files/root/updatep2
@@ -35,26 +35,28 @@
. /etc/nanobsd.conf
-if mount | grep ${NANO_DRIVE}s2 > /dev/null ; then
- echo "You are running partition 2 already"
- echo "you probably want to use 'updatep1' instead"
+: "${NANO_DRIVE:?NANO_DRIVE not set in /etc/nanobsd.conf}"
+
+if mount | grep -q -F "${NANO_DRIVE}s2"; then
+ echo "You are running partition 2 already." >&2
+ echo "You probably want to use 'updatep1' instead." >&2
exit 1
fi
# Blow away old system.
-dd if=/dev/zero of=/dev/${NANO_DRIVE}s2 bs=1m count=1 > /dev/null 2>&1
+dd if=/dev/zero of="/dev/${NANO_DRIVE}s2" bs=1m count=1 > /dev/null 2>&1
# Copy in new system
-dd of=/dev/${NANO_DRIVE}s2 obs=64k
+dd of="/dev/${NANO_DRIVE}s2" obs=64k
# Check that it worked
-fsck_ffs -n /dev/${NANO_DRIVE}s2a
+fsck_ffs -n "/dev/${NANO_DRIVE}s2a"
# Update the /etc/fstab
trap "umount /mnt" 1 2 15 EXIT
-mount /dev/${NANO_DRIVE}s2a /mnt
+mount "/dev/${NANO_DRIVE}s2a" /mnt
sed -i "" "s/${NANO_DRIVE}s1/${NANO_DRIVE}s2/" /mnt/conf/base/etc/fstab
sed -i "" "s/${NANO_DRIVE}s1/${NANO_DRIVE}s2/" /mnt/etc/fstab
umount /mnt
trap 1 2 15 EXIT
-gpart set -a active -i 2 ${NANO_DRIVE}
+gpart set -a active -i 2 "${NANO_DRIVE}"
diff --git a/tools/tools/nanobsd/FlashDevice.sub b/tools/tools/nanobsd/FlashDevice.sub
--- a/tools/tools/nanobsd/FlashDevice.sub
+++ b/tools/tools/nanobsd/FlashDevice.sub
@@ -36,7 +36,6 @@
#
sub_FlashDevice () {
-
a1=`echo $1 | tr '[:upper:]' '[:lower:]'`
a2=`echo $2 | tr '[:upper:]' '[:lower:]'`
case $a1 in
@@ -103,7 +102,7 @@
# Version 10.9
# Document No. 20-10-00038
# April 2005
- # Table 2-7
+ # Table 2-7
# NB: notice math error in SDCFJ-4096-388 line.
#
case $a2 in
@@ -155,11 +154,11 @@
;;
siliconsystems)
case $a2 in
- 256|256mb)
- NANO_MEDIASIZE=`expr 260571136 / 512`
- NANO_HEADS=16
- NANO_SECTS=32
- ;;
+ 256|256mb)
+ NANO_MEDIASIZE=`expr 260571136 / 512`
+ NANO_HEADS=16
+ NANO_SECTS=32
+ ;;
4096|4g)
NANO_MEDIASIZE=`expr -e 4224761856 / 512`
NANO_HEADS=16
diff --git a/tools/tools/nanobsd/defaults.sh b/tools/tools/nanobsd/defaults.sh
--- a/tools/tools/nanobsd/defaults.sh
+++ b/tools/tools/nanobsd/defaults.sh
@@ -51,6 +51,8 @@
# where package metadata gets placed
NANO_PKG_META_BASE=/var/db
+# Path to the files directory used by cust_install_files()
+NANO_CUST_FILESDIR="${NANO_TOOLS}/Files"
# Path to mtree file to apply to anything copied by cust_install_files().
# If you specify this, the mtree file *must* have an entry for every file and
# directory located in Files.
@@ -105,25 +107,34 @@
# Late customize commands.
NANO_LATE_CUSTOMIZE=""
-# Newfs parameters to use
-NANO_NEWFS="-b 4096 -f 512 -i 8192 -U"
-NANO_MAKEFS="-o bsize=4096,density=8192,fsize=512,softupdates=1,version=2"
+# makefs parameters to use
+NANO_MAKEFS="-o softupdates=1,version=2"
# The drive name of the media at runtime
NANO_DRIVE=ada0
+#
+# Sector size in bytes.
+# Accepts suffixes and products (4k, 1M, 4x1024)
+#
+NANO_SECTOR_SIZE=512
+
# Target media size in 512 bytes sectors
NANO_MEDIASIZE=4000000
# Number of code images on media (1 or 2)
NANO_IMAGES=2
+#
# 0 -> Leave second image all zeroes so it compresses better.
# 1 -> Initialize second image with a copy of the first
+#
NANO_INIT_IMG2=1
+#
# Size of code file system in 512 bytes sectors
# If zero, size will be as large as possible.
+#
NANO_CODESIZE=0
# Size of configuration file system in 512 bytes sectors
@@ -141,9 +152,11 @@
# Size of the /tmp+/var ramdisk in 512 bytes sectors
NANO_RAM_TMPVARSIZE=10240
-# boot0 flags/options and configuration
-NANO_BOOT0CFG="-o packet -s 1 -m 3"
-NANO_BOOTLOADER="boot/boot0sio"
+# Size of swap partition in 512 bytes sectors
+NANO_SWAP_SIZE=0
+
+# Swap partition encryption
+NANO_SWAP_ENCRYPTION=
# boot2 flags/options
# default force serial console
@@ -159,21 +172,6 @@
# Progress Print level
PPLEVEL=3
-# Set NANO_LABEL to non-blank to form the basis for using /dev/ufs/label
-# in preference to /dev/${NANO_DRIVE}
-# Root partition will be ${NANO_LABEL}s{1,2}
-# /cfg partition will be ${NANO_LABEL}s3
-# /data partition will be ${NANO_LABEL}s4
-NANO_LABEL=""
-NANO_SLICE_ROOT=s1
-NANO_SLICE_ALTROOT=s2
-NANO_SLICE_CFG=s3
-NANO_SLICE_DATA=s4
-NANO_PARTITION_ROOT=a
-NANO_PARTITION_ALTROOT=a
-NANO_ROOT=s1a
-NANO_ALTROOT=s2a
-
# Default ownership for nopriv build
NANO_DEF_UNAME=root
NANO_DEF_GNAME=wheel
@@ -524,43 +522,48 @@
}
#
-# Update the path the files table of the target pkg database from
-# /usr/local/etc to /etc/local. All paths are relative to NANO_WORLDDIR
+# Swap the dir ID with the symlink ID in the pkg_directories table.
+# Remove the dir ID from the directories table
#
-tgt_pkg_update_file_path_etc_local() {
- tgt_pkg shell <<-EOF
- UPDATE files
- SET path = '/etc/local' || SUBSTR(path, 15)
- WHERE path LIKE '/usr/local/etc%';
- EOF
-}
+tgt_pkg_rm_dir2symlink() {
+ local dir dir_id realpath_target symlink symlink_id update_stmt
-#
-# Swap the /tmp ID with the /var/tmp ID in the pkg_directories table.
-# Remove the /tmp directory from the directories table.
-#
-tgt_pkg_link_tmp_var_tmp() {
- local tmp_id var_tmp_id
+ dir="$1"
+ symlink="$2"
- tmp_id=$(tgt_pkg shell "SELECT id FROM directories WHERE path = '/tmp';")
- var_tmp_id=$(tgt_pkg shell "SELECT id FROM directories WHERE path = '/var/tmp';")
+ # Resolve the symlink's target destination to query the database
+ realpath_target=$(realpath -q "${NANO_WORLDDIR}/${dir}/../${symlink}")
+ realpath_target="${realpath_target#$NANO_WORLDDIR}"
- if [ -z "$tmp_id" ] || [ -z "$var_tmp_id" ]; then
- return
+ if [ -n "$realpath_target" ]; then
+ symlink_id=$(tgt_pkg shell "SELECT id FROM directories
+ WHERE path = '${realpath_target}';")
+ fi
+ dir_id=$(tgt_pkg shell "SELECT id FROM directories
+ WHERE path = '/${dir}';")
+ if [ -z "$dir_id" ]; then
+ return 0
+ fi
+
+ # Change any package relation from the dir ID to the symlink ID (if any)
+ if [ -n "$symlink_id" ]; then
+ update_stmt="UPDATE OR IGNORE pkg_directories
+ SET directory_id = ${symlink_id}
+ WHERE directory_id = ${dir_id};"
+ else
+ update_stmt="-- Skip UPDATE: symlink_id is empty"
fi
tgt_pkg shell <<-EOF
BEGIN TRANSACTION;
- -- Change any package relation from the /tmp ID to the /var/tmp ID
- UPDATE OR IGNORE pkg_directories
- SET directory_id = ${var_tmp_id} WHERE directory_id = ${tmp_id};
+ ${update_stmt}
- -- Remove residual /tmp remnants left behind by "OR IGNORE"
- DELETE FROM pkg_directories WHERE directory_id = ${tmp_id};
+ -- Remove residual dir ID remnants left behind by "OR IGNORE"
+ DELETE FROM pkg_directories WHERE directory_id = ${dir_id};
- -- Remove /tmp from the directories table
- DELETE FROM directories WHERE id = ${tmp_id};
+ -- Remove dir ID from the directories table
+ DELETE FROM directories WHERE id = ${dir_id};
COMMIT;
EOF
@@ -569,7 +572,7 @@
# Timestamp all files with NANO_TIMESTAMP in the pkg database
tgt_pkg_time_timestamp() {
if [ -z "$NANO_TIMESTAMP" ]; then
- return
+ return 0
fi
tgt_pkg shell "UPDATE files SET mtime = ${NANO_TIMESTAMP};"
@@ -584,6 +587,7 @@
-o IGNORE_OSVERSION=yes \
-o OSVERSION="$NANO_OSVERSION" \
-o PKG_CACHEDIR="$(nano_pkg_cachedir)" \
+ -o PKG_DBDIR="${NANO_WORLDDIR}/var/db/pkg" \
"$@"
}
@@ -655,7 +659,7 @@
# XXXJL FINGERPRINTS!
cat > "$(nano_pkg_repos_dir)/FreeBSD-local.conf" <<EOF
FreeBSD-local: {
- url: "file:///$(nano_pkg_cachedir)",
+ url: "file://$(nano_pkg_cachedir)",
enabled: no
}
EOF
@@ -802,25 +806,14 @@
done
)
-#
-# Update the path the files table of the target pkg database from
-# /usr/local/etc to /etc/local. All paths are relative to NANO_WORLDDIR
-#
-tgt_pkg_update_file_path_etc_local() {
- tgt_pkg shell <<-EOF
- UPDATE files
- SET path = '/etc/local' || SUBSTR(path, 15)
- WHERE path LIKE '/usr/local/etc%';
- EOF
-}
-
#
# Convert a directory into a symlink. Takes three arguments, the current
# directory, what it should become a symlink to, and optionally, the mode.
# The directory is removed and a symlink is created. If we're doing
# a nopriv build, then append this fact to the metalog
#
-tgt_dir2symlink() (
+tgt_dir2symlink() {
+ (
local dir=$1
local symlink=$2
local mode=${3:-0777}
@@ -828,25 +821,22 @@
cd "${NANO_WORLDDIR}"
rm -xrf "$dir"
- if $do_precompiled && [ -z "$NANO_NOPKGBASE" ]; then
- tgt_pkg shell <<-EOF
- DELETE FROM directories WHERE path = '$dir';
- EOF
+ if [ -n "$NANO_METALOG" ]; then
+ sed -i "" "\=^\./${dir} =d" "$NANO_METALOG"
+ fi
+ if [ -z "$NANO_NOPKGBASE" ]; then
+ tgt_pkg_rm_dir2symlink "$dir" "$symlink" || true
fi
ln -sf "$symlink" "$dir"
+ chmod "$mode" "$dir"
if [ -n "$NANO_METALOG" ]; then
printf "./%s type=link uname=%s gname=%s mode=%s link=%s\n" \
"$dir" "$NANO_DEF_UNAME" "$NANO_DEF_GNAME" "$mode" \
"$symlink" >> "$NANO_METALOG"
fi
- if $do_precompiled && [ -z "$NANO_NOPKGBASE" ]; then
- tgt_pkg shell <<-EOF
- INSERT INTO files (path, uname, gname, perm, fflags, symlink_target)
- VALUES ('$dir', '$NANO_DEF_UNAME', '$NANO_DEF_GNAME', '$mode', 0, '$symlink');
- EOF
- fi
-)
+ )
+}
#
# Generate metalog entries for each intermediate directory in a path.
@@ -902,8 +892,7 @@
# Switch the current root partition in the target file system tab.
# Input: $1 = current root partition, $2 = new root partition
#
-tgt_switch_root_fstab()
-{
+tgt_switch_root_fstab() {
local current new
current="$1"
new="$2"
@@ -1271,8 +1260,13 @@
sed -i "" "\=^\./usr/local/etc =d" "$NANO_METALOG"
sed -i "" -e "s=^\./usr/local/etc/=./etc/local/=g" "$NANO_METALOG"
fi
- if $do_precompiled && [ -z "$NANO_NOPKGBASE" ]; then
- tgt_pkg_update_file_path_etc_local
+ if [ -z "$NANO_NOPKGBASE" ]; then
+ tgt_pkg shell "UPDATE directories
+ SET path = '/etc/local'
+ WHERE path = '/usr/local/etc';"
+ tgt_pkg shell "UPDATE files
+ SET path = '/etc/local' || SUBSTR(path, 15)
+ WHERE path LIKE '/usr/local/etc%';"
fi
fi
@@ -1288,6 +1282,9 @@
nano_pkg_disable_repos
fi
+ # Put /tmp on the /var ramdisk
+ tgt_dir2symlink tmp var/tmp 1777
+
if [ -n "$NANO_METALOG" ]; then
_xxx_pkg_add_var_db_files_to_metalog
fi
@@ -1320,19 +1317,11 @@
tgt_touch conf/base/etc/md_size
tgt_touch conf/base/var/md_size
- # Pick up config files from the special partition
- echo "mount -o ro /dev/${NANO_DRIVE}${NANO_SLICE_CFG}" > conf/default/etc/remount
- tgt_touch conf/default/etc/remount
-
- # Put /tmp on the /var ramdisk (it may already be symlinked)
- if [ -n "$NANO_METALOG" ]; then
- sed -i "" "\=^\./tmp =d" "$NANO_METALOG"
- fi
- tgt_dir2symlink tmp var/tmp 1777
- if [ -z "$NANO_NOPKGBASE" ]; then
- tgt_pkg_link_tmp_var_tmp
- fi
+ # Add the /conf/default/etc/remount file
+ tgt_etc_remount
+ # Make sure that firstboot scripts run so growfs works
+ tgt_touch firstboot
) > ${NANO_LOG}/_.dl 2>&1
}
@@ -1379,6 +1368,8 @@
# entropy through reboots.
entropy_dir="NO" # Disable caching entropy via cron.
dumpdev="NO" # Disable dumpdev.
+growfs_enable="YES" # Attempt to grow the root filesystem on boot.
+growfs_swap_size="${NANO_SWAP_SIZE}" # Size in bytes to specify swap size.
##############################################################
.
@@ -1394,13 +1385,7 @@
tgt_pkg_update_config_files_content etc/defaults/rc.conf
fi
- # Save config file for scripts
- echo "NANO_DRIVE=${NANO_DRIVE}" > etc/nanobsd.conf
- tgt_touch etc/nanobsd.conf
-
- echo "/dev/${NANO_DRIVE}${NANO_ROOT} / ufs ro 1 1" > etc/fstab
- echo "/dev/${NANO_DRIVE}${NANO_SLICE_CFG} /cfg ufs rw,noauto 2 2" >> etc/fstab
- tgt_touch etc/fstab
+ tgt_write_fstab
tgt_dir cfg
# Create directory for eventual /usr/local/etc contents
@@ -1408,6 +1393,53 @@
)
}
+# Write to the /etc/fstab file
+printf_fstab() {
+ printf "%s\t\t%s\t%s\t%s\t\t%s\t%s\n" \
+ "$1" "$2" "$3" "$4" "$5" "$6" >> ${NANO_WORLDDIR}/etc/fstab
+}
+
+get_uefi_bootname() {
+ case "$NANO_ARCH" in
+ amd64) echo BOOTX64 ;;
+ aarch64) echo BOOTAA64 ;;
+ i386) echo BOOTIA32 ;;
+ armv7) echo BOOTARM ;;
+ riscv64) echo BOOTRISCV64 ;;
+ *) err "Unsupported NANO_ARCH '${NANO_ARCH}'" ;;
+ esac
+}
+
+get_bootcode() {
+ local boot_type part_type
+ boot_type="$1"
+ part_type="$2"
+
+ case "$boot_type" in
+ [Bb][Ii][Oo][Ss])
+ case "$part_type" in
+ [Mm][Bb][Rr]) echo "boot/boot" ;;
+ [Gg][Pp][Tt]) echo "boot/gptboot" ;;
+ *) err "Unsupported BIOS partition type '${part_type}'" ;;
+ esac
+ ;;
+ [Uu][Ee][Ff][Ii])
+ # XXXJL we want /boot/loader.efi for Primary/Secondary ESP partitions.
+ # These are supposed to be switched with efibootmgr -n.
+ # For the Recovery ESP with UFS, we want /boot/gptboot.efi,
+ # this allows us to switch using gpart set -a bootonce.
+ # For the Recovery ESP with ZFS, we want /boot/loader.efi,
+ # coupled with a bare-minimum zpool-features(7)?
+ case "$part_type" in
+ [Gg][Pp][Tt]) echo "boot/loader.efi" ;;
+ [Zz][Ff][Ss]) echo "boot/loader.efi" ;;
+ *) err "Unsupported UEFI partition type '${part_type}'" ;;
+ esac
+ ;;
+ *) err "Unsupported boot type '${boot_type}'" ;;
+ esac
+}
+
# Remove all empty directories under NANO_WORLDDIR/usr
prune_usr() {
# Remove all empty directories in /usr
@@ -1449,8 +1481,13 @@
image=$4
dir=$5
- makefs -t ffs ${options} -F "${metalog}" -N "${NANO_WORLDDIR}/etc" \
- -R "${size}b" -T "${NANO_TIMESTAMP}" "${image}" "${dir}"
+ if [ -n "$metalog" ] && [ -f "$metalog" ]; then
+ makefs -t ffs -DxZ ${options} -F "$metalog" -N "${NANO_WORLDDIR}/etc" \
+ -R "${size}b" -T "$NANO_TIMESTAMP" "$image" "$dir"
+ else
+ makefs -t ffs -Z ${options} -N "${NANO_WORLDDIR}/etc" \
+ -R "${size}b" -T "$NANO_TIMESTAMP" "$image" "$dir"
+ fi
}
#
@@ -1489,7 +1526,7 @@
# Input: $1 = type (cfg/data), $2 = output image path, $3 = source dir,
# $4 = label, $5 = size in sectors, $6 = metalog
#
-_populate_part() {
+populate_part() {
local dir fs lbl metalog size type
type=$1
fs=$2
@@ -1528,7 +1565,7 @@
)
fi
- nano_makefs "-DxZ ${NANO_MAKEFS}" "${metalog}" "${size}" "${fs}" "${dir}"
+ nano_makefs "${NANO_MAKEFS}" "${metalog}" "${size}" "${fs}" "${dir}"
fi
}
@@ -1541,13 +1578,13 @@
}
#
-# Thin wrapper around _populate_part for creating
+# Thin wrapper around populate_part for creating
# the configuration partition image file
-# Input: $1 = image path, $2 = source dir, $3 = label, $4 = size in sectors,
-# $5 = metalog
+# Input: $1 = image path, $2 = source dir, $3 = slice number,
+# $4 = size in sectors, $5 = metalog
#
-_populate_cfg_part() {
- _populate_part "cfg" "$1" "$2" "$3" "$4" "$5"
+populate_cfg_part() {
+ populate_part "cfg" "$1" "$2" "$3" "$4" "$5"
}
#
@@ -1559,11 +1596,11 @@
}
#
-# Thin wrapper around _populate_part for creating the data partition image file
+# Thin wrapper around populate_part for creating the data partition image file
# Input: $1 = image path, $2 = source dir, $3 = label, $4 = size, $5 = metalog
#
-_populate_data_part() {
- _populate_part "data" "$1" "$2" "$3" "$4" "$5"
+populate_data_part() {
+ populate_part "data" "$1" "$2" "$3" "$4" "$5"
}
#
@@ -1590,6 +1627,36 @@
exit 2
}
+#
+# Convert a human-readable size string with a suffix (b/k/m/g/t/w) into bytes.
+# Also accepts "x"-delimited products followed by a suffix (e.g., "2x1024k")
+# makefs(8)-size compatible. See NetBSD's strsuftoll(3)
+# Input: $1 = size string (e.g., "512m", "2x1024x1024k")
+# Output: byte count
+#
+strsuftoll() {
+ local num result unit
+
+ num=${1%?}
+ unit=${1#"${num}"}
+
+ case "$unit" in
+ [bB]) result="${num}x${NANO_SECTOR_SIZE}" ;;
+ [kK]) result="${num}x1024" ;;
+ [mM]) result="${num}x1024x1024" ;;
+ [gG]) result="${num}x1024x1024x1024" ;;
+ [tT]) result="${num}x1024x1024x1024x1024" ;;
+ [wW]) result="${num}x4" ;; # sizeof(int)
+ [0-9]) result="$1" ;;
+ *)
+ printf "%s\n" "'$1': illegal number"
+ exit 1
+ ;;
+ esac
+
+ printf "%s" "$(echo "scale=0; $result" | tr 'x' '*' | bc)"
+}
+
#######################################################################
# Common Flash device geometries
#
@@ -1691,17 +1758,25 @@
# Install the stuff under ./Files
# Copy all files from NANO_TOOLS/Files into NANO_WORLDDIR
-cust_install_files() (
- cd "${NANO_TOOLS}/Files"
+cust_install_files() {
+ (
+ cd "$NANO_CUST_FILESDIR"
find . -print | grep -Ev '/(CVS|\.svn|\.hg|\.git)/' |
- cpio ${CPIO_SYMLINK} -Ldumpv ${NANO_WORLDDIR}
+ cpio ${CPIO_SYMLINK} -Ldumpv "$NANO_WORLDDIR"
- if [ -n "${NANO_CUST_FILES_MTREE}" -a -f ${NANO_CUST_FILES_MTREE} ]; then
- CR "mtree -eiU -p /" <${NANO_CUST_FILES_MTREE}
+ if [ -n "$NANO_CUST_FILES_MTREE" ] && [ -f "$NANO_CUST_FILES_MTREE" ]; then
+ if [ -n "$NANO_NOPRIV_BUILD" ]; then
+ # Entries in NANO_CUST_FILES_MTREE must precede NANO_METALOG
+ cat "$NANO_CUST_FILES_MTREE" "$NANO_METALOG" > "${NANO_METALOG}.tmp"
+ mv "${NANO_METALOG}.tmp" "$NANO_METALOG"
+ else
+ CR "mtree -eiU -p /" <"$NANO_CUST_FILES_MTREE"
+ fi
+ else
+ tgt_touch $(find * -type f)
fi
-
- tgt_touch $(find * -type f)
-)
+ )
+}
#######################################################################
# Install packages from ${NANO_PACKAGE_DIR}
@@ -1711,6 +1786,11 @@
# into NANO_WORLDDIR via a nullfs-mounted chroot
#
cust_pkgng() {
+ if ! $do_root && [ -n "$NANO_NOPRIV_BUILD" ]; then
+ pprint 2 'Skipping "cust_pkgng" (unprivileged builds not supported yet)'
+ return 0
+ fi
+
mkdir -p ${NANO_WORLDDIR}/usr/local/etc
local PKG_CONF="${NANO_WORLDDIR}/usr/local/etc/pkg.conf"
local PKGCMD="env BATCH=YES ASSUME_ALWAYS_YES=YES PKG_DBDIR=${NANO_PKG_META_BASE}/pkg SIGNATURE_TYPE=none /usr/sbin/pkg"
@@ -1825,11 +1905,11 @@
# Input: $1 = level, $2 = message
#
pprint() {
- if [ "$1" -le $PPLEVEL ]; then
+ if [ "$1" -le $PPLEVEL ]; then
runtime=$(( $(date +%s) - NANO_STARTTIME ))
printf "%s %.${1}s %s\n" \
"$(date -u -r $runtime +%H:%M:%S)" "#####" "$2" 1>&3
- fi
+ fi
}
# Print the nanobsd.sh command-line option summary to stderr, exit with code 2
@@ -1891,9 +1971,6 @@
NANO_MAKE_CONF_BUILD=${MAKEOBJDIRPREFIX}/make.conf.build
NANO_MAKE_CONF_INSTALL=${NANO_OBJ}/make.conf.install
- # Override user's NANO_DRIVE if they specified a NANO_LABEL
- [ -n "${NANO_LABEL}" ] && NANO_DRIVE="ufs/${NANO_LABEL}" || true
-
# Set a default NANO_TOOLS to NANO_SRC/NANO_TOOLS if it exists.
[ ! -d "${NANO_TOOLS}" ] && [ -d "${NANO_SRC}/${NANO_TOOLS}" ] && \
NANO_TOOLS="${NANO_SRC}/${NANO_TOOLS}" || true
@@ -1911,6 +1988,7 @@
export_var NANO_CONFSIZE
export_var NANO_CUSTOMIZE
export_var NANO_DATASIZE
+ export_var NANO_DISKIMGDIR
export_var NANO_DRIVE
export_var NANO_HEADS
export_var NANO_IMAGES
@@ -1928,6 +2006,8 @@
export_var NANO_PMAKE
export_var NANO_SECTS
export_var NANO_SRC
+ export_var NANO_SWAP_ENCRYPTION
+ export_var NANO_SWAP_SIZE
export_var NANO_TIMESTAMP
export_var NANO_TOOLS
export_var NANO_WORLDDIR
diff --git a/tools/tools/nanobsd/embedded/common b/tools/tools/nanobsd/embedded/common
--- a/tools/tools/nanobsd/embedded/common
+++ b/tools/tools/nanobsd/embedded/common
@@ -168,31 +168,6 @@
NANO_PACKAGE_ONLY=1
-# makefs(8)-size compatible
-# See NetBSD's strsuftoll(3)
-strsuftoll() {
- local num result unit
-
- num=${1%?}
- unit=${1#"${num}"}
-
- case "$unit" in
- [bB]) result="${num}x512" ;;
- [kK]) result="${num}x1024" ;;
- [mM]) result="${num}x1024x1024" ;;
- [gG]) result="${num}x1024x1024x1024" ;;
- [tT]) result="${num}x1024x1024x1024x1024" ;;
- [wW]) result="${num}x4" ;; # sizeof(int)
- [0-9]) result="$1" ;;
- *)
- printf "%s\n" "'$1': illegal number"
- exit 1
- ;;
- esac
-
- printf "%s" "$(echo "scale=0; $result" | tr 'x' '*' | bc)"
-}
-
# Creates images for all the formats that use MBR / GPT
# split later if the #ifdef soup gets too bad.
create_diskimage_gpt() {
diff --git a/tools/tools/nanobsd/gpt.sh b/tools/tools/nanobsd/gpt.sh
new file mode 100644
--- /dev/null
+++ b/tools/tools/nanobsd/gpt.sh
@@ -0,0 +1,489 @@
+#!/bin/sh
+#
+# Copyright (c) 2026 The FreeBSD Project.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+#
+
+set -e
+
+NANO_PLAN=gpt
+
+#
+# Space-separated list of boot types; options: BIOS, UEFI (case-insensitive).
+# Default enables both.
+#
+NANO_BOOT_TYPE="BIOS UEFI"
+
+# EFI System Partition size in 512 bytes sectors
+NANO_EFI_BOOTPART_SIZE=532480
+
+# Set NANO_LABEL to non-blank to form the basis for using /dev/gpt/code
+# in preference to /dev/${NANO_DRIVE}
+# Root partition will be /dev/gpt/${NANO_ROOT, NANO_ALTROOT}
+# /cfg partition will be /dev/gpt/cfg
+# /data partition will be /dev/gpt/data
+NANO_LABEL=code
+NANO_PARTITION_ROOT=1
+NANO_PARTITION_CFG=cfg
+NANO_PARTITION_DATA=data
+
+NANO_ROOT="${NANO_LABEL}${NANO_PARTITION_ROOT}"
+
+if [ "$NANO_IMAGES" -gt 1 ]; then
+ NANO_PARTITION_ALTROOT=2
+ NANO_ALTROOT="${NANO_LABEL}${NANO_PARTITION_ALTROOT}"
+fi
+
+# Override NANO_DRIVE with NANO_LABEL
+if [ -z "${NANO_LABEL}" ]; then
+ err "NANO_LABEL must be defined"
+fi
+
+NANO_BOOTLOADER="boot/gptboot"
+
+NANO_CUST_FILESDIR="${NANO_TOOLS}/gpt/Files"
+NANO_CUST_FILES_MTREE="${NANO_TOOLS}/gpt/Files.mtree"
+
+# Create the /etc/fstab file
+tgt_write_fstab() {
+ (
+ cd "$NANO_WORLDDIR"
+
+ # Save config file for scripts
+ echo "NANO_DRIVE=${NANO_DRIVE}" > etc/nanobsd.conf
+ echo "NANO_LABEL=${NANO_LABEL}" >> etc/nanobsd.conf
+ echo "NANO_ROOT=${NANO_ROOT}" >> etc/nanobsd.conf
+ echo "NANO_ALTROOT=${NANO_ALTROOT}" >> etc/nanobsd.conf
+ tgt_touch etc/nanobsd.conf
+
+ printf_fstab "# Device" Mountpoint FStype Options Dump "Pass#"
+ if is_boot_type UEFI; then
+ printf_fstab "/dev/gpt/efiboot0" /boot/efi msdosfs rw,noauto 2 2
+ fi
+ printf_fstab "/dev/gpt/${NANO_ROOT}" / ufs ro 1 1
+ printf_fstab /dev/gpt/${NANO_PARTITION_CFG} /cfg ufs rw,noauto 2 2
+ if [ "$NANO_SWAP_SIZE" -gt 0 ]; then
+ if [ -n "$NANO_SWAP_ENCRYPTION" ]; then
+ printf_fstab "/dev/gpt/swap0.eli" none swap sw 0 0
+ else
+ printf_fstab "/dev/gpt/swap0" none swap sw 0 0
+ fi
+ fi
+
+ tgt_touch etc/fstab
+ )
+}
+
+# Pick up config files from the special partition
+tgt_etc_remount() {
+ (
+ cd "$NANO_WORLDDIR"
+
+ echo "mount -o ro /dev/gpt/${NANO_PARTITION_CFG}" > conf/default/etc/remount
+ tgt_touch conf/default/etc/remount
+ )
+}
+
+#
+# Check whether a boot type is present in NANO_BOOT_TYPE
+# Input: $1 = boot type to check
+# Output: return 0 if found, 1 if not
+#
+is_boot_type() {
+ local boot_type boot_types
+
+ boot_type=$(echo "$1" | tr "[:upper:]" "[:lower:]")
+ boot_types=$(echo "${NANO_BOOT_TYPE}" | tr "[:upper:]" "[:lower:]")
+
+ # These architectures lack a BIOS
+ case "$NANO_ARCH" in
+ aarch64|riscv64|riscv)
+ case "${boot_type}" in
+ efi|uefi) ;;
+ *) return 1 ;;
+ esac
+ ;;
+ esac
+
+ case " ${boot_types} " in
+ *" ${boot_type} "*) return 0 ;;
+ *) return 1 ;;
+ esac
+}
+
+#
+# Create a FreeBSD Boot Partition image file of 512 KiB
+# Input: $1 = label
+#
+make_boot_partition() {
+ local bootcode name
+
+ name="$1"
+ bootcode="${NANO_WORLDDIR}/${NANO_BOOTLOADER}"
+
+ if [ ! -f "$bootcode" ]; then
+ echo "Image will not be bootable"
+ else
+ cp -p "$bootcode" "${NANO_OBJ}/_.${name}.image"
+ truncate -s 512k "${NANO_OBJ}/_.${name}.image"
+ fi
+}
+
+#
+# Create an EFI System Partition image file
+# Input: $1 = label, $2 = is the recovery ESP?
+#
+make_esp_partition() {
+ local bootcode efibootname espdir fat_size fat_type is_recovery name
+
+ name="$1"
+ is_recovery="${2:-}"
+
+ FAT16MIN=2150400
+ FAT32MIN=34091008
+
+ esp_sects=$(awk -v label="$name" '$5 == label {print $4}' "${NANO_LOG}/_.partitioning")
+ fat_size=$(strsuftoll "${esp_sects:-0}b")
+ if [ "$fat_size" -ge "$FAT32MIN" ]; then
+ fat_type=32
+ elif [ "$fat_size" -ge "$FAT16MIN" ]; then
+ fat_type=16
+ else
+ fat_type=12
+ fi
+
+ espdir="${NANO_OBJ}/_.efi"
+ rm -rf "${espdir}"
+
+ if [ "$is_recovery" = "recovery" ]; then
+ mkdir -p "${espdir}/EFI/BOOT"
+ else
+ mkdir -p "${espdir}/EFI/FreeBSD"
+ fi
+
+ efibootname=$(get_uefi_bootname)
+ bootcode="${NANO_WORLDDIR}/$(get_bootcode uefi gpt)"
+
+ if [ ! -f "$bootcode" ]; then
+ echo "Image will not be bootable"
+ fi
+
+ if [ "$is_recovery" = "recovery" ]; then
+ cp -p "${NANO_WORLDDIR}/boot/gptboot.efi" \
+ "${espdir}/EFI/BOOT/${efibootname}.EFI"
+ else
+ cp -p "$bootcode" "${espdir}/EFI/FreeBSD/loader.efi"
+ fi
+
+ makefs -t msdos \
+ -o fat_type="$fat_type" \
+ -o sectors_per_cluster=1 \
+ -o volume_label="$name" \
+ -o OEM_string="" \
+ -s "$fat_size" \
+ -T "$NANO_TIMESTAMP" \
+ "${NANO_OBJ}/_.${name}.image" "${espdir}"
+
+ rm -rf "${espdir}"
+}
+
+#
+# Calculate partition sizes aligned at 1 MiB boundaries.
+# All sizes are in sectors.
+# The output is compatible with gpart restore
+#
+calculate_partitioning() {
+ local boot_sects boot_size boot_type esp_sects
+ boot_sects=0
+ boot_type=0
+ esp_sects=0
+
+ if is_boot_type BIOS; then
+ boot_type=1
+ # Boot partition is exactly 512 KiB
+ boot_size=$(strsuftoll 512k)
+ boot_sects=$(( boot_size / NANO_SECTOR_SIZE ))
+ fi
+ is_boot_type UEFI && esp_sects="$NANO_EFI_BOOTPART_SIZE"
+
+ echo "$NANO_MEDIASIZE" "$NANO_IMAGES" "$NANO_SECTOR_SIZE" \
+ "$NANO_CODESIZE" "$NANO_CONFSIZE" "$NANO_DATASIZE" "$boot_type" \
+ "$boot_sects" "$esp_sects" "$NANO_SWAP_SIZE" "$NANO_ROOT" \
+ "$NANO_ALTROOT" "$NANO_PARTITION_CFG" "$NANO_PARTITION_DATA" |
+ awk '
+ function roundup(sects) {
+ return int((sects + align - 1) / align) * align
+ }
+ function print_line(type, sects, label, windex, wtype, wblocks) {
+ windex = 3
+ wtype = ($7 == 1 || swap_sects > 0) ? length("freebsd-swap") : length("freebsd-ufs")
+ wblocks = length($1)
+
+ printf "%-*s %*s %*s %*s %s\n",
+ windex, i,
+ wtype, type,
+ wblocks, sstart,
+ wblocks, sects,
+ label
+ sstart += sects
+ avail_sects -= sects
+ i++
+ }
+
+ {
+ # Sector size
+ ssize = $3
+
+ # Align to a 1 MiB boundary in sectors
+ align = int((1024 * 1024) / ssize)
+
+ # GPT backup metadata at the end of the disk in sectors
+ # (128 entries x 128 bytes + 1 header sector)
+ gpt_end_sects = int(16384 / ssize) + 1
+
+ # Boot size in sectors (already rounded up)
+ boot_sects = ($8 > 0) ? $8 : 0
+
+ # ESP size in sectors (rounded up)
+ esp_sects = ($9 > 0) ? roundup($9) : 0
+
+ # Swap size in sectors (rounded up)
+ swap_sects = ($10 > 0) ? roundup($10) : 0
+
+ # Configuration partition size in sectors (rounded up)
+ cfg_sects = roundup($5)
+
+ # Data partition size in sectors (rounded up)
+ data_sects = ($6 > 0) ? roundup($6) : $6
+
+ # Starting sector (512/4K-bytes aligned)
+ sstart = 40
+
+ # Available sectors
+ avail_sects = $1 - sstart - gpt_end_sects
+
+ # Print header (scheme and number of entries)
+ print "GPT 128"
+
+ # Partition index counter
+ i = 1
+
+ # Boot partition (if any)
+ if ($7 == 1) {
+ print_line("freebsd-boot", boot_sects, "gptboot0")
+ }
+
+ # Starting sector (1 MiB aligned)
+ avail_sects -= (align - sstart)
+ sstart = align
+
+ # ESP partition (if any)
+ if (esp_sects > 0) {
+ print_line("efi", esp_sects, "efiboot0")
+ }
+
+ if (swap_sects > 0) {
+ print_line("freebsd-swap", swap_sects, "swap0")
+ }
+
+ # Code partition size in sectors
+ code_sects = $4
+ if (code_sects == 0) {
+ # (rounded down)
+ total_code_sects = avail_sects - cfg_sects - \
+ ((data_sects > 0) ? data_sects : 0)
+ total_code_sects = int(total_code_sects / align) * align
+ code_sects = int((total_code_sects / $2) / align) * align
+ } else {
+ # (rounded up)
+ code_sects = roundup(code_sects)
+ }
+
+ # First code partition
+ print_line("freebsd-ufs", code_sects, $11)
+
+ # Second code partition (if any)
+ if ($2 > 1) {
+ print_line("freebsd-ufs", code_sects, $12)
+ }
+
+ # Configuration partition
+ print_line("freebsd-ufs", cfg_sects, $13)
+
+ # Data partition (if any)
+ if (data_sects > 0) {
+ print_line("freebsd-ufs", data_sects, $14)
+ } else if (data_sects < 0 && avail_sects > 0) {
+ print_line("freebsd-ufs", avail_sects, $14)
+ }
+
+ # Overcommit check
+ if (avail_sects < 0) {
+ print "Disk space overcommitted by", \
+ (avail_sects * -1), "sectors" > "/dev/stderr"
+ exit 2
+ }
+ }' > "${NANO_LOG}/_.partitioning"
+}
+
+# Create the code partition image
+create_code_partition() {
+ pprint 2 "build code partition"
+ pprint 3 "log: ${NANO_OBJ}/_.cp"
+
+ (
+ local IMG code_sects
+
+ IMG=${NANO_DISKIMGDIR}/${NANO_IMG1NAME}
+ code_sects=$(awk -v label="$NANO_ROOT" '$5 == label {print $4}' "${NANO_LOG}/_.partitioning")
+
+ echo "Writing code image..."
+ nano_makefs "${NANO_MAKEFS} -o minfree=0,optimization=space" \
+ "$NANO_METALOG" "$code_sects" "$IMG" "$NANO_WORLDDIR"
+ ) > "${NANO_OBJ}/_.cp" 2>&1
+}
+
+_create_diskimage() {
+ create_diskimage
+}
+
+# Assemble the final GPT disk image from pre-built partition images using mkimg
+create_diskimage() {
+ pprint 2 "build diskimage"
+ pprint 3 "log: ${NANO_OBJ}/_.di"
+
+ (
+ local IMG code_sects code_size
+ local bootcode cfg data efiboot0 gptboot0 swap0
+ local code1 "${NANO_ROOT}" code2 "${NANO_ALTROOT}" # XXXJL NANO_ALTROOT
+
+ IMG=${NANO_DISKIMGDIR}/${NANO_IMGNAME}
+ code_sects=$(awk -v label="$NANO_ROOT" '$5 == label {print $4}' "${NANO_LOG}/_.partitioning")
+ code_size=$(( code_sects * NANO_SECTOR_SIZE ))
+
+ # Build mkimg partition entries
+ if [ -f "${NANO_WORLDDIR}/boot/pmbr" ]; then
+ bootcode="-b ${NANO_WORLDDIR}/boot/pmbr"
+ fi
+
+ for image in gptboot0 efiboot0 swap0 \
+ ${NANO_ROOT} ${NANO_ALTROOT} cfg data; do
+ match=$(awk -v dir="$NANO_OBJ" -v img="$image" -v ssize="$NANO_SECTOR_SIZE" \
+ '$5 == img {
+ if ($5 == "swap0") {
+ print "-p", $2 "/" $5 "::" ($4 * ssize) ":" ($3 * ssize)
+ } else {
+ print "-p", $2 "/" $5 ":=" dir "/_." $5 ".image:" ($3 * ssize)
+ }
+ }' "${NANO_LOG}/_.partitioning")
+
+ if [ -n "$match" ]; then
+ eval "${image}=\"\${match}\""
+ else
+ eval "${image}=\"\""
+ fi
+ done
+
+ # Use fixed variable names when dealing with code partitions
+ eval "code1=\"\$${NANO_ROOT}\""
+ eval "code2=\"\$${NANO_ALTROOT}\""
+
+ # Rename code1 image name to match NANO_IMG1NAME
+ code1=$(echo "$code1" | sed "s|${NANO_OBJ}/_.${NANO_ROOT}.image|${NANO_DISKIMGDIR}/${NANO_IMG1NAME}|")
+
+ # Create boot partition (if any)
+ if is_boot_type BIOS; then
+ make_boot_partition "gptboot0"
+ fi
+
+ # Create ESP partition (if any)
+ if is_boot_type UEFI; then
+ make_esp_partition "efiboot0" "recovery"
+ fi
+
+ # Swap partition must be greater than 100 MiB
+ if [ "$NANO_SWAP_SIZE" -gt 0 ] && [ "$NANO_SWAP_SIZE" -lt 104857600 ]; then
+ err "Swap size (${NANO_SWAP_SIZE}) too small (must be > 100 MiB)."
+ fi
+
+ # Create secondary code partition (if any)
+ if [ "$NANO_IMAGES" -gt 1 ]; then
+ if [ "$NANO_INIT_IMG2" -gt 0 ]; then
+ echo "Duplicating to second image..."
+ tgt_switch_root_fstab 1 2
+ nano_makefs "${NANO_MAKEFS} -o minfree=0,optimization=space" \
+ "${NANO_METALOG}" "$code_sects" \
+ "${NANO_OBJ}/_.${NANO_ALTROOT}.image" "${NANO_WORLDDIR}"
+ tgt_switch_root_fstab 2 1
+ else
+ code2=$(echo "$code2" |
+ sed "s#=${NANO_OBJ}/_.${NANO_ALTROOT}.image#:${code_size}#")
+ fi
+ fi
+
+ # Create cfg partition
+ populate_cfg_part "${NANO_OBJ}/_.cfg.image" \
+ "$NANO_CFGDIR" "$NANO_PARTITION_CFG" "$NANO_CONFSIZE" \
+ "$NANO_METALOG_CFG"
+
+ # Create data partition (if any)
+ if [ "${NANO_DATASIZE}" -ne 0 ]; then
+ populate_data_part "${NANO_OBJ}/_.data.image" \
+ "$NANO_DATADIR" "$NANO_PARTITION_DATA" "$DATA_SIZE" \
+ "$NANO_METALOG_DATA"
+ fi
+
+ echo "Writing out ${NANO_IMGNAME}..."
+ mkimg -s gpt -S ${NANO_SECTOR_SIZE} \
+ --capacity $(( NANO_MEDIASIZE * NANO_SECTOR_SIZE )) \
+ ${bootcode} \
+ ${gptboot0} \
+ ${efiboot0} \
+ ${swap0} \
+ ${code1} \
+ ${code2} \
+ ${cfg} \
+ ${data} \
+ -o ${IMG}
+
+ # Cleanup
+ rm -f "${NANO_OBJ}/_.gptboot0.image" \
+ "${NANO_OBJ}/_.efiboot0.image" \
+ "${NANO_OBJ}/_.${NANO_ALTROOT}.image" \
+ "${NANO_OBJ}/_.cfg.image" \
+ "${NANO_OBJ}/_.data.image" \
+ ) > "${NANO_LOG}/_.di" 2>&1
+}
+
+# XXXJL FIXME
+tgt_switch_root_fstab() {
+ local current new
+ current="$1"
+ new="$2"
+
+ for f in ${NANO_WORLDDIR}/etc/fstab ${NANO_WORLDDIR}/conf/base/etc/fstab; do
+ sed -i "" "s=/dev/gpt/efiboot${current}=/dev/gpt/efiboot${new}=g" "${f}"
+ sed -i "" "s=/dev/gpt/${NANO_LABEL}${current}=/dev/gpt/${NANO_LABEL}${new}=g" "${f}"
+ done
+}
diff --git a/tools/tools/nanobsd/gpt/Files.mtree b/tools/tools/nanobsd/gpt/Files.mtree
new file mode 100644
--- /dev/null
+++ b/tools/tools/nanobsd/gpt/Files.mtree
@@ -0,0 +1,10 @@
+. type=dir uname=root gname=wheel mode=0755
+./usr type=dir uname=root gname=wheel mode=0755
+./usr/local type=dir uname=root gname=wheel mode=0755
+./usr/local/sbin type=dir uname=root gname=wheel mode=0755
+./usr/local/sbin/change_password type=file uname=root gname=wheel mode=0555
+./usr/local/sbin/save_cfg type=file uname=root gname=wheel mode=0555
+./usr/local/sbin/save_sshkeys type=file uname=root gname=wheel mode=0555
+./usr/local/sbin/update type=file uname=root gname=wheel mode=0555
+./usr/local/sbin/updatep1 type=file uname=root gname=wheel mode=0555
+./usr/local/sbin/updatep2 type=file uname=root gname=wheel mode=0555
diff --git a/tools/tools/nanobsd/Files/root/change_password b/tools/tools/nanobsd/gpt/Files/usr/local/sbin/change_password
copy from tools/tools/nanobsd/Files/root/change_password
copy to tools/tools/nanobsd/gpt/Files/usr/local/sbin/change_password
--- a/tools/tools/nanobsd/Files/root/change_password
+++ b/tools/tools/nanobsd/gpt/Files/usr/local/sbin/change_password
@@ -30,10 +30,8 @@
passwd root
-cfgslice=`grep '/cfg' /etc/fstab | cut -d \ -f 1`
-
trap "umount /cfg" 1 2 15 EXIT
mount /cfg
-cp /etc/master.passwd /etc/passwd /etc/pwd.db /etc/spwd.db /etc/group /cfg
+cp -p /etc/master.passwd /etc/passwd /etc/pwd.db /etc/spwd.db /etc/group /cfg
umount /cfg
-trap 1 2 15 EXIT
+trap - 1 2 15 EXIT
diff --git a/tools/tools/nanobsd/gpt/Files/usr/local/sbin/save_cfg b/tools/tools/nanobsd/gpt/Files/usr/local/sbin/save_cfg
new file mode 100644
--- /dev/null
+++ b/tools/tools/nanobsd/gpt/Files/usr/local/sbin/save_cfg
@@ -0,0 +1,100 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 Mathieu Arnold
+# Copyright (c) 2010 Alex Bakhtin
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+set -e
+
+mount /cfg
+trap "umount /cfg" 1 2 15 EXIT
+
+(
+cd /etc
+find . -type f 2>/dev/null | while read -r relative_path; do
+ filename="${relative_path#./}"
+ if [ ! -f "/cfg/${filename}" ] &&
+ [ ! -f "/cfg/.ignore/${filename}" ]; then
+ #
+ # If file doesn't exist in /cfg and file is not in the "ignore"
+ # list then check if this file is exactly the same as original
+ # file in nanobsd image
+ #
+ if ! cmp -s "/etc/${filename}" "/conf/base/etc/${filename}"; then
+ file_path="${filename%/*}"
+ if [ "$file_path" != "$filename" ]; then
+ if [ ! -d "/etc/${file_path}" ]; then
+ echo "Error: Path /etc/${file_path} is not a directory." >&2
+ exit 1;
+ fi
+ fi
+
+ #
+ # Ask user - how should we handle this file.
+ # Add to cfg (y/n/i)?
+ # y) -> save this file in /cfg
+ # n) -> do not save this file in /cfg for current
+ # script invocation ONLY
+ # i) -> add file to ignore list (/cfg/.ignore hierarchy)
+ # and never try to add this file to /cfg.
+ #
+ # touch is used to add files to /cfg to keep the script
+ # flow straight and easy
+ #
+ read -rp "New file /etc/${filename} found. Add to /cfg (y/n/i)? " key < /dev/tty
+ case "$key" in
+ [yY])
+ if [ "$file_path" != "$filename" ]; then
+ mkdir -vp "/cfg/${file_path}"
+ fi
+ touch "/cfg/${filename}" &&
+ echo "File /etc/${filename} added to /cfg."
+ ;;
+ [iI])
+ mkdir -vp /cfg/.ignore
+ if [ "$file_path" != "$filename" ]; then
+ mkdir -vp "/cfg/.ignore/${file_path}"
+ fi
+ touch "/cfg/.ignore/${filename}" &&
+ echo "File /etc/${filename} added to ignore list."
+ ;;
+ esac
+ fi
+ fi
+done || exit 1
+
+#
+# Actually check all files in /cfg and save if necessary
+#
+cd /cfg
+find . -type f 2>/dev/null | while read -r relative_path; do
+ filename="${relative_path#./}"
+
+ case "$filename" in
+ .ignore/*) continue ;;
+ esac
+
+ if [ -f "/etc/${filename}" ]; then
+ cmp -s "/etc/${filename}" "/cfg/${filename}" ||
+ cp -pfv "/etc/${filename}" "/cfg/${filename}"
+ else
+ #
+ # Give user an option to remove file from /cfg if this file is
+ # removed from /etc
+ #
+ read -rp "File /cfg/${filename} not found in /etc. Remove from /cfg (y/n)? " key < /dev/tty
+ case "$key" in
+ [yY])
+ rm "/cfg/${filename}" &&
+ echo "File /cfg/${filename} removed"
+ ;;
+ esac
+ fi
+done
+)
+
+umount /cfg
+trap - 1 2 15 EXIT
diff --git a/tools/tools/nanobsd/gpt/Files/usr/local/sbin/save_sshkeys b/tools/tools/nanobsd/gpt/Files/usr/local/sbin/save_sshkeys
new file mode 100644
--- /dev/null
+++ b/tools/tools/nanobsd/gpt/Files/usr/local/sbin/save_sshkeys
@@ -0,0 +1,25 @@
+#!/bin/sh
+#
+# Copyright (c) 2004-2005 Poul-Henning Kamp.
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+set -e
+
+mount /cfg
+trap "umount /cfg" 1 2 15 EXIT
+
+mkdir -p /cfg/ssh
+(
+cd /etc/ssh
+for keyfile in ./ssh_host_*; do
+ if [ -f "$keyfile" ]; then
+ cp -p "$keyfile" /cfg/ssh/
+ fi
+done
+)
+
+umount /cfg
+trap - 1 2 15 EXIT
diff --git a/tools/tools/nanobsd/gpt/Files/usr/local/sbin/update b/tools/tools/nanobsd/gpt/Files/usr/local/sbin/update
new file mode 100644
--- /dev/null
+++ b/tools/tools/nanobsd/gpt/Files/usr/local/sbin/update
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Copyright (c) 2026 [XXX]
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+set -e
+
+. /etc/nanobsd.conf
+
+: "${NANO_ROOT:?NANO_ROOT not set in /etc/nanobsd.conf}"
+: "${NANO_ALTROOT:?NANO_ALTROOT not set in /etc/nanobsd.conf}"
+
+current_root=$(df -n / | awk 'END {print $1}')
+
+case "$current_root" in
+"/dev/gpt/${NANO_ALTROOT}")
+ exec sh /usr/local/sbin/updatep1
+ ;;
+"/dev/gpt/${NANO_ROOT}")
+ exec sh /usr/local/sbin/updatep2
+ ;;
+*)
+ echo "Invalid root device '${current_root}'." >&2
+ exit 1
+ ;;
+esac
diff --git a/tools/tools/nanobsd/legacy.sh b/tools/tools/nanobsd/legacy.sh
--- a/tools/tools/nanobsd/legacy.sh
+++ b/tools/tools/nanobsd/legacy.sh
@@ -37,6 +37,34 @@
#
METADATA_SECTS=16
+# Newfs parameters to use
+NANO_NEWFS="-b 4096 -f 512 -i 8192 -U"
+
+# makefs parameters to use
+NANO_MAKEFS="-o bsize=4096,density=8192,fsize=512,softupdates=1,version=2"
+
+# Set NANO_LABEL to non-blank to form the basis for using /dev/ufs/label
+# in preference to /dev/${NANO_DRIVE}
+# Root partition will be ${NANO_LABEL}s{1,2}
+# /cfg partition will be ${NANO_LABEL}s3
+# /data partition will be ${NANO_LABEL}s4
+NANO_LABEL=""
+NANO_SLICE_ROOT=s1
+NANO_SLICE_ALTROOT=s2
+NANO_SLICE_CFG=s3
+NANO_SLICE_DATA=s4
+NANO_PARTITION_ROOT=a
+NANO_PARTITION_ALTROOT=a
+NANO_ROOT=s1a
+NANO_ALTROOT=s2a
+
+# Override user's NANO_DRIVE if they specified a NANO_LABEL
+[ -n "${NANO_LABEL}" ] && NANO_DRIVE="ufs/${NANO_LABEL}" || true
+
+# boot0 flags/options and configuration
+NANO_BOOT0CFG="-o packet -s 1 -m 3"
+NANO_BOOTLOADER="boot/boot0sio"
+
#######################################################################
# Functions and variable definitions used by the legacy nanobsd
# image building system.
@@ -120,6 +148,8 @@
pprint 3 "log: ${NANO_OBJ}/_.cs"
(
+ local CODE_SIZE IMG MNT
+
IMG=${NANO_DISKIMGDIR}/${NANO_IMG1NAME}
MNT=${NANO_OBJ}/_.mnt
mkdir -p ${MNT}
@@ -176,6 +206,8 @@
pprint 3 "log: ${NANO_OBJ}/_.cs"
(
+ local CODE_SIZE IMG
+
IMG=${NANO_DISKIMGDIR}/${NANO_IMG1NAME}
CODE_SIZE=$(awk '$3 == 1 {print $2}' "${NANO_LOG}/_.partitioning")
@@ -186,7 +218,7 @@
else
echo "Partition will not be bootable"
fi
- nano_makefs "-DxZ ${NANO_MAKEFS} -o minfree=0,optimization=space" \
+ nano_makefs "${NANO_MAKEFS} -o minfree=0,optimization=space" \
"${NANO_METALOG}" "$(( CODE_SIZE - METADATA_SECTS ))" \
"${NANO_OBJ}/_.disk.part" "${NANO_WORLDDIR}"
mkimg -s bsd -S 512 --capacity $(( CODE_SIZE * 512 )) \
@@ -274,8 +306,7 @@
# Create Data slice, if any.
if [ -n "$NANO_SLICE_DATA" -a "$NANO_SLICE_CFG" = "$NANO_SLICE_DATA" -a \
"$NANO_DATASIZE" -ne 0 ]; then
- pprint 2 "NANO_SLICE_DATA is the same as NANO_SLICE_CFG, fix."
- exit 2
+ err "NANO_SLICE_DATA is the same as NANO_SLICE_CFG, fix."
fi
if [ $NANO_DATASIZE -ne 0 -a -n "$NANO_SLICE_DATA" ]; then
populate_data_slice /dev/${MD}${NANO_SLICE_DATA} "${NANO_DATADIR}" ${MNT} "${NANO_SLICE_DATA}"
@@ -310,6 +341,7 @@
pprint 3 "log: ${NANO_OBJ}/_.di"
(
+ local CODE_SIZE CONF_SIZE DATA_SIZE
local altroot bootloader cfgimage dataimage diskimage
CODE_SIZE=$(awk '$3 == 1 {print $2}' "${NANO_LOG}/_.partitioning")
@@ -332,7 +364,7 @@
if [ "$NANO_INIT_IMG2" -gt 0 ]; then
echo "Duplicating to second image..."
tgt_switch_root_fstab "${NANO_SLICE_ROOT}" "${NANO_SLICE_ALTROOT}"
- nano_makefs "-DxZ ${NANO_MAKEFS} -o minfree=0,optimization=space" \
+ nano_makefs "${NANO_MAKEFS} -o minfree=0,optimization=space" \
"${NANO_METALOG}" "$(( CODE_SIZE - METADATA_SECTS ))" \
"${NANO_OBJ}/_.altroot.part" "${NANO_WORLDDIR}"
tgt_switch_root_fstab "${NANO_SLICE_ALTROOT}" "${NANO_SLICE_ROOT}"
@@ -353,7 +385,7 @@
fi
# Create Config slice
- _populate_cfg_part "${NANO_OBJ}/_.cfg.part" "${NANO_CFGDIR}" \
+ populate_cfg_part "${NANO_OBJ}/_.cfg.part" "${NANO_CFGDIR}" \
"${NANO_SLICE_CFG}" "${CONF_SIZE}" "${NANO_METALOG_CFG}"
cfgimage="-p freebsd:=${NANO_OBJ}/_.cfg.part"
@@ -361,11 +393,10 @@
if [ -n "${NANO_SLICE_DATA}" ] &&
[ "${NANO_SLICE_CFG}" = "${NANO_SLICE_DATA}" ] &&
[ "${NANO_DATASIZE}" -ne 0 ]; then
- pprint 2 "NANO_SLICE_DATA is the same as NANO_SLICE_CFG, fix."
- exit 2
+ err "NANO_SLICE_DATA is the same as NANO_SLICE_CFG, fix."
fi
if [ "${NANO_DATASIZE}" -ne 0 ] && [ -n "${NANO_SLICE_DATA}" ]; then
- _populate_data_part "${NANO_OBJ}/_.data.part" "${NANO_DATADIR}" \
+ populate_data_part "${NANO_OBJ}/_.data.part" "${NANO_DATADIR}" \
"${NANO_SLICE_DATA}" "${DATA_SIZE}" "${NANO_METALOG_DATA}"
dataimage="-p freebsd:=${NANO_OBJ}/_.data.part"
fi
@@ -384,3 +415,29 @@
"${NANO_OBJ}/_.data.part"
) > ${NANO_LOG}/_.di 2>&1
}
+
+# Create the /etc/fstab file
+tgt_write_fstab() {
+ (
+ cd "$NANO_WORLDDIR"
+
+ # Save config file for scripts
+ echo "NANO_DRIVE=${NANO_DRIVE}" > etc/nanobsd.conf
+ tgt_touch etc/nanobsd.conf
+
+ printf_fstab "# Device" Mountpoint FStype Options Dump "Pass#"
+ printf_fstab "/dev/${NANO_DRIVE}${NANO_ROOT}" / ufs ro 1 1
+ printf_fstab "/dev/${NANO_DRIVE}${NANO_SLICE_CFG}" /cfg ufs rw,noauto 2 2
+ tgt_touch etc/fstab
+ )
+}
+
+# Pick up config files from the special partition
+tgt_etc_remount() {
+ (
+ cd "$NANO_WORLDDIR"
+
+ echo "mount -o ro /dev/${NANO_DRIVE}${NANO_SLICE_CFG}" > conf/default/etc/remount
+ tgt_touch conf/default/etc/remount
+ )
+}
diff --git a/tools/tools/nanobsd/nanobsd.sh b/tools/tools/nanobsd/nanobsd.sh
--- a/tools/tools/nanobsd/nanobsd.sh
+++ b/tools/tools/nanobsd/nanobsd.sh
@@ -28,6 +28,23 @@
set -e
+legacy() {
+ # Pull in legacy stuff on demand
+ . "${topdir}/legacy.sh"
+}
+
+gpt() {
+ # Pull in gpt stuff on demand
+ . "${topdir}/gpt.sh"
+}
+
+is_defined() {
+ case $(type $1 2>/dev/null) in
+ *function) return 0 ;;
+ *) return 1 ;;
+ esac
+}
+
nanobsd_sh=$(realpath $0)
topdir=$(dirname ${nanobsd_sh})
. "${topdir}/_xxx_includes.subr"
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Aug 22, 2:01 PM (4 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37086979
Default Alt Text
D58964.id184464.diff (45 KB)
Attached To
Mode
D58964: nanobsd: Add gpt support
Attached
Detach File
Event Timeline
Log In to Comment