limine 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. #!/bin/bash
  2. # NAME: Script to transition from systemd-boot to Limine bootloader
  3. # REQUIRES: sudo
  4. set -euo pipefail
  5. echo "do you confirm this transition?"
  6. read -r -p "Are you sure? [y/N] " response
  7. if [[ "$response" != "y" ]]; then
  8. exit 0
  9. fi
  10. RED='\033[0;31m'
  11. GREEN='\033[0;32m'
  12. YELLOW='\033[1;33m'
  13. BLUE='\033[0;34m'
  14. NC='\033[0m'
  15. print_status() { echo -e "${BLUE}[INFO]${NC} $1"; }
  16. print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
  17. print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
  18. print_error() { echo -e "${RED}[ERROR]${NC} $1"; }
  19. if [[ $EUID -ne 0 ]]; then
  20. print_error "This script must be run as root (use sudo)"
  21. exit 1
  22. fi
  23. if ! command -v pacman &>/dev/null; then
  24. print_error "This script is designed for Arch Linux / CachyOS systems"
  25. exit 1
  26. fi
  27. print_status "Starting transition from systemd-boot to Limine..."
  28. ESP_PATH=""
  29. if command -v bootctl &>/dev/null; then
  30. ESP_PATH=$(bootctl --print-esp-path 2>/dev/null || echo "")
  31. fi
  32. if [[ -z "$ESP_PATH" ]]; then
  33. if [[ -d "/boot/EFI" ]]; then
  34. ESP_PATH="/boot"
  35. elif [[ -d "/efi/EFI" ]]; then
  36. ESP_PATH="/efi"
  37. else
  38. print_error "Could not detect ESP path"
  39. exit 1
  40. fi
  41. fi
  42. print_success "ESP detected at: $ESP_PATH"
  43. BACKUP_DIR="/root/bootloader-backup-$(date +%Y%m%d-%H%M%S)"
  44. mkdir -p "$BACKUP_DIR"
  45. [[ -d "$ESP_PATH/loader" ]] && cp -r "$ESP_PATH/loader" "$BACKUP_DIR/" 2>/dev/null || true
  46. [[ -d "$ESP_PATH/EFI/systemd" ]] && cp -r "$ESP_PATH/EFI/systemd" "$BACKUP_DIR/" 2>/dev/null || true
  47. efibootmgr -v >"$BACKUP_DIR/efibootmgr-backup.txt" 2>/dev/null || true
  48. print_success "Backup created at: $BACKUP_DIR"
  49. CURRENT_CMDLINE=""
  50. if [[ -f "/etc/kernel/cmdline" ]]; then
  51. CURRENT_CMDLINE=$(cat /etc/kernel/cmdline)
  52. print_status "Found existing /etc/kernel/cmdline: $CURRENT_CMDLINE"
  53. else
  54. CURRENT_CMDLINE=$(cat /proc/cmdline | sed 's/BOOT_IMAGE=[^ ]* //')
  55. print_status "Using current /proc/cmdline: $CURRENT_CMDLINE"
  56. fi
  57. print_status "Installing Limine and related packages..."
  58. pacman -S --needed --noconfirm limine limine-snapper-sync limine-mkinitcpio-hook
  59. print_success "Limine packages installed"
  60. print_status "Installing Limine bootloader to ESP..."
  61. mkdir -p "$ESP_PATH/EFI/Limine"
  62. if [[ -f "/usr/share/limine/limine_x64.efi" ]]; then
  63. cp /usr/share/limine/limine_x64.efi "$ESP_PATH/EFI/Limine/"
  64. elif [[ -f "/usr/share/limine/BOOTX64.EFI" ]]; then
  65. cp /usr/share/limine/BOOTX64.EFI "$ESP_PATH/EFI/Limine/limine_x64.efi"
  66. else
  67. print_error "Could not find Limine EFI files"
  68. exit 1
  69. fi
  70. print_success "Limine files installed to ESP"
  71. print_status "Creating UEFI boot entry for Limine..."
  72. ESP_DEVICE=$(df "$ESP_PATH" | tail -1 | awk '{print $1}')
  73. ESP_DISK=$(echo "$ESP_DEVICE" | sed 's/[0-9]*$//')
  74. ESP_PART_NUM=$(echo "$ESP_DEVICE" | sed 's/.*[^0-9]//')
  75. efibootmgr -c -d "$ESP_DISK" -p "$ESP_PART_NUM" -L "Limine" -l "\\EFI\\Limine\\limine_x64.efi" || {
  76. print_warning "Could not create UEFI boot entry automatically"
  77. }
  78. print_success "Limine UEFI boot entry created"
  79. print_status "Configuring kernel command line..."
  80. echo "$CURRENT_CMDLINE" >/etc/kernel/cmdline
  81. print_success "Kernel command line configured: $CURRENT_CMDLINE"
  82. print_status "Configuring Limine..."
  83. [[ ! -f "/etc/default/limine" ]] && cat >/etc/default/limine <<EOF
  84. SPACE_NUMBER=2
  85. ENABLE_VERIFICATION=yes
  86. BACKUP_THRESHOLD=8
  87. BOOT_ORDER="*, *fallback, Snapshots"
  88. ENABLE_SORT=no
  89. ENABLE_LIMINE_FALLBACK=no
  90. FIND_BOOTLOADERS=yes
  91. ROOT_SNAPSHOTS_PATH="/@snapshots"
  92. EOF
  93. print_status "Creating custom Limine configuration..."
  94. cat >"$ESP_PATH/limine.conf" <<'EOF'
  95. ### Read more at config document: https://github.com/limine-bootloader/limine/blob/trunk/CONFIG.md
  96. timeout: 1
  97. ### Note: For "default_entry" to select a sub-entry within an OS menu, modify "/OS name" to "/+OS name" to keep its submenus visible.
  98. default_entry: 2
  99. #interface_branding_color: 3
  100. interface_branding:
  101. hash_mismatch_panic: no
  102. term_palette: 1e1e2e;f38ba8;a6e3a1;f9e2af;89b4fa;f5c2e7;94e2d5;cdd6f4
  103. term_palette_bright: 585b70;f38ba8;a6e3a1;f9e2af;89b4fa;f5c2e7;94e2d5;cdd6f4
  104. term_background: 1e1e2e
  105. term_foreground: cdd6f4
  106. term_background_bright: 585b70
  107. term_foreground_bright: cdd6f4
  108. EOF
  109. print_status "Generating Limine boot entries..."
  110. limine-update
  111. print_success "Limine configuration created"
  112. print_status "Setting Limine as default boot option..."
  113. LIMINE_ENTRY=$(efibootmgr | grep "Limine" | head -1 | cut -c5-8)
  114. if [[ -n "$LIMINE_ENTRY" ]]; then
  115. CURRENT_ORDER=$(efibootmgr | grep "BootOrder" | cut -d' ' -f2)
  116. NEW_ORDER=$(echo "$CURRENT_ORDER" | sed "s/$LIMINE_ENTRY,//g" | sed "s/,$LIMINE_ENTRY//g" | sed "s/^$LIMINE_ENTRY$//g")
  117. if [[ -n "$NEW_ORDER" ]]; then
  118. efibootmgr -o "$LIMINE_ENTRY,$NEW_ORDER"
  119. else
  120. efibootmgr -o "$LIMINE_ENTRY"
  121. fi
  122. print_success "Limine set as default boot option"
  123. else
  124. print_warning "Could not find Limine boot entry to set as default"
  125. fi
  126. print_status "Removing systemd-boot components..."
  127. # Remove systemd-boot UEFI entries
  128. SYSTEMD_ENTRIES=$(efibootmgr | grep -i "Linux Boot Manager\|systemd" | cut -c5-8 || true)
  129. if [[ -n "$SYSTEMD_ENTRIES" ]]; then
  130. for entry in $SYSTEMD_ENTRIES; do
  131. print_status "Removing UEFI boot entry: Boot$entry"
  132. efibootmgr -b "$entry" -B || print_warning "Failed to remove boot entry $entry"
  133. done
  134. fi
  135. # Remove systemd-boot files from ESP
  136. if [[ -d "$ESP_PATH/EFI/systemd" ]]; then
  137. print_status "Removing systemd-boot EFI files..."
  138. rm -rf "$ESP_PATH/EFI/systemd"
  139. print_success "systemd-boot EFI files removed"
  140. fi
  141. if [[ -d "$ESP_PATH/loader" ]]; then
  142. print_status "Removing systemd-boot configuration..."
  143. rm -rf "$ESP_PATH/loader"
  144. print_success "systemd-boot configuration removed"
  145. fi
  146. if [[ -f "$ESP_PATH/limine.conf" ]]; then
  147. print_success "Limine configuration file exists"
  148. else
  149. print_error "Limine configuration file missing!"
  150. fi
  151. if [[ -f "$ESP_PATH/EFI/Limine/limine_x64.efi" ]]; then
  152. print_success "Limine EFI bootloader exists"
  153. else
  154. print_error "Limine EFI bootloader missing!"
  155. fi
  156. sudo pacman -S snap-pac
  157. sudo systemctl enable --now limine-snapper-sync.service
  158. echo
  159. print_success "TRANSITION COMPLETED SUCCESSFULLY!"
  160. echo
  161. print_status "Summary:"
  162. echo " • Limine bootloader installed to: $ESP_PATH/EFI/Limine/"
  163. echo " • Configuration file: $ESP_PATH/limine.conf"
  164. echo " • Kernel command line: /etc/kernel/cmdline"
  165. echo " • Backup created at: $BACKUP_DIR"
  166. echo " • Boot order updated"
  167. echo " • systemd-boot completely removed"
  168. echo
  169. print_warning "IMPORTANT: Reboot to test the new Limine setup!"
  170. print_warning "systemd-boot has been completely removed - ensure Limine works before removing backup!"
  171. print_success "Script completed. Please reboot when ready."