core: 兼容 alpine extlinux

This commit is contained in:
bin456789 2024-09-09 22:56:13 +08:00
parent 1b0667a271
commit 925f148fc7
No known key found for this signature in database
GPG Key ID: EE301B386DE6C11B
2 changed files with 198 additions and 101 deletions

View File

@ -141,8 +141,12 @@ is_use_dd() {
[ "$distro" = dd ]
}
is_boot_in_separate_partition() {
mount | grep -q ' on /boot type '
}
is_os_in_btrfs() {
mount | grep -qw 'on / type btrfs'
mount | grep -q ' on / type btrfs '
}
is_os_in_subvol() {
@ -1742,13 +1746,27 @@ is_secure_boot_enabled() {
fi
}
is_use_grub() {
is_need_grub_extlinux() {
! { is_netboot_xyz && is_efi; }
}
# 只有 linux bios 是用本机的 grub
# 只有 linux bios 是用本机的 grub/extlinux
is_use_local_grub_extlinux() {
is_need_grub_extlinux && ! is_in_windows && ! is_efi
}
is_use_local_grub() {
is_use_grub && ! is_in_windows && ! is_efi
is_use_local_grub_extlinux && is_mbr_using_grub
}
is_use_local_extlinux() {
is_use_local_grub_extlinux && ! is_mbr_using_grub
}
is_mbr_using_grub() {
find_main_disk
# 各发行版不一定自带 strings hexdump xxd od 命令
head -c 440 /dev/$xda | grep --text -iq 'GRUB'
}
to_upper() {
@ -2262,6 +2280,29 @@ install_grub_win() {
fi
}
find_grub_extlinux_cfg() {
dir=$1
filename=$2
keyword=$3
# 当 ln -s /boot/grub /boot/grub2 时
# find /boot/ 会自动忽略 /boot/grub2 里面的文件
cfgs=$(
# 只要 $dir 存在
# 无论是否找到结果,返回值都是 0
find $dir \
-type f -name $filename \
-exec grep -E -l "$keyword" {} \;
)
count="$(wc -l <<<"$cfgs")"
if [ "$count" -eq 1 ]; then
echo "$cfgs"
else
error_and_exit "Find $count $filename."
fi
}
# 转换 finalos_a=1 为 finalos.a=1 ,排除 finalos_mirrorlist
build_finalos_cmdline() {
if vars=$(compgen -v finalos_); then
@ -3239,7 +3280,7 @@ if [ "$nextos_distro" = alpine ] || is_distro_like_debian "$nextos_distro"; then
fi
# 将内核/netboot.xyz.lkrn 放到正确的位置
if false && is_use_grub; then
if false && is_need_grub_extlinux; then
if is_in_windows; then
cp -f /reinstall-vmlinuz /cygdrive/$c/
is_have_initrd && cp -f /reinstall-initrd /cygdrive/$c/
@ -3251,8 +3292,8 @@ if false && is_use_grub; then
fi
fi
# grub
if is_use_grub; then
# grub / extlinux
if is_need_grub_extlinux; then
# win 使用外部 grub
if is_in_windows; then
install_grub_win
@ -3265,9 +3306,7 @@ if is_use_grub; then
fi
fi
info 'create grub config'
# 寻找 grub.cfg
# 寻找 grub.cfg / extlinux.conf
if is_in_windows; then
if is_efi; then
grub_cfg=/cygdrive/$c/grub.cfg
@ -3282,28 +3321,25 @@ if is_use_grub; then
efi_reinstall_dir=$(find $(get_maybe_efi_dirs_in_linux) -type d -name "reinstall" | head -1)
grub_cfg=$efi_reinstall_dir/grub.cfg
else
if is_mbr_using_grub; then
if is_have_cmd update-grub; then
# alpine debian ubuntu
grub_cfg=$(grep -o '[^ ]*grub.cfg' "$(get_cmd_path update-grub)" | head -1)
else
# 找出主配置文件含有menuentry|blscfg
# 现在 efi 用下载的 grub因此不需要查找 efi 目录
grub_cfg=$(
find /boot/grub* \
-type f -name grub.cfg \
-exec grep -E -l 'menuentry|blscfg' {} \;
)
if [ "$(wc -l <<<"$grub_cfg")" -gt 1 ]; then
error_and_exit 'find multi grub.cfg files.'
grub_cfg=$(find_grub_extlinux_cfg '/boot/grub*' grub.cfg 'menuentry|blscfg')
fi
else
# extlinux
extlinux_cfg=$(find_grub_extlinux_cfg /boot extlinux.conf LINUX)
fi
fi
fi
# 判断用 linux 还是 linuxefi主要是红帽系
# 现在 efi 用下载的 grub因此不需要判断 linux 或 linuxefi
if false && is_use_local_grub; then
if false && is_use_local_grub_extlinux; then
# 在x86 efi机器上不同版本的 grub 可能用 linux 或 linuxefi 加载内核
# 通过检测原有的条目有没有 linuxefi 字样就知道当前 grub 用哪一种
# 也可以检测 /etc/grub.d/10_linux
@ -3343,7 +3379,14 @@ if is_use_grub; then
fi
fi
# 选择用 custom.cfg (linux-bios) 还是 grub.cfg (win/linux-efi)
# 重新生成 extlinux.conf
if is_use_local_extlinux; then
if is_have_cmd update-extlinux; then
update-extlinux
fi
fi
# 选择用 custom.cfg (linux-bios) 还是 grub.cfg (linux-efi / win)
if is_use_local_grub; then
target_cfg=$(dirname $grub_cfg)/custom.cfg
else
@ -3354,6 +3397,11 @@ if is_use_grub; then
if is_in_windows; then
# dir=/cygwin/
dir=$(cygpath -m / | cut -d: -f2-)/
else
# extlinux + 单独的 boot 分区
# 把内核文件放在 extlinux.conf 所在的目录
if is_use_local_extlinux && is_boot_in_separate_partition; then
dir=
else
# 获取当前系统根目录在 btrfs 中的绝对路径
if is_os_in_btrfs; then
@ -3367,24 +3415,67 @@ if is_use_grub; then
dir=/
fi
fi
fi
vmlinuz=${dir}reinstall-vmlinuz
initrd=${dir}reinstall-initrd
firmware=${dir}reinstall-firmware
# 生成 linux initrd 命令
if is_netboot_xyz; then
linux_cmd="linux16 $vmlinuz"
# 设置 linux initrd 命令
if is_use_local_extlinux; then
linux_cmd=LINUX
initrd_cmd=INITRD
else
find_main_disk
build_cmdline
linux_cmd="linux$efi $vmlinuz $cmdline"
initrd_cmd="initrd$efi $initrd"
if is_use_firmware; then
initrd_cmd+=" $firmware"
if is_netboot_xyz; then
linux_cmd=linux16
initrd_cmd=initrd16
else
linux_cmd="linux$efi"
initrd_cmd="initrd$efi"
fi
fi
# 设置 cmdlind initrds
if ! is_netboot_xyz; then
find_main_disk
build_cmdline
initrds="$initrd"
if is_use_firmware; then
initrds+=" $firmware"
fi
fi
if is_use_local_extlinux; then
info extlinux
echo $extlinux_cfg
extlinux_dir="$(dirname $extlinux_cfg)"
# 不起作用
# 好像跟 extlinux --once 有冲突
sed -i "/^MENU HIDDEN/d" $extlinux_cfg
sed -i "/^TIMEOUT /d" $extlinux_cfg
del_empty_lines <<EOF | tee -a $extlinux_cfg
TIMEOUT 5
LABEL reinstall
MENU LABEL $(get_entry_name)
$linux_cmd $vmlinuz
$([ -n "$initrds" ] && echo "$initrd_cmd $initrds")
$([ -n "$cmdline" ] && echo "APPEND $cmdline")
EOF
# 设置重启引导项
extlinux --once=reinstall $extlinux_dir
# 复制文件到 extlinux 工作目录
if is_boot_in_separate_partition; then
info "copying files to $extlinux_dir"
is_have_initrd && cp -f /reinstall-initrd $extlinux_dir
is_use_firmware && cp -f /reinstall-firmware $extlinux_dir
# 放最后,防止前两条返回非 0 而报错
cp -f /reinstall-vmlinuz $extlinux_dir
fi
else
# cloudcone 从光驱的 grub 启动,再加载硬盘的 grub.cfg
# menuentry "Grub 2" --id grub2 {
# set root=(hd0,msdos1)
@ -3422,6 +3513,7 @@ if is_use_grub; then
# 生成 grub 配置
# 实测 centos 7 lvm 要手动加载 lvm 模块
info grub
echo $target_cfg
get_function_content load_grubenv_if_not_loaded >$target_cfg
@ -3435,8 +3527,8 @@ menuentry "$(get_entry_name)" --unrestricted {
$(is_os_in_btrfs && echo 'set btrfs_relative_path=n')
insmod all_video
search --no-floppy --file --set=root $vmlinuz
$linux_cmd
$initrd_cmd
$linux_cmd $vmlinuz $cmdline
$([ -n "$initrds" ] && echo "$initrd_cmd $initrds")
}
EOF
@ -3445,6 +3537,7 @@ EOF
$grub-reboot "$(get_entry_name)"
fi
fi
fi
info 'info'
echo "$distro $releasever"

View File

@ -1861,6 +1861,10 @@ create_part() {
mkfs.ext4 -E nodiscard -F -L installer /dev/$xda*2 #2 installer
fi
elif [ "$distro" = alpine ] || [ "$distro" = arch ] || [ "$distro" = gentoo ] || [ "$distro" = nixos ]; then
# alpine 本身关闭了 64bit ext4
# https://gitlab.alpinelinux.org/alpine/alpine-conf/-/blob/3.18.1/setup-disk.in?ref_type=tags#L908
# 而且 alpine 的 extlinux 不兼容 64bit ext4
[ "$distro" = alpine ] && ext4_opts="-O ^64bit" || ext4_opts=
if is_efi; then
# efi
parted /dev/$xda -s -- \
@ -1871,7 +1875,7 @@ create_part() {
update_part
mkfs.fat /dev/$xda*1 #1 efi
mkfs.ext4 -E nodiscard -F /dev/$xda*2 #2 os
mkfs.ext4 -E nodiscard -F $ext4_opts /dev/$xda*2 #2 os
elif is_xda_gt_2t; then
# bios > 2t
parted /dev/$xda -s -- \
@ -1882,7 +1886,7 @@ create_part() {
update_part
echo #1 bios_boot
mkfs.ext4 -E nodiscard -F /dev/$xda*2 #2 os
mkfs.ext4 -E nodiscard -F $ext4_opts /dev/$xda*2 #2 os
else
# bios
parted /dev/$xda -s -- \
@ -1891,7 +1895,7 @@ create_part() {
set 1 boot on
update_part
mkfs.ext4 -E nodiscard -F /dev/$xda*1 #1 os
mkfs.ext4 -E nodiscard -F $ext4_opts /dev/$xda*1 #1 os
fi
else
# 安装红帽系或ubuntu
@ -1913,7 +1917,7 @@ create_part() {
# centos 7 无法加载alpine格式化的ext4
# 要关闭这个属性
ext4_options="-O ^metadata_csum"
ext4_opts="-O ^metadata_csum"
apk add dosfstools
if is_efi; then
@ -1928,7 +1932,7 @@ create_part() {
mkfs.fat -n efi /dev/$xda*1 #1 efi
mkfs.ext4 -E nodiscard -F -L os /dev/$xda*2 #2 os
mkfs.ext4 -E nodiscard -F -L installer $ext4_options /dev/$xda*3 #2 installer
mkfs.ext4 -E nodiscard -F -L installer $ext4_opts /dev/$xda*3 #2 installer
elif is_xda_gt_2t; then
# bios > 2t
parted /dev/$xda -s -- \
@ -1941,7 +1945,7 @@ create_part() {
echo #1 bios_boot
mkfs.ext4 -E nodiscard -F -L os /dev/$xda*2 #2 os
mkfs.ext4 -E nodiscard -F -L installer $ext4_options /dev/$xda*3 #3 installer
mkfs.ext4 -E nodiscard -F -L installer $ext4_opts /dev/$xda*3 #3 installer
else
# bios
parted /dev/$xda -s -- \
@ -1952,7 +1956,7 @@ create_part() {
update_part
mkfs.ext4 -E nodiscard -F -L os /dev/$xda*1 #1 os
mkfs.ext4 -E nodiscard -F -L installer $ext4_options /dev/$xda*2 #2 installer
mkfs.ext4 -E nodiscard -F -L installer $ext4_opts /dev/$xda*2 #2 installer
fi
update_part
fi