From b196ad7d52c7c7403bc12b5f42238a653899a3b8 Mon Sep 17 00:00:00 2001 From: MeexReay Date: Sat, 15 Mar 2025 19:53:59 +0300 Subject: [PATCH] some fixes mb --- install | 34 ++ isolinux/isolinux.cfg.in | 2 +- mkiso | 975 +++++++++++++++++++++++++++++++++++++++ mkmine | 83 ++++ 4 files changed, 1093 insertions(+), 1 deletion(-) create mode 100755 install create mode 100755 mkiso create mode 100755 mkmine diff --git a/install b/install new file mode 100755 index 0000000..a1bc63e --- /dev/null +++ b/install @@ -0,0 +1,34 @@ +#!/bin/bash + +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root" + exit 1 +fi + +IMAGE_FILE=$1 +DISK_FILE=$2 + +mkdir -p build +cp $IMAGE_FILE build/live_cd.iso + +isohybrid --partok build/live_cd.iso + +echo "Partitioning $DISK_FILE..." + +wipefs -a "$DISK_FILE" + +parted -s "$DISK_FILE" mklabel msdos + +parted -s "$DISK_FILE" mkpart primary ext4 2048s 1G +parted -s "$DISK_FILE" set 1 boot on + +parted -s "$DISK_FILE" mkpart primary ext4 1G 100% + +fdisk -l "$DISK_FILE" + +echo "Partitioning complete." + +mkfs -t ext4 "$DISK_FILE" + +dd if=build/live_cd.iso of="$DISK_FILE" bs=1M status=progress +dd if=/usr/lib/syslinux/mbr.bin of="$DISK_FILE" status=progress diff --git a/isolinux/isolinux.cfg.in b/isolinux/isolinux.cfg.in index 3c51baa..327aa40 100644 --- a/isolinux/isolinux.cfg.in +++ b/isolinux/isolinux.cfg.in @@ -6,4 +6,4 @@ color black/black black/black LABEL linux MENU LABEL @@BOOT_TITLE@@ @@KERNVER@@ @@ARCH@@ KERNEL /boot/vmlinuz -APPEND initrd=/boot/initrd root=live:CDLABEL=VOID_LIVE init=/sbin/init ro rd.luks=0 rd.md=0 rd.dm=0 loglevel=1 vconsole.unicode=1 vconsole.keymap=@@KEYMAP@@ locale.LANG=@@LOCALE@@ @@BOOT_CMDLINE@@ live.autologin live.user=player quiet splash vt.color=0 vga=0x301 +APPEND initrd=/boot/initrd root=live:CDLABEL=VOID_LIVE rw init=/sbin/init rd.luks=0 rd.md=0 rd.dm=0 loglevel=1 vconsole.unicode=1 vconsole.keymap=@@KEYMAP@@ locale.LANG=@@LOCALE@@ @@BOOT_CMDLINE@@ live.autologin live.user=player quiet splash vt.color=0 vga=0x301 diff --git a/mkiso b/mkiso new file mode 100755 index 0000000..ab854b7 --- /dev/null +++ b/mkiso @@ -0,0 +1,975 @@ +#!/bin/bash + +readonly LIBTOOLS="cp echo cat printf which mountpoint mount umount modprobe" +readonly HOSTARCH=$(xbps-uhelper arch) + +is_target_native() { + # Because checking whether the target is runnable is ugly, stuff + # it into a single function. That makes it easy to check anywhere. + local target_arch + + target_arch="$1" + # this will cover most + if [ "${target_arch%-musl}" = "${HOSTARCH%-musl}" ]; then + return 0 + fi + + case "$HOSTARCH" in + # ppc64le has no 32-bit variant, only runs its own stuff + ppc64le*) return 1 ;; + # x86_64 also runs i686 + x86_64*) test -z "${target_arch##*86*}" ;; + # aarch64 also runs armv* + aarch64*) test -z "${target_arch##armv*}" ;; + # bigendian ppc64 also runs ppc + ppc64*) test "${target_arch%-musl}" = "ppc" ;; + # anything else is just their own + *) return 1 ;; + esac + + return $? +} + +version() ( + set +u + [ -n "$PROGNAME" ] && printf "%s " "$PROGNAME" + echo "$(cat ./version) ${MKLIVE_REV:-"$(git -c safe.directory="$(pwd)" rev-parse --short HEAD 2> /dev/null)"}" +) + +info_msg() { + # This function handles the printing that is bold within all + # scripts. This is a convenience function so that the rather ugly + # looking ASCII escape codes live in only one place. + printf "\033[1m%s\n\033[m" "$@" +} + +die() { + # This function is registered in all the scripts to make sure that + # the important mounts get cleaned up and the $ROOTFS location is + # removed. + printf "FATAL: %s\n" "$@" + umount_pseudofs + [ -d "$ROOTFS" ] && rm -rf "$ROOTFS" + exit 1 +} + +check_tools() { + # All scripts within mklive declare the tools they will use in a + # variable called "REQTOOLS". This function checks that these + # tools are available and prints out the path to each tool that + # will be used. This can be useful to figure out what is broken + # if a different version of something is used than was expected. + for tool in $LIBTOOLS $REQTOOLS ; do + if ! which "$tool" > /dev/null ; then + die "Required tool $tool is not available on this system!" + fi + done + + info_msg "The following tools will be used:" + for tool in $LIBTOOLS $REQTOOLS ; do + which "$tool" + done +} + +mount_pseudofs() { + # This function ensures that the psuedofs mountpoints are present + # in the chroot. Strictly they are not necessary to have for many + # commands, but bind-mounts are cheap and it isn't too bad to just + # mount them all the time. + for f in dev proc sys; do + # In a naked chroot there is nothing to bind the mounts to, so + # we need to create directories for these first. + [ ! -d "$ROOTFS/$f" ] && mkdir -p "$ROOTFS/$f" + if ! mountpoint -q "$ROOTFS/$f" ; then + # It is VERY important that this only happen if the + # pseudofs isn't already mounted. If it already is then + # this is virtually impossible to troubleshoot because it + # looks like the subsequent umount just isn't working. + mount -r --rbind /$f "$ROOTFS/$f" --make-rslave + fi + done + if ! mountpoint -q "$ROOTFS/tmp" ; then + mkdir -p "$ROOTFS/tmp" + mount -o mode=0755,nosuid,nodev -t tmpfs tmpfs "$ROOTFS/tmp" + fi +} + +umount_pseudofs() { + # This function cleans up the mounts in the chroot. Failure to + # clean up these mounts will prevent the tmpdir from being + # deletable instead throwing the error "Device or Resource Busy". + # The '-f' option is passed to umount to account for the + # contingency where the psuedofs mounts are not present. + if [ -d "${ROOTFS}" ]; then + for f in dev proc sys; do + umount -R -f "$ROOTFS/$f" >/dev/null 2>&1 + done + fi + umount -f "$ROOTFS/tmp" >/dev/null 2>&1 +} + +run_cmd_target() { + info_msg "Running $* for target $XBPS_TARGET_ARCH ..." + if is_target_native "$XBPS_TARGET_ARCH"; then + # This is being run on the same architecture as the host, + # therefore we should set XBPS_ARCH. + if ! eval XBPS_ARCH="$XBPS_TARGET_ARCH" "$@" ; then + die "Could not run command $*" + fi + else + # This is being run on a foriegn arch, therefore we should set + # XBPS_TARGET_ARCH. In this case XBPS will not attempt + # certain actions and will require reconfiguration later. + if ! eval XBPS_TARGET_ARCH="$XBPS_TARGET_ARCH" "$@" ; then + die "Could not run command $*" + fi + fi +} + +run_cmd() { + # This is a general purpose function to run commands that a user + # may wish to see. For example its useful to see the tar/xz + # pipeline to not need to delve into the scripts to see what + # options its set up with. + info_msg "Running $*" + eval "$@" +} + +run_cmd_chroot() { + # General purpose chroot function which makes sure the chroot is + # prepared. This function takes 2 arguments, the location to + # chroot to and the command to run. + + # This is an idempotent function, it is safe to call every time + # before entering the chroot. This has the advantage of making + # execution in the chroot appear as though it "Just Works(tm)". + register_binfmt + + # Before we step into the chroot we need to make sure the + # pseudo-filesystems are ready to go. Not all commands will need + # this, but its still a good idea to call it here anyway. + mount_pseudofs + + # With assurance that things will run now we can jump into the + # chroot and run stuff! + chroot "$1" sh -c "$2" +} + +cleanup_chroot() { + # This function cleans up the chroot shims that are used by QEMU + # to allow builds on alien platforms. It takes no arguments but + # expects the global $ROOTFS variable to be set. + + # Un-Mount the pseudofs mounts if they were mounted + umount_pseudofs +} + +register_binfmt() { + # This function sets up everything that is needed to be able to + # chroot into a ROOTFS and be able to run commands there. This + # really matters on platforms where the host architecture is + # different from the target, and you wouldn't be able to run + # things like xbps-reconfigure -a. This function is idempotent + # (You can run it multiple times without modifying state). This + # function takes no arguments, but does expect the global variable + # $XBPS_TARGET_ARCH to be set. + + # This select sets up the "magic" bytes in /proc that let the + # kernel select an alternate interpreter. More values for this + # map can be obtained from here: + # https://github.com/qemu/qemu/blob/master/scripts/qemu-binfmt-conf.sh + + # If the XBPS_TARGET_ARCH is unset but the PLATFORM is known, it + # may be possible to set the architecture from the static + # platforms map. + if [ -z "$XBPS_TARGET_ARCH" ] && [ ! -z "$PLATFORM" ] ; then + set_target_arch_from_platform + fi + + # In the special case where the build is native we can return + # without doing anything else + # This is only a basic check for identical archs, with more careful + # checks below for cases like ppc64 -> ppc and x86_64 -> i686. + _hostarch="${HOSTARCH%-musl}" + _targetarch="${XBPS_TARGET_ARCH%-musl}" + if [ "$_hostarch" = "$_targetarch" ] ; then + return + fi + + case "${_targetarch}" in + armv*) + # TODO: detect aarch64 hosts that run 32 bit ARM without qemu (some cannot) + if ( [ "${_targetarch}" = "armv6l" ] && [ "${_hostarch}" = "armv7l" ] ) ; then + return + fi + if [ "${_targetarch}" = "armv5tel" -a \ + \( "${_hostarch}" = "armv6l" -o "${_hostarch}" = "armv7l" \) ] ; then + return + fi + _cpu=arm + ;; + aarch64) + _cpu=aarch64 + ;; + ppc64le) + _cpu=ppc64le + ;; + ppc64) + _cpu=ppc64 + ;; + ppc) + if [ "$_hostarch" = "ppc64" ] ; then + return + fi + _cpu=ppc + ;; + mipsel) + if [ "$_hostarch" = "mips64el" ] ; then + return + fi + _cpu=mipsel + ;; + x86_64) + _cpu=x86_64 + ;; + i686) + if [ "$_hostarch" = "x86_64" ] ; then + return + fi + _cpu=i386 + ;; + riscv64) + _cpu=riscv64 + ;; + *) + die "Unknown target architecture!" + ;; + esac + + # For builds that do not match the host architecture, the correct + # qemu binary will be required. + QEMU_BIN="qemu-${_cpu}" + if ! $QEMU_BIN -version >/dev/null 2>&1; then + die "$QEMU_BIN binary is missing in your system, exiting." + fi + + # In order to use the binfmt system the binfmt_misc mountpoint + # must exist inside of proc + if ! mountpoint -q /proc/sys/fs/binfmt_misc ; then + modprobe -q binfmt_misc + mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc 2>/dev/null + fi + + # Only register if the map is incomplete + if [ ! -f /proc/sys/fs/binfmt_misc/qemu-$_cpu ] ; then + if ! command -v update-binfmts >/dev/null 2>&1; then + die "could not add binfmt: update-binfmts binary is missing in your system" + fi + update-binfmts --import "qemu-$_cpu" + fi +} + +set_target_arch_from_platform() { + # This function maintains a lookup from platform to target + # architecture. This is required for scripts that need to know + # the target architecture, but don't necessarily need to know it + # internally (i.e. only run_cmd_chroot). + case "$PLATFORM" in + rpi-aarch64*) XBPS_TARGET_ARCH="aarch64";; + rpi-armv7l*) XBPS_TARGET_ARCH="armv7l";; + rpi-armv6l*) XBPS_TARGET_ARCH="armv6l";; + i686*) XBPS_TARGET_ARCH="i686";; + x86_64*) XBPS_TARGET_ARCH="x86_64";; + GCP*) XBPS_TARGET_ARCH="x86_64";; + pinebookpro*) XBPS_TARGET_ARCH="aarch64";; + pinephone*) XBPS_TARGET_ARCH="aarch64";; + rock64*) XBPS_TARGET_ARCH="aarch64";; + rockpro64*) XBPS_TARGET_ARCH="aarch64";; + asahi*) XBPS_TARGET_ARCH="aarch64";; + *) die "$PROGNAME: Unable to compute target architecture from platform";; + esac + + if [ -z "${PLATFORM##*-musl}" ] ; then + XBPS_TARGET_ARCH="${XBPS_TARGET_ARCH}-musl" + fi +} + +set_dracut_args_from_platform() { + # In rare cases it is necessary to set platform specific dracut + # args. This is mostly the case on ARM platforms. + case "$PLATFORM" in + *) ;; + esac +} + +set_cachedir() { + # The package artifacts are cacheable, but they need to be isolated + # from the host cache. + : "${XBPS_CACHEDIR:=--cachedir=$PWD/xbps-cache/${XBPS_TARGET_ARCH}}" +} + +rk33xx_flash_uboot() { + local dir="$1" + local dev="$2" + dd if="${dir}/idbloader.img" of="${dev}" seek=64 conv=notrunc,fsync >/dev/null 2>&1 + dd if="${dir}/u-boot.itb" of="${dev}" seek=16384 conv=notrunc,fsync >/dev/null 2>&1 +} + +# These should all resolve even if they won't have the appropriate +# repodata files for the selected architecture. +: "${XBPS_REPOSITORY:=--repository=https://repo-default.voidlinux.org/current \ + --repository=https://repo-default.voidlinux.org/current/musl \ + --repository=https://repo-default.voidlinux.org/current/aarch64}" + +# This library is the authoritative source of the platform map, +# because of this we may need to get this information from the command +# line. This select allows us to get that information out. This +# fails silently if the toolname isn't known since this script is +# sourced. +case "${1:-}" in + platform2arch) + PLATFORM=$2 + set_target_arch_from_platform + echo "$XBPS_TARGET_ARCH" + ;; +esac + +umask 022 + +MOSVER="$(cat version)" +REQUIRED_PKGS=(base-files libgcc plymouth dash coreutils sed tar gawk squashfs-tools xorriso) +TARGET_PKGS=(base-files plymouth) +INITRAMFS_PKGS=(binutils xz device-mapper fbv dhclient dracut-network openresolv xsetroot) +PACKAGE_LIST=(bash openjdk21 xorg qt5 qt5-devel elogind plymouth) +IGNORE_PKGS=() +PLATFORMS=() +readonly PROGNAME="$(basename "$0")" +declare -a INCLUDE_DIRS=() + +# sudo ./mklive.sh -T minceraftOS -p openjdk21 live.autologin live.user=player live.shell=/bin/bash + +die() { + info_msg "ERROR: $*" + error_out 1 $LINENO +} + +print_step() { + CURRENT_STEP=$((CURRENT_STEP+1)) + info_msg "[${CURRENT_STEP}/${STEP_COUNT}] $*" +} + +mount_pseudofs() { + for f in sys dev proc; do + mkdir -p "$ROOTFS"/$f + mount --rbind /$f "$ROOTFS"/$f + done +} + +umount_pseudofs() { + for f in sys dev proc; do + if [ -d "$ROOTFS/$f" ] && ! umount -R -f "$ROOTFS/$f"; then + info_msg "ERROR: failed to unmount $ROOTFS/$f/" + return 1 + fi + done +} + +error_out() { + trap - INT TERM 0 + umount_pseudofs || exit "${1:-0}" + [ -d "$BUILDDIR" ] && [ -z "$KEEP_BUILDDIR" ] && rm -rf --one-file-system "$BUILDDIR" + exit "${1:-0}" +} + +copy_void_keys() { + mkdir -p "$1"/var/db/xbps/keys + cp keys/*.plist "$1"/var/db/xbps/keys +} + +copy_dracut_files() { + mkdir -p "$1"/usr/lib/dracut/modules.d/01vmklive + cp dracut/vmklive/* "$1"/usr/lib/dracut/modules.d/01vmklive/ +} + +copy_autoinstaller_files() { + mkdir -p "$1"/usr/lib/dracut/modules.d/01autoinstaller + cp dracut/autoinstaller/* "$1"/usr/lib/dracut/modules.d/01autoinstaller/ +} + +install_prereqs() { + XBPS_ARCH=$HOST_ARCH "$XBPS_INSTALL_CMD" -r "$VOIDHOSTDIR" ${XBPS_REPOSITORY} \ + -c "$XBPS_HOST_CACHEDIR" -y "${REQUIRED_PKGS[@]}" + [ $? -ne 0 ] && die "Failed to install required software, exiting..." +} + +install_target_pkgs() { + XBPS_ARCH=$TARGET_ARCH "$XBPS_INSTALL_CMD" -r "$VOIDTARGETDIR" ${XBPS_REPOSITORY} \ + -c "$XBPS_HOST_CACHEDIR" -y "${TARGET_PKGS[@]}" + [ $? -ne 0 ] && die "Failed to install required software, exiting..." +} + +post_install_packages() { + # Cleanup and remove useless stuff. + rm -rf "$ROOTFS"/var/cache/* "$ROOTFS"/run/* "$ROOTFS"/var/run/* + + # boot failure if disks have raid logical volumes and this isn't loaded + for f in "$ROOTFS/usr/lib/modules/$KERNELVERSION/kernel/drivers/md/dm-raid.ko".*; do + echo "dm-raid" > "$ROOTFS"/etc/modules-load.d/dm-raid.conf + break + done + + chroot "$ROOTFS" xbps-install -S plymouth + + mkdir -p /usr + mkdir -p /usr/share + mkdir -p /usr/share/plymouth + mkdir -p /usr/share/plymouth/themes + mkdir -p /usr/share/plymouth/themes/simple-image + cp data/simple-image.plymouth "$ROOTFS"/usr/share/plymouth/themes/simple-image + cp data/simple-image.script "$ROOTFS"/usr/share/plymouth/themes/simple-image + cp data/logo.png "$ROOTFS"/usr/share/plymouth/themes/simple-image + + mkdir -p /etc + mkdir -p /etc/plymouth + echo "[Daemon] +Theme=simple-image" > /etc/plymouth/plymouthd.conf + + chroot "$ROOTFS" env -i plymouth-set-default-theme -R "simple-image" +} + +install_packages() { + XBPS_ARCH=$TARGET_ARCH "${XBPS_INSTALL_CMD}" -r "$ROOTFS" \ + ${XBPS_REPOSITORY} -c "$XBPS_CACHEDIR" -yn "${PACKAGE_LIST[@]}" "${INITRAMFS_PKGS[@]}" + [ $? -ne 0 ] && die "Missing required binary packages, exiting..." + + mount_pseudofs + + LANG=C XBPS_TARGET_ARCH=$TARGET_ARCH "${XBPS_INSTALL_CMD}" -U -r "$ROOTFS" \ + ${XBPS_REPOSITORY} -c "$XBPS_CACHEDIR" -y "${PACKAGE_LIST[@]}" "${INITRAMFS_PKGS[@]}" + [ $? -ne 0 ] && die "Failed to install ${PACKAGE_LIST[*]} ${INITRAMFS_PKGS[*]}" + + xbps-reconfigure -r "$ROOTFS" -f base-files >/dev/null 2>&1 + chroot "$ROOTFS" env -i xbps-reconfigure -f base-files + + # Enable choosen UTF-8 locale and generate it into the target rootfs. + if [ -f "$ROOTFS"/etc/default/libc-locales ]; then + sed -e "s/\#\(${LOCALE}.*\)/\1/g" -i "$ROOTFS"/etc/default/libc-locales + fi + + if XBPS_ARCH=$BASE_ARCH "$XBPS_QUERY_CMD" -r "$ROOTFS" dkms >/dev/null 2>&1; then + # dkms modules alphabetically before dkms can't configure + # if dkms hasn't configured beforehand to create /var/lib/dkms + chroot "$ROOTFS" env -i xbps-reconfigure dkms + fi + + chroot "$ROOTFS" env -i xbps-reconfigure -a + + if XBPS_ARCH=$BASE_ARCH "$XBPS_QUERY_CMD" -r "$ROOTFS" dash >/dev/null 2>&1; then + # bash configures alphabetically before dash, + # so if it's installed we should ensure it's /bin/sh + chroot "$ROOTFS" env -i xbps-alternatives -s dash + fi + + post_install_packages +} + +ignore_packages() { + mkdir -p "$ROOTFS"/etc/xbps.d + for pkg in "${IGNORE_PKGS[@]}"; do + echo "ignorepkg=$pkg" >> "$ROOTFS"/etc/xbps.d/mklive-ignore.conf + done +} + +enable_services() { + SERVICE_LIST="$*" + for service in $SERVICE_LIST; do + if ! [ -e $ROOTFS/etc/sv/$service ]; then + die "service $service not in /etc/sv" + fi + ln -sf /etc/sv/$service $ROOTFS/etc/runit/runsvdir/default/ + done + ln -sf /etc/sv/plymouthd $ROOTFS/etc/runit/runsvdir/default/ + ln -sf /etc/sv/elogind $ROOTFS/etc/runit/runsvdir/default/ +} + +change_shell() { + chroot "$ROOTFS" chsh -s "$ROOT_SHELL" root + [ $? -ne 0 ] && die "Failed to change the shell for root" +} + +copy_include_directories() { + for includedir in "${INCLUDE_DIRS[@]}"; do + info_msg "=> copying include directory '$includedir' ..." + find "$includedir" -mindepth 1 -maxdepth 1 -exec cp -rfpPv {} "$ROOTFS"/ \; + done +} + +generate_initramfs() { + local _args + + copy_dracut_files "$ROOTFS" + copy_autoinstaller_files "$ROOTFS" + chroot "$ROOTFS" env -i /usr/bin/dracut -N --"${INITRAMFS_COMPRESSION}" \ + --add-drivers "ahci" --force-add "vmklive autoinstaller" --omit systemd "/boot/initrd" $KERNELVERSION + [ $? -ne 0 ] && die "Failed to generate the initramfs" + + mv "$ROOTFS"/boot/initrd "$BOOT_DIR" + case "$TARGET_ARCH" in + i686*|x86_64*) cp "$ROOTFS/boot/vmlinuz-$KERNELVERSION" "$BOOT_DIR"/vmlinuz ;; + aarch64*) cp "$ROOTFS/boot/vmlinux-$KERNELVERSION" "$BOOT_DIR"/vmlinux ;; + esac +} + +cleanup_rootfs() { + for f in "${INITRAMFS_PKGS[@]}"; do + revdeps=$(xbps-query -r "$ROOTFS" -X $f) + if [ -n "$revdeps" ]; then + xbps-pkgdb -r "$ROOTFS" -m auto $f + else + xbps-remove -r "$ROOTFS" -Ry ${f} >/dev/null 2>&1 + fi + done + rm -r "$ROOTFS"/usr/lib/dracut/modules.d/01vmklive + rm -r "$ROOTFS"/usr/lib/dracut/modules.d/01autoinstaller +} + +generate_isolinux_boot() { + cp -f "$SYSLINUX_DATADIR"/isolinux.bin "$ISOLINUX_DIR" + cp -f "$SYSLINUX_DATADIR"/ldlinux.c32 "$ISOLINUX_DIR" + cp -f "$SYSLINUX_DATADIR"/libcom32.c32 "$ISOLINUX_DIR" + cp -f "$SYSLINUX_DATADIR"/vesamenu.c32 "$ISOLINUX_DIR" + cp -f "$SYSLINUX_DATADIR"/libutil.c32 "$ISOLINUX_DIR" + cp -f "$SYSLINUX_DATADIR"/chain.c32 "$ISOLINUX_DIR" + cp -f "$SYSLINUX_DATADIR"/reboot.c32 "$ISOLINUX_DIR" + cp -f "$SYSLINUX_DATADIR"/poweroff.c32 "$ISOLINUX_DIR" + cp -f isolinux/isolinux.cfg.in "$ISOLINUX_DIR"/isolinux.cfg + cp -f ${SPLASH_IMAGE} "$ISOLINUX_DIR" + + sed -i -e "s|@@SPLASHIMAGE@@|$(basename "${SPLASH_IMAGE}")|" \ + -e "s|@@KERNVER@@|${KERNELVERSION}|" \ + -e "s|@@KEYMAP@@|${KEYMAP}|" \ + -e "s|@@ARCH@@|$TARGET_ARCH|" \ + -e "s|@@LOCALE@@|${LOCALE}|" \ + -e "s|@@BOOT_TITLE@@|${BOOT_TITLE}|" \ + -e "s|@@BOOT_CMDLINE@@|${BOOT_CMDLINE}|" \ + "$ISOLINUX_DIR"/isolinux.cfg + + # include memtest86+ + if [ -e "$VOIDTARGETDIR"/boot/memtest86+/memtest.bin ]; then + cp "$VOIDTARGETDIR"/boot/memtest86+/memtest.bin "$BOOT_DIR" + fi +} + +generate_grub_efi_boot() { + cp -f grub/grub.cfg "$GRUB_DIR" + cp -f "${SPLASH_IMAGE}" "$ISOLINUX_DIR" + cp -f grub/grub_void.cfg.pre "$GRUB_DIR"/grub_void.cfg + + case "$TARGET_ARCH" in + i686*|x86_64*) KERNEL_IMG=vmlinuz; WANT_MEMTEST=yes ;; + aarch64*) KERNEL_IMG=vmlinux; WANT_MEMTEST=no ;; + esac + + write_entry() { + local entrytitle="$1" id="$2" cmdline="$3" dtb="$4" hotkey="$5" + cat << EOF >> "$GRUB_DIR"/grub_void.cfg +menuentry "${entrytitle}" --id "${id}" ${hotkey:+--hotkey $hotkey} { + set gfxpayload="keep" + linux (\${voidlive})/boot/${KERNEL_IMG} \\ + root=live:CDLABEL=VOID_LIVE ro init=/sbin/init \\ + rd.luks=0 rd.md=0 rd.dm=0 loglevel=4 gpt add_efi_memmap \\ + vconsole.unicode=1 vconsole.keymap=${KEYMAP} locale.LANG=${LOCALE} ${cmdline} + initrd (\${voidlive})/boot/initrd +EOF + if [ -n "${dtb}" ]; then + printf ' devicetree (${voidlive})/boot/dtbs/%s\n' "${dtb}" >> "$GRUB_DIR"/grub_void.cfg + fi + printf '}\n' >> "$GRUB_DIR"/grub_void.cfg + } + + write_entries() { + local title_sfx="$1" id_sfx="$2" cmdline="$3" dtb="$4" + + ENTRY_TITLE="${BOOT_TITLE}" + + write_entry "${ENTRY_TITLE}" "linux${id_sfx}" \ + "$BOOT_CMDLINE $cmdline live.autologin live.user=player live.shell=/bin/bash quiet splash" "$dtb" + } + + write_entries + + # for platform in "${PLATFORMS[@]}"; do + # ( + # . "platforms/${platform}.sh" + + # if [ -n "$PLATFORM_DTB" ]; then + # mkdir -p "${BOOT_DIR}/dtbs/${PLATFORM_DTB%/*}" + # cp "${ROOTFS}/boot/dtbs/dtbs-${KERNVER}"*/"${PLATFORM_DTB}" "${BOOT_DIR}/dtbs/${PLATFORM_DTB}" + # fi + + # printf 'submenu "%s" --id platform-%s {\n' \ + # "${BOOT_TITLE} for ${PLATFORM_NAME:-$platform} >" "${platform}" >> "$GRUB_DIR"/grub_void.cfg + # write_entries "for ${PLATFORM_NAME:-$platform} " "-$platform" "$PLATFORM_CMDLINE" "${PLATFORM_DTB}" + # printf '}\n' >> "$GRUB_DIR"/grub_void.cfg + # ) + # done + + cat grub/grub_void.cfg.post >> "$GRUB_DIR"/grub_void.cfg + + cat grub/grub_void.cfg + + sed -i -e "s|@@SPLASHIMAGE@@|$(basename "${SPLASH_IMAGE}")|" "$GRUB_DIR"/grub_void.cfg + + mkdir -p "$GRUB_DIR"/fonts + + cp -f "$GRUB_DATADIR"/unicode.pf2 "$GRUB_DIR"/fonts + + modprobe -q loop || : + + # Create EFI vfat image. + truncate -s 32M "$GRUB_DIR"/efiboot.img >/dev/null 2>&1 + mkfs.vfat -F12 -S 512 -n "grub_uefi" "$GRUB_DIR/efiboot.img" >/dev/null 2>&1 + + GRUB_EFI_TMPDIR="$(mktemp --tmpdir="$BUILDDIR" -dt grub-efi.XXXXX)" + LOOP_DEVICE="$(losetup --show --find "${GRUB_DIR}"/efiboot.img)" + mount -o rw,flush -t vfat "${LOOP_DEVICE}" "${GRUB_EFI_TMPDIR}" >/dev/null 2>&1 + + build_grub_image() { + local GRUB_ARCH="$1" EFI_ARCH="$2" + xbps-uchroot "$VOIDTARGETDIR" grub-mkstandalone -- \ + --directory="/usr/lib/grub/${GRUB_ARCH}-efi" \ + --format="${GRUB_ARCH}-efi" \ + --output="/tmp/boot${EFI_ARCH,,}.efi" \ + "boot/grub/grub.cfg" + if [ $? -ne 0 ]; then + umount "$GRUB_EFI_TMPDIR" + losetup --detach "${LOOP_DEVICE}" + die "Failed to generate EFI loader" + fi + mkdir -p "${GRUB_EFI_TMPDIR}"/EFI/BOOT + cp -f "$VOIDTARGETDIR/tmp/boot${EFI_ARCH,,}.efi" "${GRUB_EFI_TMPDIR}/EFI/BOOT/BOOT${EFI_ARCH^^}.EFI" + } + + cp -a "$IMAGEDIR"/boot "$VOIDTARGETDIR" + + case "$TARGET_ARCH" in + i686*|x86_64*) + # XXX: why are both built on both arches? + build_grub_image i386 ia32 + build_grub_image x86_64 x64 + # include memtest86+ + if [ -e "$VOIDTARGETDIR"/boot/memtest86+/memtest.efi ]; then + cp "$VOIDTARGETDIR"/boot/memtest86+/memtest.efi "$BOOT_DIR" + fi + ;; + aarch64*) + build_grub_image arm64 aa64 + ;; + esac + umount "$GRUB_EFI_TMPDIR" + losetup --detach "${LOOP_DEVICE}" + rm -rf "$GRUB_EFI_TMPDIR" +} + +generate_squashfs() { + umount_pseudofs || exit 1 + # Find out required size for the rootfs and create an ext3fs image off it. + ROOTFS_SIZE=$(du --apparent-size -sm "$ROOTFS"|awk '{print $1}') + mkdir -p "$BUILDDIR/tmp/LiveOS" + truncate -s "$((ROOTFS_SIZE+ROOTFS_SIZE))M" \ + "$BUILDDIR"/tmp/LiveOS/ext3fs.img >/dev/null 2>&1 + mkdir -p "$BUILDDIR/tmp-rootfs" + mkfs.ext3 -F -m1 "$BUILDDIR/tmp/LiveOS/ext3fs.img" >/dev/null 2>&1 + mount -o loop "$BUILDDIR/tmp/LiveOS/ext3fs.img" "$BUILDDIR/tmp-rootfs" + cp -a "$ROOTFS"/* "$BUILDDIR"/tmp-rootfs/ + umount -f "$BUILDDIR/tmp-rootfs" + mkdir -p "$IMAGEDIR/LiveOS" + "$VOIDHOSTDIR"/usr/bin/mksquashfs "$BUILDDIR/tmp" "$IMAGEDIR/LiveOS/squashfs.img" \ + -comp "${SQUASHFS_COMPRESSION}" || die "Failed to generate squashfs image" + chmod 444 "$IMAGEDIR/LiveOS/squashfs.img" + # Remove rootfs and temporary dirs, we don't need them anymore. + rm -rf "$ROOTFS" "$BUILDDIR/tmp-rootfs" "$BUILDDIR/tmp" +} + +generate_iso_image() { + local bootloader n + XORRISO_ARGS=( + -iso-level 3 -rock -joliet -joliet-long -max-iso9660-filenames -omit-period + -omit-version-number -relaxed-filenames -allow-lowercase + -volid VOID_LIVE + ) + + if [ "$IMAGE_TYPE" = hybrid ]; then + XORRISO_ARGS+=(-isohybrid-mbr "$SYSLINUX_DATADIR"/isohdpfx.bin) + fi + + n=1 + for bootloader in "${BOOTLOADERS[@]}"; do + if (( n > 1 )); then + XORRISO_ARGS+=(-eltorito-alt-boot) + fi + + case "${bootloader}" in + grub) + XORRISO_ARGS+=( + -e boot/grub/efiboot.img -no-emul-boot + -isohybrid-gpt-basdat -isohybrid-apm-hfsplus + ) + ;; + syslinux) + XORRISO_ARGS+=( + -eltorito-boot boot/isolinux/isolinux.bin + -eltorito-catalog boot/isolinux/boot.cat + -no-emul-boot -boot-load-size 4 -boot-info-table + ) + ;; + esac + + n=$(( n + 1 )) + done + + XORRISO_ARGS+=( + -output "$OUTPUT_FILE" "$IMAGEDIR" + ) + + "$VOIDHOSTDIR"/usr/bin/xorriso -as mkisofs "${XORRISO_ARGS[@]}" || die "Failed to generate ISO image" +} + +# +# main() +# +# while getopts "a:b:r:c:C:T:Kk:l:i:I:S:e:s:o:p:g:v:P:Vh" opt; do +# case $opt in +# a) TARGET_ARCH="$OPTARG";; +# b) BASE_SYSTEM_PKG="$OPTARG";; +# r) XBPS_REPOSITORY="--repository=$OPTARG $XBPS_REPOSITORY";; +# c) XBPS_CACHEDIR="$OPTARG";; +# g) IGNORE_PKGS+=($OPTARG) ;; +# K) readonly KEEP_BUILDDIR=1;; +# k) KEYMAP="$OPTARG";; +# l) LOCALE="$OPTARG";; +# i) INITRAMFS_COMPRESSION="$OPTARG";; +# I) INCLUDE_DIRS+=("$OPTARG");; +# S) SERVICE_LIST="$SERVICE_LIST $OPTARG";; +# e) ROOT_SHELL="$OPTARG";; +# s) SQUASHFS_COMPRESSION="$OPTARG";; +# o) OUTPUT_FILE="$OPTARG";; +# p) PACKAGE_LIST+=($OPTARG);; +# P) PLATFORMS+=($OPTARG) ;; +# C) BOOT_CMDLINE="$OPTARG";; +# T) BOOT_TITLE="$OPTARG";; +# v) LINUX_VERSION="$OPTARG";; +# esac +# done +shift $((OPTIND - 1)) +XBPS_REPOSITORY="$XBPS_REPOSITORY --repository=https://repo-default.voidlinux.org/current --repository=https://repo-default.voidlinux.org/current/musl --repository=https://repo-default.voidlinux.org/current/aarch64" + +# Configure dracut to use overlayfs for the writable overlay. +BOOT_CMDLINE="$BOOT_CMDLINE rd.live.overlay.overlayfs=1 " + +HOST_ARCH=$(xbps-uhelper arch) + +# Set defaults +: ${TARGET_ARCH:=$(xbps-uhelper arch 2>/dev/null || uname -m)} +: ${XBPS_CACHEDIR:="$(pwd -P)"/xbps-cachedir-${TARGET_ARCH}} +: ${XBPS_HOST_CACHEDIR:="$(pwd -P)"/xbps-cachedir-${HOST_ARCH}} +: ${KEYMAP:=us} +: ${LOCALE:=en_US.UTF-8} +: ${INITRAMFS_COMPRESSION:=xz} +: ${SQUASHFS_COMPRESSION:=xz} +: ${BASE_SYSTEM_PKG:=base-system} +: ${BOOT_TITLE:="MinceraftOS"} +: ${LINUX_VERSION:=linux} + +XBPS_TARGET_ARCH="$TARGET_ARCH" register_binfmt + +case "$TARGET_ARCH" in + x86_64*|i686*) + BOOTLOADERS=(syslinux grub) + IMAGE_TYPE='hybrid' + TARGET_PKGS+=(syslinux grub-i386-efi grub-x86_64-efi memtest86+) + PLATFORMS=() # arm only + ;; + aarch64*) + BOOTLOADERS=(grub) + IMAGE_TYPE='efi' + TARGET_PKGS+=(grub-arm64-efi) + for platform in "${PLATFORMS[@]}"; do + if [ -r "platforms/${platform}.sh" ]; then + . "platforms/${platform}.sh" + else + die "unknown platform: ${platform}" + fi + PACKAGE_LIST+=("${PLATFORM_PKGS[@]}") + unset PLATFORM_PKGS PLATFORM_CMDLINE PLATFORM_DTB + done + + ;; + *) >&2 echo "architecture $TARGET_ARCH not supported by mklive.sh"; exit 1;; +esac + +# Required packages in the image for a working system. +PACKAGE_LIST+=("$BASE_SYSTEM_PKG") + +# Check for root permissions. +if [ "$(id -u)" -ne 0 ]; then + die "Must be run as root, exiting..." +fi + +trap 'error_out $? $LINENO' INT TERM 0 + +BUILDDIR="./build" +rm -rf $BUILDDIR +IMAGEDIR="$BUILDDIR/image" +ROOTFS="$IMAGEDIR/rootfs" +VOIDHOSTDIR="$BUILDDIR/void-host" +VOIDTARGETDIR="$BUILDDIR/void-target" +BOOT_DIR="$IMAGEDIR/boot" +ISOLINUX_DIR="$BOOT_DIR/isolinux" +GRUB_DIR="$BOOT_DIR/grub" +ROOT_SHELL="/bin/bash" +CURRENT_STEP=0 +STEP_COUNT=10 +[ "${IMAGE_TYPE}" = hybrid ] && STEP_COUNT=$((STEP_COUNT+1)) +[ "${#INCLUDE_DIRS[@]}" -gt 0 ] && STEP_COUNT=$((STEP_COUNT+1)) +[ "${#IGNORE_PKGS[@]}" -gt 0 ] && STEP_COUNT=$((STEP_COUNT+1)) +[ -n "$ROOT_SHELL" ] && STEP_COUNT=$((STEP_COUNT+1)) + +: ${SYSLINUX_DATADIR:="$VOIDTARGETDIR"/usr/lib/syslinux} +: ${GRUB_DATADIR:="$VOIDTARGETDIR"/usr/share/grub} +: ${SPLASH_IMAGE:=data/splash.png} +: ${XBPS_INSTALL_CMD:=xbps-install} +: ${XBPS_REMOVE_CMD:=xbps-remove} +: ${XBPS_QUERY_CMD:=xbps-query} +: ${XBPS_RINDEX_CMD:=xbps-rindex} +: ${XBPS_UHELPER_CMD:=xbps-uhelper} +: ${XBPS_RECONFIGURE_CMD:=xbps-reconfigure} + +mkdir -p "$ROOTFS" "$VOIDHOSTDIR" "$VOIDTARGETDIR" "$GRUB_DIR" "$ISOLINUX_DIR" + +print_step "Synchronizing XBPS repository data..." +copy_void_keys "$ROOTFS" +XBPS_ARCH=$TARGET_ARCH $XBPS_INSTALL_CMD -r "$ROOTFS" ${XBPS_REPOSITORY} -Sy +copy_void_keys "$VOIDHOSTDIR" +XBPS_ARCH=$HOST_ARCH $XBPS_INSTALL_CMD -r "$VOIDHOSTDIR" ${XBPS_REPOSITORY} -Sy +copy_void_keys "$VOIDTARGETDIR" +XBPS_ARCH=$TARGET_ARCH $XBPS_INSTALL_CMD -r "$VOIDTARGETDIR" ${XBPS_REPOSITORY} -Sy + +# Get linux version for ISO +# If linux version option specified use +shopt -s extglob +case "$LINUX_VERSION" in + linux+([0-9.])) + IGNORE_PKGS+=(linux) + PACKAGE_LIST+=("$LINUX_VERSION" linux-base) + ;; + linux-@(mainline|lts)) + IGNORE_PKGS+=(linux) + PACKAGE_LIST+=("$LINUX_VERSION") + LINUX_VERSION="$(XBPS_ARCH=$TARGET_ARCH $XBPS_QUERY_CMD -r "$ROOTFS" ${XBPS_REPOSITORY:=-R} -x "$LINUX_VERSION" | grep 'linux[0-9._]\+')" + ;; + linux-asahi) + IGNORE_PKGS+=(linux) + PACKAGE_LIST+=(linux-asahi linux-base) + ;; + linux) + PACKAGE_LIST+=(linux) + LINUX_VERSION="$(XBPS_ARCH=$TARGET_ARCH $XBPS_QUERY_CMD -r "$ROOTFS" ${XBPS_REPOSITORY:=-R} -x linux | grep 'linux[0-9._]\+')" + ;; + *) + die "-v option must be in format linux or linux-" + ;; +esac +shopt -u extglob + +_kver="$(XBPS_ARCH=$TARGET_ARCH $XBPS_QUERY_CMD -r "$ROOTFS" ${XBPS_REPOSITORY:=-R} -p pkgver $LINUX_VERSION)" +KERNELVERSION=$($XBPS_UHELPER_CMD getpkgversion ${_kver}) + +if [ "$LINUX_VERSION" = linux-asahi ]; then + KERNELVERSION="${KERNELVERSION%%_*}-asahi_${KERNELVERSION##*_}" +fi + +if [ "$?" -ne "0" ]; then + die "Failed to find kernel package version" +fi + +mkdir -p output + +: ${OUTPUT_FILE="output/minceraftOS-$MOSVER-$(date '+%Y-%m-%d_%H:%M:%S').iso"} + +print_step "Installing software to generate the image: ${REQUIRED_PKGS[*]} ..." +install_prereqs "${REQUIRED_PKGS[@]}" + +print_step "Installing software to generate the image: ${TARGET_PKGS[*]} ..." +install_target_pkgs "${TARGET_PKGS[@]}" + +mkdir -p "$ROOTFS"/etc +[ -s data/motd ] && cp data/motd "$ROOTFS"/etc +[ -s data/issue ] && cp data/issue "$ROOTFS"/etc +# cp -r data/minceraft "$ROOTFS"/etc + +if [ "${#IGNORE_PKGS[@]}" -gt 0 ]; then + print_step "Ignoring packages in the rootfs: ${IGNORE_PKGS[*]} ..." + ignore_packages +fi + +print_step "Installing void pkgs into the rootfs: ${PACKAGE_LIST[*]} ..." +install_packages + +: ${DEFAULT_SERVICE_LIST:=agetty-tty1 agetty-tty2 agetty-tty3 agetty-tty4 agetty-tty5 agetty-tty6 udevd} +print_step "Enabling services: ${SERVICE_LIST} ..." +enable_services ${DEFAULT_SERVICE_LIST} ${SERVICE_LIST} + +if [ -n "$ROOT_SHELL" ]; then + print_step "Changing the root shell ..." + change_shell +fi + +if [ "${#INCLUDE_DIRS[@]}" -gt 0 ];then + print_step "Copying directory structures into the rootfs ..." + copy_include_directories +fi + +print_step "Generating initramfs image ($INITRAMFS_COMPRESSION)..." +generate_initramfs + +if [ "$IMAGE_TYPE" = hybrid ]; then + print_step "Generating isolinux support for PC-BIOS systems..." + generate_isolinux_boot +fi + +print_step "Generating GRUB support for EFI systems..." +generate_grub_efi_boot + +mkdir -p "$ROOTFS"/home +mkdir -p "$ROOTFS"/home/player +cp data/xinitrc "$ROOTFS"/home/player/.xinitrc +cp data/bash_profile "$ROOTFS"/home/player/.bash_profile +cp -r data/mine "$ROOTFS"/home/player/mine +touch "$ROOTFS"/home/player/.Xauthority +cp data/bash_profile "$ROOTFS"/home/player/.profile +cp data/bash_profile "$ROOTFS"/etc/profile +chmod 777 "$ROOTFS"/home/player -R + +mkdir -p "$ROOTFS"/usr +mkdir -p "$ROOTFS"/usr/share +mkdir -p "$ROOTFS"/usr/share/icons/ +mkdir -p "$ROOTFS"/usr/share/icons/default +cp -r data/cursors "$ROOTFS"/usr/share/icons/default/cursors +cp data/index.theme "$ROOTFS"/usr/share/icons/default/index.theme +chmod -R 755 "$ROOTFS"/usr/share/icons/default/cursors + +cat "$ROOTFS"/etc +cat "$ROOTFS"/etc/X11 + +print_step "Cleaning up rootfs..." +cleanup_rootfs + +print_step "Generating squashfs image ($SQUASHFS_COMPRESSION) from rootfs..." +generate_squashfs + +print_step "Generating ISO image..." +generate_iso_image + +hsize=$(du -sh "$OUTPUT_FILE"|awk '{print $1}') +info_msg "Created $(readlink -f "$OUTPUT_FILE") ($hsize) successfully." diff --git a/mkmine b/mkmine new file mode 100755 index 0000000..b293bf0 --- /dev/null +++ b/mkmine @@ -0,0 +1,83 @@ +#!/bin/bash + +start_path="$(pwd)" + +function wrap_pwd { + local was_path="$(pwd)" + cd $start_path + $@ + cd $was_path +} + +function build_ultimmc { + echo "Build UltimMC" + if [ -f ultimmc/build/UltimMC ]; then + return + fi + mkdir -p ultimmc/build + cd ultimmc/build + export JAVA_HOME=/usr/lib/jvm/openjdk8 + cmake \ + -DCMAKE_C_COMPILER=/usr/bin/gcc \ + -DCMAKE_CXX_COMPILER=/usr/bin/g++ \ + -DCMAKE_BUILD_TYPE=Release \ + -DLauncher_NOTIFICATION_URL:STRING=https://files.multimc.org/notifications.json \ + -DCMAKE_INSTALL_PREFIX:PATH=../ \ + -DLauncher_UPDATER_BASE=https://files.multimc.org/update/ \ + -DLauncher_PASTE_EE_API_KEY:STRING=utLvciUouSURFzfjPxLBf5W4ISsUX4pwBDF7N1AfZ \ + -DLauncher_ANALYTICS_ID:STRING=UA-87731965-2 \ + -DLauncher_LAYOUT=lin-nodeps \ + -DLauncher_BUILD_PLATFORM=lin64 \ + -DLauncher_BUG_TRACKER_URL=https://github.com/UltimMC/Launcher/issues \ + -DLauncher_EMBED_SECRETS=On \ + .. + make +} + +function start_launcher { + echo "Launcher is starting..." + cd data/mine + ./UltimMC -l default +} + +function build_mods { + echo "Mods are building..." + cd mods + ./build-all.sh +} + +function copy_mine_data { + echo "Minceraft data is copying..." + cp mine-data/ultimmc.cfg data/mine + cp mine-data/run_mine.sh data/mine + cp mine-data/accounts.json data/mine + cp -r mine-data/translations data/mine + cp -r mine-data/themes data/mine + cp -r mine-data/libraries data/mine + cp -r mine-data/injectors data/mine + cp -r mine-data/icons data/mine + mkdir -p data/mine/instances + mkdir -p data/mine/instances/default + cp mine-data/mmc-pack.json data/mine/instances/default + cp mine-data/instance.cfg data/mine/instances/default + mkdir -p data/mine/instances/default/.minecraft + cp mine-data/options.txt data/mine/instances/default/.minecraft +} + +function create_mine_dir { + echo "Create minceraft launcher directory..." + mkdir data/mine || return + wrap_pwd copy_mine_data + wrap_pwd build_mods + rm -rf data/mine/instances/default/.minecraft/mods + cp -r mods/build data/mine/instances/default/.minecraft/mods + wrap_pwd build_ultimmc + cp -a ultimmc/build/. data/mine + chmod 777 data/mine -R + wrap_pwd start_launcher + wrap_pwd copy_mine_data +} + +rm -rf data/mine +create_mine_dir +echo "Minceraft is ready to play!"