I just want to sincerely thank all those involved in fixing this issue, well done! I wish I could have helped more, but I got buried with work and and just did not have any spare time. But I would watch the thread on my phone when I could, and I learned a lot! Any way, I hope to do some testing on my ISO’s this weekend, Thank you all again!
Can i ask what should be the official testing method to create pendrive, or acceptable testing method? Should use the gnome disk tool? balena etcher, rufus?
And what info will be usefull/valuable?
The only method that do not work - ever - is the iso-mode originally used by Rufus and claimed as the only way. After contacting Manjaro - the Rufus developer changed how a Manjaro ISO is written to be a byte-to-byte copy - known in Rufus as dd-mode (the actual documentation has been lost to the byte-void).
That means - any software capable of doing a byte-to-byte copy will work.
One could say that creating a byte-to-byte copy of a Manjaro ISO, to the chosen target medium should prove without any shred of doubt that the ISO is bootable and fully functional.
I do want to add that one should always use a suitable USB-stick, as using a DVD is discouraged as the loading of the desktop may be unreasonable slow, thereby causing a bad experience.
Any method that creates an exact “byte-for-byte” (as @linux-aarhus suggests) copy of an ISO should normally suffice.
Ventoy is popular because once the USB is created, one only needs to drag an ISO file to the empty Ventoy USB partition (the actual Ventoy functionality remains contained within the $ESP of the USB).
Each of us have preferences; opinions; however, for the convenience factor (being able to store many ISO files on the Ventoy USB, ready to boot) my goto is Ventoy.
You could make an USB drive with three partitions: EFI, GRUB, and a data partition for ISO-files.
I doubt if this is able to boot a Windows install ISO like Ventoy can, but I never need that anyway.
grub2usb.sh: script to make partitions
#!/bin/sh
# inspired by colinxu.wordpress.com/2018/12/29/create-a-universal-bootable-usb-drive-using-grub2/
THIS=$(realpath --canonicalize-existing "$0" 2>/dev/null)
THISPATH=$(dirname "$THIS")
THISPROG=$(basename $THIS)
efilabel=EFIPART
fstype=ext2
datalabel=ISOSHERE
HELPTXT="\t run $THIS -h for help\n"
USAGE="
$THISPROG wipes a device and installs GRUB2
Usage: $THISPROG [options] {device}
options:
-l {label} : label for data partition, default $datalabel
-t {vfat|exfat|ext2|ext4} : type of file system to use, default $fstype
-v: verbose mode, show commands
-d: DEBUG mode, just show commands, do not run commands
$THISPROG must be run by root or with sudo
"
#################### FUNCTIONS #################################################
Exit_if_Error ()
# $1 is return code to test
# $2 is command line that returned return code
{
if test $1 -ne 0 ; then
printf %b "\n$(date '+%F %T') command '$2' failed with return code $1\n"
umount ${DEVICE}1 ${DEVICE}2 ${DEVICE}3
exit $1
fi
}
MakeFilesys ()
# $1 is file system type
# $2 is device to create file system on
# $3 is label for file system (optional)
{
local _fsopt _command
if test "$1" = "ext4" -o "$1" = "ext2" ; then _fsopt='-m 0' ; fi
if test -z "$3" ; then
_command="mkfs $VERBOSE $_fsopt -t $1 $2"
else
_command="mkfs $VERBOSE $_fsopt -t $1 -L $3 $2"
fi
if test -n "$VERBOSE" ; then printf %b "\nmaking file system with $_command\n" ; fi
$DEBUG $_command ; Exit_if_Error $? "$_command"
} # MakeFilesys
#################### MAIN ######################################################
unset DEBUG VERBOSE VERB
while getopts 'l:t:vdhH' OPTION ; do
case $OPTION in
l) datalabel=$OPTARG ;; # no blanks allowed
t)
fstype=$OPTARG
if test $fstype = fat -o $fstype = msdos -o $fstype = umsdos ; then fstype=vfat ; fi
if test $fstype != vfat -a $fstype != exfat -a $fstype != ext2 -a $fstype != ext4 ; then
printf %b "\n\t filesystem must be vfat or exfat or ext2 or ext4 - ABORTING\n$HELPTXT"
exit 1
fi
;;
v) VERBOSE='--verbose' ; VERB='-v' ;;
d) DEBUG='echo -e \nDEBUG ECHOING' ; VERBOSE='--verbose' ; VERB='-v' ;;
*)
printf %b "$USAGE"
exit 1
;;
esac
done
shift $(expr $OPTIND - 1)
if test -n "$VERBOSE" ; then printf %b "\n$THIS started $(date '+%F %T') with PID $$ and parameters '$*'\n" ; fi
if test $# -ne 1 ; then printf %b "\n\t No device in parameters - ABORTING!\n$USAGE" ; exit 1
else DEVICE="$1"
fi
devtype=$(lsblk -ndo type ${DEVICE}) ; rescode=$?
if test $rescode -gt 0 ; then printf %b "\n\t $DEVICE is not a usable device - ABORTING!\n$HELPTXT" ; exit 2
elif test "$devtype" = "part" ; then printf %b "\n\t $DEVICE is a partition, you must use disk device - ABORTING!\n$HELPTXT" ; exit 3
elif test "$devtype" != "disk" ; then printf %b "\n\t $DEVICE is not a disk - ABORTING!\n$HELPTXT" ; exit 4
fi
printf %b "\n\t THIS SCRIPT WILL ERASE EVERYTHING ON $DEVICE COMPLETELY \n\t enter YES to proceed or press Ctrl+C to abort - LAST CHANCE !\n"
read pressedkey
if test "$pressedkey" != "YES" ; then printf %b "\n\t did not enter YES - ABORTING!\n" ; exit 1 ; fi
printf %b "\n\t Creating partitions and install GRUB2 on '$DEVICE' , file system '$fstype' with label '${datalabel}'\n"
if test $(id -u) -gt 0 ; then printf %b "\n\t YOU ARE NOT ROOT - ABORTING!\n$HELPTXT" ; exit 9 ; fi
if test -n "$VERBOSE" -a -z "$DEBUG" ; then set -x ; fi
$DEBUG umount ${DEVICE}1 ${DEVICE}2 ${DEVICE}3
# remove all file systems on device
$DEBUG wipefs --all ${DEVICE}
$DEBUG sgdisk --zap-all
$DEBUG dd if=/dev/zero of=${DEVICE} bs=4k count=64
sleep 1
partprobe ${DEVICE}
# Create 1st partition as BIOS Boot partition to store MBR boot code
$DEBUG sgdisk --new=1:2048:4095 --typecode=1:0xEF02 ${DEVICE}
# Hide BIOS boot partition from EFI and mark it bootable
$DEBUG sgdisk --attributes=1:set:1 --attributes=1:set:2 ${DEVICE}
# Create 2nd partition as ESP for UEFI boot code
$DEBUG sgdisk --new=2:4096:135167 --typecode=2:0xEF00 ${DEVICE}
# Create partition for ISO-files etc.
$DEBUG sgdisk --largest-new=3 ${DEVICE}
$DEBUG mkfs.vfat -F32 -n ${efilabel} ${DEVICE}2
$DEBUG umount ${DEVICE}1 ${DEVICE}2 ${DEVICE}3
MakeFilesys $fstype ${DEVICE}3 ${datalabel}
partprobe ${DEVICE}
mkdir --parent /mnt/efi /mnt/data
$DEBUG mount ${DEVICE}2 /mnt/efi
$DEBUG grub-install --target=i386-pc --boot-directory=/mnt/efi/boot --removable ${DEVICE}
$DEBUG grub-install --target=i386-efi --efi-directory=/mnt/efi/ --boot-directory=/mnt/efi/boot --removable ${DEVICE}
$DEBUG grub-install --target=x86_64-efi --efi-directory=/mnt/efi/ --boot-directory=/mnt/efi/boot --removable ${DEVICE}
if test -r "$THISPATH/usbgrub.cfg" ; then $DEBUG cp --preserve=timestamps "$THISPATH/usbgrub.cfg" /mnt/efi/boot/grub/grub.cfg ; fi
if test -r "$THISPATH/menu.autoiso.sh" ; then
$DEBUG cp --preserve=timestamps "$THISPATH/menu.autoiso.sh" /mnt/efi/boot/grub/
$DEBUG mount ${DEVICE}3 /mnt/data
$DEBUG mkdir /mnt/data/ISOboot
$DEBUG chown 1000:1000 /mnt/data/ISOboot
fi
umount ${DEVICE}1 ${DEVICE}2 ${DEVICE}3
menu.autoiso.sh: GRUB script to boot from ISO
########## Auto Live ISO distros searching below ###############################
if test -z "$langcode" ; then langcode=dk ; fi # must set global variable
insmod regexp
function basename { regexp -s 1:"$2" '.*/([^/]*)$' "$1"; }
function increment {
# stackoverflow.com/questions/42244685/grub2-howto-increment-variable
# increment number
# increment $varname -s varname
# Validate arguments
[ $# -eq 1 -o $# -eq 3 ]
set usage=$?
if [ $# -eq 3 ]; then
[ "$2" = "-s" -o "$2" = "--set" ]
set usage=$?
fi
if [ $usage -eq 1 -o "$1" = "-h" -o "$1" = "--help" ]; then
echo "Usage: increment NUMBER"
echo "Increment decimal NUMBER >= 0."
echo
echo "-s, --set VARNAME Store value in VARNAME."
unset usage
return 1
fi
unset usage
# Validate decimal number >= 0 (empty string "" equivalent to 0)
if ! regexp '^[0-9]*$' -- "$1"; then
echo "$1: not a decimal number >=0 "
return 1
fi
# Use regexp to compute and save $1 (mod 10) to (div, mod)
# Use tr to obtain successor(mod) where "0" requires carry
if [ -z "$1" ]; then
set div=
set mod=0
else
regexp '(.*)([0-9])$' "$1" -s 1:div -s 2:mod
fi
tr '[0123456789]' '[1234567890]' "$mod" -s successor
# Work right to left adding a zero for each carry
set zeros=
while [ -n "$div" -a "$successor" = "0" ]; do
set zeros=0${zeros}
regexp '(.*)([0-9])$' "$div" -s 1:div -s 2:mod
tr '[0123456789]' '[1234567890]' "$mod" -s successor
done
if [ "$successor" = "0" ]; then
set successor=10
fi
# Remove leading zeros
set result=${div}${successor}${zeros}
regexp '^00*(..*)$' "$result" -s result
# Save or print result
if [ -n "$3" ]; then
eval set $3=${result}
else
echo ${result}
fi
# Cleanup function variables
for varname in div mod successor zeros result; do
eval unset $varname
done
unset varname
} # increment
# https://github.com/cfriedt/grub/blob/master/docs/autoiso.cfg
# https://gitlab.com/linux-be/grub/blob/master/docs/autoiso.cfg
# and from source in https://ftp.gnu.org/gnu/grub/
# Sample GRUB script to autodetect operating systems
#
# Copyright (C) 2010 Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
function pathname { regexp -s 2:"$2" '^(\(.*\))?(/.*)$' "$1"; }
function devname { regexp -s "$2" '^(\(.*\)).*$' "$1"; }
function loopback_iso_entry {
realdev="$1"
isopath="$2"
loopdev="$3"
if test -f /boot/grub/loopback.cfg; then
cfgpath=/boot/grub/loopback.cfg
elif test -f /grub/loopback.cfg; then
cfgpath=/grub/loopback.cfg
elif test -f /boot/grub2/loopback.cfg; then
cfgpath=/boot/grub2/loopback.cfg
elif test -f /grub2/loopback.cfg; then
cfgpath=/grub2/loopback.cfg
else
return 1;
fi
# echo loopback.cfg $isopath: yes
# menuentry "Boot GRUB Loopback Config from ${realdev}${isopath}" "$realdev" "$isopath" "$cfgpath" {
# echo "loopback.cfg $isopath: yes - press escape to continue" ; sleep --verbose --interruptible 5
basename ${isopath} isofile
menuentry "$foundcount: ${isofile} GRUB Loopback Config ${realdev}" "$realdev" "$isopath" "$cfgpath" --hotkey="$foundcount" {
set device="$2"
set iso_path="$3"
set cfg_path="$4"
export iso_path
loopback loopdev_cfg "${device}${iso_path}"
set root=(loopdev_cfg)
configfile $cfg_path
loopback -d loopdev_cfg
}
return 0
} # loopback_iso_entry
function casper_iso_entry {
realpath="$1"
isopath="$2"
loopdev="$3"
if ! test -f /casper/vmlinuz; then return 1; fi
initrd=
# for f in /casper/initrd.*z; do
for f in /casper/initrd* ; do
if ! test -f "$f"; then continue; fi
pathname "$f" initrd
done
if test -z "$initrd"; then return 1; fi
# echo casper $isopath: yes
# menuentry "Casper based Linux from ${realdev}${isopath}" "$realdev" "$isopath" "$initrd" {
# echo "casper $isopath: yes - press escape to continue" ; sleep --verbose --interruptible 5
basename ${isopath} isofile
menuentry "$foundcount: ${isofile} Casper based ${realdev}" "$realdev" "$isopath" "$initrd" --hotkey="$foundcount" {
set device="$2"
set isopath="$3"
set initrd="$4"
loopback loopdev_casper "${device}${isopath}"
set root=(loopdev_casper)
linux /casper/vmlinuz boot=casper iso-scan/filename="$isopath" quiet splash noprompt keyb="$langcode" \
debian-installer/language="$langcode" console-setup/layoutcode?="$langcode" --
initrd $initrd
loopback -d loopdev_casper
}
return 0
} # casper_iso_entry
########## functions added by Freddy Vejen below ###############################
function tails_iso_entry {
realdev="$1"
isopath="$2"
if ! test ( -f /live/Tails.module -a -f /live/vmlinuz -a -f /live/initrd.img ) ; then return 1; fi
# echo "TAILS in ${realdev}${isopath} : yes - press escape to continue" ; sleep --verbose --interruptible 5
menuentry "$foundcount: TAILS in ${realdev}${isopath}" "$realdev" "$isopath" --hotkey="$foundcount" {
set device="$2"
set iso_path="$3"
set kernel=/live/vmlinuz
set initramdisk=/live/initrd.img
loopback looplocal "${device}${iso_path}"
set root=(looplocal)
set FAILSAFE="noapic noapm nodma nomce nolapic nomodeset nosmp vga=normal"
echo "Loading kernel $kernel ..."
linux $kernel findiso=$iso_path boot=live config nopersistence noprompt timezone=Europe/Copenhagen nosplash noautologin module=Tails slab_nomerge slub_debug=FZ mce=0 vsyscall=none init_on_free=1 mds=full,nosmt page_alloc.shuffle=1 randomize_kstack_offset=on efi_pstore.pstore_disable=1 erst_disable spec_store_bypass_disable=on systemd.condition_needs_update=no
# linux /live/vmlinuz initrd=/live/initrd.img boot=live config live-media=removable nopersistence noprompt timezone=Etc/UTC splash noautologin module=Tails slab_nomerge slub_debug=FZ mce=0 vsyscall=none init_on_free=1 mds=full,nosmt page_alloc.shuffle=1 randomize_kstack_offset=on efi_pstore.pstore_disable=1 erst_disable spec_store_bypass_disable=on systemd.condition_needs_update=no FSUUID=${rootuuid} quiet
echo 'Loading initial ramdisk ...'
initrd $initramdisk
loopback -d looplocal
} # end of menuentry
return 0
} # tails_iso_entry
function clozil_iso_entry {
realdev="$1"
isopath="$2"
if ! test ( -f /live/Clonezilla-Live-Version -a -f /live/vmlinuz -a -f /live/initrd.img ) ; then return 1; fi
# echo "Clonezilla in ${realdev}${isopath} : yes - press escape to continue" ; sleep --verbose --interruptible 5
basename ${isopath} isofile
menuentry "$foundcount: ${isofile} Clonezilla ${realdev}" "$realdev" "$isopath" --hotkey="$foundcount" {
set device="$2"
set iso_path="$3"
set kernel=/live/vmlinuz
set initramdisk=/live/initrd.img
loopback looplocal "${device}${iso_path}"
set root=(looplocal)
echo "Loading kernel $kernel ... "
# failsafe from iso/boot/grub/grub.cfg # linux $kernel boot=live union=overlay username=user config components loglevel=3 hostname=cl-3.3.2-31 noswap edd=on nomodeset enforcing=0 locales= keyboard-layouts= ocs_live_run="ocs-live-general" ocs_live_extra_param="" ocs_live_batch="no" acpi=off irqpoll noapic noapm nodma nomce nolapic nosmp net.ifnames=0 nomodeset vga=normal nosplash
linux $kernel boot=live findiso=$iso_path locales=en_US.UTF-8 keyboard-layouts=$langcode nosplash noswap vga=normal
echo 'Loading initial ramdisk ...'
initrd $initramdisk
loopback -d looplocal
} # end of menuentry
return 0
} # clozil_iso_entry
function live_iso_entry {
realdev="$1"
isopath="$2"
if ! test ( -f /live/vmlinuz -a -f /live/initrd.img ) ; then return 1; fi
# echo "UNKNOWN possible Live distro in ${realdev}${isopath} : yes - press escape to continue" ; sleep --verbose --interruptible 5
basename ${isopath} isofile
menuentry "$foundcount: ${isofile} UNKNOWN ${realdev}" "$realdev" "$isopath" --hotkey="$foundcount" {
set device="$2"
set iso_path="$3"
set kernel=/live/vmlinuz
set initramdisk=/live/initrd.img
loopback looplocal "${device}${iso_path}"
set root=(looplocal)
echo "Loading kernel $kernel ..."
linux $kernel boot=live findiso=$iso_path locales=en_US.UTF-8 keyboard-layouts=$langcode nosplash noswap
echo 'Loading initial ramdisk ...'
initrd $initramdisk
loopback -d looplocal
} # end of menuentry
return 0
} # live_iso_entry
########## functions added by Freddy Vejen above ###############################
function scan_isos {
isodirs="$1"
echo "scan_isos '$isodirs' "
for device in (*) ; do echo "device '$device'" ; done # try to wake up devices
foundcount=0
for dev in (*); do
for dir in $isodirs; do # NB: all isodirs must have trailing slash
for file in ${dev}${dir}*.iso ${dev}${dir}*.ISO ${dev}${dir}*.isodef ; do
if ! test -f "$file"; then continue; fi # reloop if not file
# echo "foundcount '$foundcount' dev '$dev' isopath '$isopath' "
# echo "- press escape to continue" ; sleep --verbose --interruptible 5
pathname $file isopath
if test -z "$dev" -o -z "$isopath"; then continue; fi # reloop if empty
if ! loopback loopdev_scan "$file"; then continue; fi # reloop if loop mount fails
saved_root=$root
set root=(loopdev_scan)
# entries with (loopdev_scan) are from GRUB's autoiso.cfg
if clozil_iso_entry $dev $isopath ; then increment $foundcount -s foundcount
elif tails_iso_entry $dev $isopath ; then increment $foundcount -s foundcount
elif casper_iso_entry $dev $isopath (loopdev_scan); then increment $foundcount -s foundcount # Ubuntu uses GRUB loop-back to point to Casper
elif loopback_iso_entry $dev $isopath (loopdev_scan); then increment $foundcount -s foundcount
# NB: loopback_iso_entry must be after all the specific distros because it catches all with *grub/loopback.cfg
elif live_iso_entry $dev $isopath ; then increment $foundcount -s foundcount
# NB: live_iso_entry must be last because it does not check for file with certain file name that can identify distro
else true; fi
echo ' '
set root=$saved_root
loopback -d loopdev_scan
done # for file
done # for dir
done # for dev
# echo "end of scan_isos - press escape to continue" ; sleep --verbose --interruptible 30
return 0
} # scan_isos
########## Auto Live ISO MAIN ##################################################
# echo "before scan_isos - press escape to continue" ; sleep --verbose --interruptible 5
# NB: all isodirs must have trailing slash
scan_isos "/ /*iso*/ /boot/*iso*/ /*Iso*/ /boot/*Iso*/ /*ISO*/ /BOOT/*ISO*/ /_ISO/LINUX/ "
# echo "after scan_isos - press escape to continue" ; sleep --verbose --interruptible 5
########## Auto Live ISO distros searching above ###############################
usbgrub.cfg: GRUB config file
insmod part_gpt # GPT partition table
insmod part_msdos # MBR partition table
insmod fat # FAT partition
insmod exfat # exFAT partition
insmod ext2 # ext partition
insmod ntfs # NTFS partition
insmod ntfscomp # NTFS compression
insmod allvideo # Additional video and graphics
insmod chain # chainloader
if [ ${grub_platform} == "pc" ]; then
insmod ntldr # chainloader from file without reading boot record
else
insmod efi_uga # UEFI UGA
insmod efi_gop # UEFI GOP
fi
if [ -s $prefix/grubenv ]; then
load_env
fi
set timeout_style=menu
play 480 440 1
menuentry "Reboot" {
reboot
}
menuentry "Shutdown" {
halt
}
submenu 'L: LIVE menu - search for ISO files with live distros' --hotkey=L {configfile $prefix/menu.autoiso.sh}
There are many ways to achieve a similar goal; for a “Grub2-only” approach, there is this solution which could be written to CD, or to a (small) USB, or simply dragged to a Ventoy USB:
please somene push this to manjaro-tools-livecd
I only can test on Gnome. Works good!
lib/util-live.sh:
#!/bin/bash
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
kernel_cmdline(){
for param in $(cat /proc/cmdline); do
case "${param}" in
$1=*) echo "${param##*=}"; return 0 ;;
$1) return 0 ;;
*) continue ;;
esac
done
[ -n "${2}" ] && echo "${2}"
return 1
}
get_lang(){
echo $(kernel_cmdline lang)
}
get_keytable(){
echo $(kernel_cmdline keytable)
}
get_tz(){
echo $(kernel_cmdline tz)
}
get_timer_ms(){
echo $(date +%s%3N)
}
# $1: start timer
elapsed_time_ms(){
echo $(echo $1 $(get_timer_ms) | awk '{ printf "%0.3f",($2-$1)/1000 }')
}
load_live_config(){
[[ -f $1 ]] || return 1
live_conf="$1"
[[ -r ${live_conf} ]] && source ${live_conf}
[[ -z ${autologin} ]] && autologin=true
[[ -z ${username} ]] && username="manjaro"
[[ -z ${password} ]] && password="manjaro"
[[ -z ${addgroups} ]] && addgroups=""
[[ -z ${login_shell} ]] && login_shell="/bin/bash"
[[ -z ${smb_workgroup} ]] && smb_workgroup="Manjaro"
echo "Loaded ${live_conf}: $(elapsed_time_ms ${livetimer})ms" >> /var/log/manjaro-live.log
return 0
}
is_valid_de(){
if [[ ${default_desktop_executable} != "none" ]] && \
[[ ${default_desktop_file} != "none" ]]; then
return 0
else
return 1
fi
}
load_desktop_map(){
local _space="s| ||g" _clean=':a;N;$!ba;s/\n/ /g' _com_rm="s|#.*||g" \
file=${DATADIR}/desktop.map
local desktop_map=$(sed "$_com_rm" "$file" \
| sed "$_space" \
| sed "$_clean")
echo ${desktop_map}
}
detect_desktop_env(){
local xs=/usr/share/xsessions ex=/usr/bin key val map=( $(load_desktop_map) )
default_desktop_file="none"
default_desktop_executable="none"
for item in "${map[@]}";do
key=${item%:*}
val=${item#*:}
if [[ -f $xs/$key.desktop ]] && [[ -f $ex/$val ]];then
default_desktop_file="$key"
default_desktop_executable="$val"
fi
done
}
configure_accountsservice(){
local path=/var/lib/AccountsService/users
if [ -d "${path}" ] ; then
echo "[User]" > ${path}/$1
echo "XSession=${default_desktop_file}" >> ${path}/$1
if [[ -f "/var/lib/AccountsService/icons/$1.png" ]];then
echo "Icon=file:///var/lib/AccountsService/icons/$1.png" >> ${path}/$1
fi
fi
}
set_lightdm_greeter(){
local greeters=$(ls /usr/share/xgreeters/*greeter.desktop) name
for g in ${greeters[@]};do
name=${g##*/}
name=${name%%.*}
case ${name} in
lightdm-gtk-greeter) break ;;
lightdm-*-greeter)
sed -i -e "s/^.*greeter-session=.*/greeter-session=${name}/" /etc/lightdm/lightdm.conf
;;
esac
done
}
set_lightdm_vt(){
sed -i -e 's/^.*minimum-vt=.*/minimum-vt=7/' /etc/lightdm/lightdm.conf
}
# set_sddm_elogind(){
# gpasswd -a sddm video &> /dev/null
# }
set_pam(){
for conf in /etc/pam.d/*;do
sed -e 's|systemd.so|elogind.so|g' -i $conf
done
}
configure_samba(){
local conf=/etc/samba/smb.conf
cp /etc/samba/smb.conf.default $conf
sed -e "s|^.*workgroup =.*|workgroup = ${smb_workgroup}|" -i $conf
}
configure_displaymanager(){
# Try to detect desktop environment
# Configure display manager
if [[ -f /usr/bin/lightdm ]];then
groupadd -r autologin
[[ -d /run/openrc ]] && set_lightdm_vt
set_lightdm_greeter
if $(is_valid_de); then
sed -i -e "s/^.*user-session=.*/user-session=$default_desktop_file/" /etc/lightdm/lightdm.conf
fi
if ${autologin};then
gpasswd -a ${username} autologin &> /dev/null
sed -i -e "s/^.*autologin-user=.*/autologin-user=${username}/" /etc/lightdm/lightdm.conf
sed -i -e "s/^.*autologin-user-timeout=.*/autologin-user-timeout=0/" /etc/lightdm/lightdm.conf
sed -i -e "s/^.*pam-autologin-service=.*/pam-autologin-service=lightdm-autologin/" /etc/lightdm/lightdm.conf
fi
elif [[ -f /usr/bin/gdm ]];then
configure_accountsservice "gdm"
if ${autologin};then
sed -i -e "s/\[daemon\]/\[daemon\]\nAutomaticLogin=${username}\nAutomaticLoginEnable=True/" /etc/gdm/custom.conf
fi
elif [[ -f /usr/bin/mdm ]];then
if $(is_valid_de); then
sed -i "s|default.desktop|$default_desktop_file.desktop|g" /etc/mdm/custom.conf
fi
elif [[ -f /usr/bin/sddm ]];then
if [[ -e /etc/sddm.conf.d/kde_settings.conf ]];then
conf_file=/etc/sddm.conf.d/kde_settings.conf
else
conf_file=/etc/sddm.conf
fi
if $(is_valid_de); then
sed -i -e "s|^Session=.*|Session=$default_desktop_file.desktop|" $conf_file
fi
if ${autologin};then
sed -i -e "s|^User=.*|User=${username}|" $conf_file
fi
elif [[ -f /usr/bin/lxdm ]];then
if $(is_valid_de); then
sed -i -e "s|^.*session=.*|session=/usr/bin/$default_desktop_executable|" /etc/lxdm/lxdm.conf
fi
if ${autologin};then
sed -i -e "s/^.*autologin=.*/autologin=${username}/" /etc/lxdm/lxdm.conf
fi
fi
[[ -d /run/openrc ]] && set_pam
}
gen_pw(){
echo $(openssl passwd -6 ${password})
}
configure_user(){
# set up user and password
if [[ -n ${password} ]];then
useradd -m -G ${addgroups} -p $(gen_pw) -s ${login_shell} ${username}
else
useradd -m -G ${addgroups} -s ${login_shell} ${username}
fi
}
find_legacy_keymap(){
local file="${DATADIR}/kbd-model.map"
while read -r line || [[ -n $line ]]; do
if [[ -z $line ]] || [[ $line == \#* ]]; then
continue
fi
mapping=( $line ); # parses columns
if [[ ${#mapping[@]} != 5 ]]; then
continue
fi
if [[ "${keytable}" != "${mapping[0]}" ]]; then
continue
fi
if [[ "${mapping[3]}" = "-" ]]; then
mapping[3]=""
fi
X11_LAYOUT=${mapping[1]}
X11_MODEL=${mapping[2]}
X11_VARIANT=${mapping[3]}
X11_OPTIONS=${mapping[4]}
done < $file
}
write_x11_config(){
# write X11 keyboard configuration using previously determined
# X11_LAYOUT, X11_MODEL, X11_VARIANT, X11_OPTIONS (from find_legacy_keymap)
# fall back to keytable if layout is empty
[[ -z "$X11_LAYOUT" ]] && X11_LAYOUT="${keytable}"
[[ -z "$X11_MODEL" ]] && X11_MODEL="pc105"
[[ -z "$X11_VARIANT" ]] && X11_VARIANT=""
[[ -z "$X11_OPTIONS" ]] && X11_OPTIONS="terminate:ctrl_alt_bksp"
mkdir -p "/etc/X11/xorg.conf.d"
local XORGKBLAYOUT="/etc/X11/xorg.conf.d/00-keyboard.conf"
echo "" >> "$XORGKBLAYOUT"
echo "Section \"InputClass\"" > "$XORGKBLAYOUT"
echo " Identifier \"system-keyboard\"" >> "$XORGKBLAYOUT"
echo " MatchIsKeyboard \"on\"" >> "$XORGKBLAYOUT"
echo " Option \"XkbLayout\" \"$X11_LAYOUT\"" >> "$XORGKBLAYOUT"
echo " Option \"XkbModel\" \"$X11_MODEL\"" >> "$XORGKBLAYOUT"
echo " Option \"XkbVariant\" \"$X11_VARIANT\"" >> "$XORGKBLAYOUT"
echo " Option \"XkbOptions\" \"$X11_OPTIONS\"" >> "$XORGKBLAYOUT"
echo "EndSection" >> "$XORGKBLAYOUT"
}
configure_language(){
# hack to be able to set the locale on bootup
local lang=$(get_lang)
keytable=$(get_keytable)
local timezone=$(get_tz)
# Fallback
[[ -z "${lang}" ]] && lang="en_US"
[[ -z "${keytable}" ]] && keytable="us"
[[ -z "${timezone}" ]] && timezone="Etc/UTC"
sed -e "s/#${lang}.UTF-8/${lang}.UTF-8/" -i /etc/locale.gen
echo "LANG=${lang}.UTF-8" >> /etc/environment
if [[ -d /run/openrc ]]; then
sed -i "s/keymap=.*/keymap=\"${keytable}\"/" /etc/conf.d/keymaps
fi
echo "KEYMAP=${keytable}" > /etc/vconsole.conf
echo "LANG=${lang}.UTF-8" > /etc/locale.conf
ln -sf /usr/share/zoneinfo/${timezone} /etc/localtime
# Determine X11 layout from keytable
find_legacy_keymap
write_x11_config
# Also set the keymap via localectl so that GNOME/KDE Wayland sessions pick it up
if command -v localectl >/dev/null 2>&1 && [[ -n "${X11_LAYOUT}" ]]; then
localectl set-x11-keymap "${X11_LAYOUT}" "${X11_MODEL}" "${X11_VARIANT}" "${X11_OPTIONS}"
fi
loadkeys "${keytable}"
locale-gen
echo "Configured language: ${lang}" >> /var/log/manjaro-live.log
echo "Configured keymap: ${keytable}" >> /var/log/manjaro-live.log
echo "Configured timezone: ${timezone}" >> /var/log/manjaro-live.log
}
configure_machine_id(){
if [ -e "/etc/machine-id" ] ; then
# delete existing machine-id
echo "Deleting existing machine-id ..." >> /var/log/manjaro-live.log
rm /etc/machine-id
fi
# set unique machine-id
echo "Setting machine-id ..." >> /var/log/manjaro-live.log
dbus-uuidgen --ensure=/etc/machine-id
ln -sf /etc/machine-id /var/lib/dbus/machine-id
}
configure_sudoers_d(){
echo "%wheel ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/g_wheel
echo "root ALL=(ALL) ALL" > /etc/sudoers.d/u_root
#echo "${username} ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/u_live
}
configure_swap(){
local swapdev="$(fdisk -l 2>/dev/null | grep swap | cut -d' ' -f1)"
if [ -e "${swapdev}" ]; then
swapon ${swapdev}
fi
}
configure_user_root(){
# set up root password
echo "root:${password}" | chroot $1 chpasswd
cp /etc/skel/.{bash_profile,bashrc,bash_logout} /root/
[[ -f /etc/skel/.extend.bashrc ]] && cp /etc/skel/.extend.bashrc /root/
[[ -f /etc/skel/.gtkrc-2.0 ]] && cp /etc/skel/.gtkrc-2.0 /root/
if [[ -d /etc/skel/.config ]]; then
cp -an /etc/skel/.config /root/
fi
}
fix: propagate X11 keyboard layout via localectl for GNOME/KDE sessions
Ensure the live environment runs localectl set-x11-keymap in addition to
writing the xorg.conf.d snippet, so that Wayland-based desktops (GNOME, KDE)
correctly inherit the layout chosen in the bootloader. XFCE (X11) was
unaffected because it reads the Xorg configuration directly.
diff --git a/util-live-a.sh b/util-live-b.sh
index dc01b76..1d04c16 100644
--- a/util-live-a.sh
+++ b/util-live-b.sh
@@ -228,29 +228,20 @@ find_legacy_keymap(){
X11_LAYOUT=${mapping[1]}
X11_MODEL=${mapping[2]}
X11_VARIANT=${mapping[3]}
- x11_OPTIONS=${mapping[4]}
+ X11_OPTIONS=${mapping[4]}
done < $file
}
write_x11_config(){
- # find a x11 layout that matches the keymap
- # in isolinux if you select a keyboard layout and a language that doesnt match this layout,
- # it will provide the correct keymap, but not kblayout value
- local X11_LAYOUT=
- local X11_MODEL="pc105"
- local X11_VARIANT=""
- local X11_OPTIONS="terminate:ctrl_alt_bksp"
-
- find_legacy_keymap
-
- # layout not found, use KBLAYOUT
- if [[ -z "$X11_LAYOUT" ]]; then
- X11_LAYOUT="${keytable}"
- fi
+ # write X11 keyboard configuration using previously determined
+ # X11_LAYOUT, X11_MODEL, X11_VARIANT, X11_OPTIONS (from find_legacy_keymap)
+ # fall back to keytable if layout is empty
+ [[ -z "$X11_LAYOUT" ]] && X11_LAYOUT="${keytable}"
+ [[ -z "$X11_MODEL" ]] && X11_MODEL="pc105"
+ [[ -z "$X11_VARIANT" ]] && X11_VARIANT=""
+ [[ -z "$X11_OPTIONS" ]] && X11_OPTIONS="terminate:ctrl_alt_bksp"
- # create X11 keyboard layout config
mkdir -p "/etc/X11/xorg.conf.d"
-
local XORGKBLAYOUT="/etc/X11/xorg.conf.d/00-keyboard.conf"
echo "" >> "$XORGKBLAYOUT"
@@ -285,8 +276,16 @@ configure_language(){
echo "LANG=${lang}.UTF-8" > /etc/locale.conf
ln -sf /usr/share/zoneinfo/${timezone} /etc/localtime
+ # Determine X11 layout from keytable
+ find_legacy_keymap
+
write_x11_config
+ # Also set the keymap via localectl so that GNOME/KDE Wayland sessions pick it up
+ if command -v localectl >/dev/null 2>&1 && [[ -n "${X11_LAYOUT}" ]]; then
+ localectl set-x11-keymap "${X11_LAYOUT}" "${X11_MODEL}" "${X11_VARIANT}" "${X11_OPTIONS}"
+ fi
+
loadkeys "${keytable}"
locale-gen
manjaro-kde-26.1-testing-260804-linux618.iso boots to desktop with keyboard set as chosen in the GRUB menu - thank you!
USB media with GRUB2 and EFI and autoiso.cfg GRUB loopback booting ISO files on desktop PC with AMD Ryzen 5 3600 CPU and Radeon RX 590 graphics. In the ISOs GRUB boot menu I choose tz=Europe/Copenhagen and keytable=dk and leave lang=en_US and boot with open source drivers.
manjaro-kde-26.1-testing-260804-linux618.iso boots to desktop logged in as manjaro, and keyboard is DK both in Konsole on desktop and tty.