Skip to content

Instantly share code, notes, and snippets.

@yangxuan8282
Last active April 28, 2018 00:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yangxuan8282/774b68c33ebb9669d0b6e72a8d488f18 to your computer and use it in GitHub Desktop.
Save yangxuan8282/774b68c33ebb9669d0b6e72a8d488f18 to your computer and use it in GitHub Desktop.
linux install helper for xps13 9343 && rpi, works for USB stick, HDD and vmware, generate debian (pixel DE) and archlinux image, support BIOS/UEFI
#!/bin/sh
#genetate archlinux image: chmod +x gen-arch.sh && sudo ./gen-arch.sh
#depends: arch-install-scripts, vim(xxd)
set -eu
die() {
printf '\033[1;31mERROR:\033[0m %s\n' "$@" >&2 # bold red
exit 1
}
if [ "$(id -u)" -ne 0 ]; then
die 'This script must be run as root!'
fi
which xxd >/dev/null || exit
BUILD_DATE="$(date +%Y-%m-%d)"
usage() {
cat <<EOF
Usage: gen-arch.sh [options]
Valid options are:
-m ARCH_MIRROR URI of the mirror to fetch packages from
(default is https://mirrors.ustc.edu.cn/archlinux).
-u SUDO_USER The sudo user (default is arch).
-d DESKTOP_ENV Options: deepin, xfce4, xfce4-mods, gnome3,
kde, cinnamon, mate, none
(default is deepin)
-o OUTPUT_IMG Output img file
(default is BUILD_DATE-arch-DESKTOP_ENV.img).
-h Show this help message and exit.
EOF
}
while getopts 'm:u:d:o:h' OPTION; do
case "$OPTION" in
m) ARCH_MIRROR="$OPTARG";;
u) SUDO_USER="$OPTARG";;
d) DESKTOP_ENV="$OPTARG";;
o) OUTPUT="$OPTARG";;
h) usage; exit 0;;
esac
done
: ${ARCH_MIRROR:="https://mirrors.ustc.edu.cn/archlinux"}
: ${SUDO_USER:="arch"}
: ${DESKTOP_ENV:=}
: ${OUTPUT_IMG:="${BUILD_DATE}-arch-${DESKTOP_ENV}.img"}
#======================= F u n c t i o n s =======================#
gen_image() {
fallocate -l $(( 6 * 1024 * 1024 *1024 )) "$OUTPUT_IMG"
cat > fdisk.cmd <<-EOF
o
n
p
1
+500MB
t
c
a
n
p
2
w
EOF
fdisk "$OUTPUT_IMG" < fdisk.cmd
rm -f fdisk.cmd
}
do_format() {
mkfs.fat -F32 "$BOOT_DEV"
mkfs.ext4 "$ROOT_DEV"
mkdir -p mnt
mount "$ROOT_DEV" mnt
mkdir -p mnt/boot
mount "$BOOT_DEV" mnt/boot
}
setup_mirrors() {
sed -i "6i Server = ${ARCH_MIRROR}/\$repo/os/\$arch" /etc/pacman.d/mirrorlist
}
delete_mirrors() {
sed -i '6d' /etc/pacman.d/mirrorlist
}
do_pacstrap() {
pacstrap mnt base base-devel
}
gen_resize2fs_once_systemd() {
cat <<EOF
[Unit]
Description=Resize the root filesystem to fill partition
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-remount-fs.service
Before=systemd-sysusers.service sysinit.target shutdown.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/resize2fs_once
StandardOutput=tty
StandardInput=tty
StandardError=tty
[Install]
WantedBy=sysinit.target
EOF
}
gen_resize2fs_once_scripts() {
cat <<'EOF'
#!/bin/sh
set -xe
ROOT_DEV=$(findmnt / -o source -n)
cat > /tmp/fdisk.cmd <<-EOF
d
2
n
p
2
w
EOF
fdisk "$(echo "$ROOT_DEV" | sed -E 's/p?2$//')" < /tmp/fdisk.cmd
rm -f /tmp/fdisk.cmd
partprobe
resize2fs "$ROOT_DEV"
systemctl disable resize2fs-once
EOF
}
gen_fstabs() {
genfstab -U mnt >> mnt/etc/fstab
sed -i "/\/ /s/[^ ]* /PARTUUID=${ROOT_PARTUUID}/1" mnt/etc/fstab
sed -i "/\/boot /s/[^ ]* /PARTUUID=${BOOT_PARTUUID}/1" mnt/etc/fstab
sed -i 's/relatime/noatime/g' mnt/etc/fstab
}
gen_env() {
echo "LOOP_DEV=${LOOP_DEV}
SUDO_USER=${SUDO_USER}
DESKTOP_ENV=${DESKTOP_ENV}"
}
install_bootloader() {
pacman -S --noconfirm grub efibootmgr
grub-install --target=i386-pc --recheck --boot-directory /boot ${LOOP_DEV}
grub-install --target=x86_64-efi --efi-directory=/boot --boot-directory=/boot --removable
grub-mkconfig -o /boot/grub/grub.cfg
}
gen_initcpio() {
sed -i "/[^HOOKS]/s/HOOKS=.*/HOOKS=(base udev block autodetect modconf filesystems keyboard fsck)/g" /etc/mkinitcpio.conf
sed -i "/lz4/s/^#//" /etc/mkinitcpio.conf
mkinitcpio -p linux
}
add_sudo_user() {
useradd -m -G wheel -s /bin/bash "$SUDO_USER"
echo "${SUDO_USER}:archlinux" | chpasswd
echo "${SUDO_USER} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
pacman -S --noconfirm polkit
}
install_drivers() {
pacman -S --noconfirm xf86-video-ati xf86-video-intel xf86-video-nouveau xf86-video-vesa
pacman -S --noconfirm acpi linux-headers broadcom-wl-dkms xf86-input-libinput
}
config_touchpad() {
cat <<'EOF'
Section "InputClass"
Identifier "libinput touchpad catchall"
MatchIsTouchpad "on"
MatchDevicePath "/dev/input/event*"
Driver "libinput"
Option "Tapping" "on"
Option "ClickMethod" "clickfinger"
Option "NaturalScrolling" "true"
EndSection
EOF
}
install_yaourt() {
pacman -S --noconfirm git
su ${SUDO_USER} <<-EOF
mkdir -p /home/${SUDO_USER}/src
git clone https://aur.archlinux.org/package-query.git /home/${SUDO_USER}/src/package-query
cd /home/${SUDO_USER}/src/package-query
makepkg -si --noconfirm
git clone https://aur.archlinux.org/yaourt.git /home/${SUDO_USER}/src/yaourt
cd /home/${SUDO_USER}/src/yaourt
makepkg -si --noconfirm
echo "AURURL="https://aur.tuna.tsinghua.edu.cn"" | sudo tee --append /etc/yaourtrc
EOF
}
#install_extra() {
# pacman -S --noconfirm $EXTRA
#}
install_yay() {
pacman -S --noconfirm git wget
wget https://github.com/Jguer/yay/releases/download/v4.505/yay_4.505_x86_64.tar.gz -O - | tar -xz -C /usr/bin/ yay_4.505_x86_64/yay --strip=1
}
aur_install_packages() {
su ${SUDO_USER} <<-EOF
yay -S --noconfirm $@
EOF
}
install_de() {
case $DESKTOP_ENV in
deepin | dde) install_dde;;
xfce4) install_xfce4;;
xfce4-mods) install_xfce4_mods;;
gnome | gnome3) install_gnome;;
kde | plasma) install_kde;;
cinnamon) install_cinnamon;;
mate) install_mate;;
lite | none) echo 'Skip install desktop environment.';;
*) echo 'Choose deepin by default.' && install_dde;;
esac
}
install_sddm() {
pacman -S --noconfirm sddm
systemctl enable sddm.service
}
install_network_manager() {
pacman -S --noconfirm networkmanager
systemctl enable NetworkManager.service
}
install_dde() {
install_network_manager
pacman -S --noconfirm xorg xorg-server deepin deepin-terminal chromium htop
sed -i 's/#greeter-session=example-gtk-gnome/greeter-session=lightdm-deepin-greeter/' /etc/lightdm/lightdm.conf
systemctl enable lightdm.service
}
install_xfce4() {
pacman -S --noconfirm xorg-server xorg-xrefresh xfce4 xfce4-goodies \
xarchiver gvfs gvfs-smb sshfs \
ttf-roboto arc-gtk-theme \
blueman pulseaudio-bluetooth pavucontrol \
network-manager-applet gnome-keyring
systemctl disable dhcpcd
install_network_manager
install_sddm
}
install_xfce4_mods() {
install_xfce4
aur_install_packages paper-icon-theme-git
pacman -S --noconfirm curl
mkdir -p /usr/share/wallpapers
curl https://img2.goodfon.com/original/2048x1820/3/b6/android-5-0-lollipop-material-5355.jpg \
--output /usr/share/wallpapers/android-5-0-lollipop-material-5355.jpg
git clone https://github.com/yangxuan8282/dotfiles /home/${SUDO_USER}/src/dotfiles
cp -a /home/${SUDO_USER}/src/dotfiles/config /home/${SUDO_USER}/.config
chown -R ${SUDO_USER}:${SUDO_USER} /home/${SUDO_USER}/.config
rm -rf /home/${SUDO_USER}/src/dotfiles
}
install_gnome() {
pacman -S --noconfirm gnome
install_network_manager
install_sddm
}
install_kde() {
pacman -S --noconfirm xorg-server xorg-xrefresh \
plasma-meta plasma-wayland-session konsole chromium
install_network_manager
install_sddm
}
install_cinnamon() {
pacman -S --noconfirm cinnamon gnome-keyring
install_network_manager
install_sddm
}
install_mate() {
pacman -S --noconfirm mate mate-extra network-manager-applet gnome-keyring
install_network_manager
install_sddm
}
install_termite() {
pacman -S --noconfirm termite
aur_install_packages ttf-roboto-mono
mkdir -p /home/${SUDO_USER}/.config/termite
cp /etc/xdg/termite/config /home/${SUDO_USER}/.config/termite/config
sed -i 's/font = Monospace 9/font = RobotoMono 11/g' /home/${SUDO_USER}/.config/termite/config
chown -R ${SUDO_USER}:${SUDO_USER} /home/${SUDO_USER}/.config
}
install_docker() {
pacman -S --noconfirm docker docker-compose
gpasswd -a $SUDO_USER docker
systemctl enable docker
}
setup_miscs() {
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
hwclock --systohc
echo "en_US.UTF-8 UTF-8" | tee --append /etc/locale.gen
locale-gen
echo LANG=en_US.UTF-8 > /etc/locale.conf
echo xps13 > /etc/hostname
echo "127.0.1.1 xps13.localdomain xps13" | tee --append /etc/hosts
ln -sf /dev/null /etc/udev/rules.d/80-net-setup-link.rules
printf "Storage=volatile\nSystemMaxUse=16M\n" >> /etc/systemd/journald.conf
chmod +x /usr/local/bin/resize2fs_once
systemctl enable resize2fs-once
}
setup_chroot() {
arch-chroot mnt /bin/bash <<-EOF
set -xe
source /root/env_file
source /root/functions
rm -f /root/functions /root/env_file
gen_initcpio
pacman -Syu --noconfirm
pacman-key --init
pacman-key --populate archlinux
echo "root:toor" | chpasswd
add_sudo_user
setup_miscs
install_docker
#install_yaourt
install_yay
install_drivers
mkdir -p /etc/X11/xorg.conf.d
config_touchpad > /etc/X11/xorg.conf.d/40-libinput.conf
install_termite
install_de
install_bootloader
EOF
}
umounts() {
umount mnt/boot
umount mnt
losetup -d "$LOOP_DEV"
}
#======================= F u n c t i o n s =======================#
pass_function() {
sed -nE '/^#===.*F u n c t i o n s.*===#/,/^#===.*F u n c t i o n s.*===#/p' "$0"
}
gen_image
LOOP_DEV=$(losetup --partscan --show --find "${OUTPUT_IMG}")
BOOT_DEV="$LOOP_DEV"p1
ROOT_DEV="$LOOP_DEV"p2
do_format
setup_mirrors
do_pacstrap
IMGID="$(dd if="${OUTPUT_IMG}" skip=440 bs=1 count=4 2>/dev/null | xxd -e | cut -f 2 -d' ')"
BOOT_PARTUUID="${IMGID}-01"
ROOT_PARTUUID="${IMGID}-02"
gen_resize2fs_once_systemd > mnt/etc/systemd/system/resize2fs-once.service
gen_resize2fs_once_scripts > mnt/usr/local/bin/resize2fs_once
gen_fstabs
gen_env > mnt/root/env_file
pass_function > mnt/root/functions
setup_chroot
umounts
delete_mirrors
cat >&2 <<-EOF
---
Installation is complete
Flash to usb disk with: dd if=${OUTPUT_IMG} of=/dev/TARGET_DEV bs=4M status=progress
EOF
#!/bin/sh
#genetate archlinux arm rpi image: chmod +x gen-arch.sh && sudo ./gen-arch.sh -d xfce4-mods
#depends: arch-install-scripts, vim(xxd)
set -xe
die() {
printf '\033[1;31mERROR:\033[0m %s\n' "$@" >&2 # bold red
exit 1
}
if [ "$(id -u)" -ne 0 ]; then
die 'This script must be run as root!'
fi
which xxd >/dev/null || exit
BUILD_DATE="$(date +%Y-%m-%d)"
usage() {
cat <<EOF
Usage: gen-arch.sh [options]
Valid options are:
-m ARCH_MIRROR URI of the mirror to fetch packages from
(default is https://mirrors.ustc.edu.cn/archlinuxarm).
-u SUDO_USER The sudo user (default is alarm).
-d DESKTOP_ENV Options: xfce4, xfce4-mods, mate, none
(default is xfce4-mods)
-o OUTPUT_IMG Output img file
(default is BUILD_DATE-arch-rpi-DESKTOP_ENV.img).
-h Show this help message and exit.
EOF
}
while getopts 'm:u:d:o:h' OPTION; do
case "$OPTION" in
m) ARCH_MIRROR="$OPTARG";;
u) SUDO_USER="$OPTARG";;
d) DESKTOP_ENV="$OPTARG";;
o) OUTPUT="$OPTARG";;
h) usage; exit 0;;
esac
done
: ${ARCH_MIRROR:="https://mirrors.ustc.edu.cn/archlinuxarm"}
: ${SUDO_USER:="alarm"}
: ${DESKTOP_ENV:=}
: ${OUTPUT_IMG:="${BUILD_DATE}-arch-rpi-${DESKTOP_ENV}.img"}
#======================= F u n c t i o n s =======================#
gen_image() {
fallocate -l $(( 4 * 1024 * 1024 *1024 )) "$OUTPUT_IMG"
cat > fdisk.cmd <<-EOF
o
n
p
1
+100MB
t
c
n
p
2
w
EOF
fdisk "$OUTPUT_IMG" < fdisk.cmd
rm -f fdisk.cmd
}
do_format() {
mkfs.fat -F32 "$BOOT_DEV"
mkfs.ext4 "$ROOT_DEV"
mkdir -p mnt
mount "$ROOT_DEV" mnt
mkdir -p mnt/boot
mount "$BOOT_DEV" mnt/boot
}
setup_mirrors() {
sed -i "5i Server = ${ARCH_MIRROR}/\$arch/\$repo" /etc/pacman.d/mirrorlist
}
delete_mirrors() {
sed -i '5d' /etc/pacman.d/mirrorlist
}
do_pacstrap() {
pacstrap mnt base base-devel
}
gen_resize2fs_once_systemd() {
cat <<EOF
[Unit]
Description=Resize the root filesystem to fill partition
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-remount-fs.service
Before=systemd-sysusers.service sysinit.target shutdown.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/resize2fs_once
StandardOutput=tty
StandardInput=tty
StandardError=tty
[Install]
WantedBy=sysinit.target
EOF
}
gen_resize2fs_once_scripts() {
cat <<'EOF'
#!/bin/sh
set -xe
ROOT_DEV=$(findmnt / -o source -n)
cat > /tmp/fdisk.cmd <<-EOF
d
2
n
p
2
w
EOF
fdisk "$(echo "$ROOT_DEV" | sed -E 's/p?2$//')" < /tmp/fdisk.cmd
rm -f /tmp/fdisk.cmd
partprobe
resize2fs "$ROOT_DEV"
systemctl disable resize2fs-once
EOF
}
gen_fstabs() {
genfstab -U mnt >> mnt/etc/fstab
sed -i "/\/ /s/[^ ]* /PARTUUID=${ROOT_PARTUUID}/1" mnt/etc/fstab
sed -i "/\/boot /s/[^ ]* /PARTUUID=${BOOT_PARTUUID}/1" mnt/etc/fstab
sed -i 's/relatime/noatime/g' mnt/etc/fstab
}
gen_env() {
echo "LOOP_DEV=${LOOP_DEV}
SUDO_USER=${SUDO_USER}
DESKTOP_ENV=${DESKTOP_ENV}"
}
install_bootloader() {
pacman -S --noconfirm raspberrypi-bootloader raspberrypi-bootloader-x
}
add_sudo_user() {
useradd -m -G wheel -s /bin/bash "$SUDO_USER"
echo "${SUDO_USER}:alarm" | chpasswd
echo "${SUDO_USER} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
pacman -S --noconfirm polkit
}
install_kernel() {
pacman -S --noconfirm linux-raspberrypi
}
enable_systemd_timesyncd() {
systemctl enable systemd-timesyncd.service
}
add_vchiq_udev_rules() {
cat <<'EOF'
SUBSYSTEM=="vchiq|input", MODE="0777"
KERNEL=="mouse*|mice|event*", MODE="0777"
EOF
}
aur_install_packages() {
su ${SUDO_USER} <<-EOF
packer -S --noconfirm $@
EOF
}
install_drivers() {
pacman -S --noconfirm raspberrypi-firmware firmware-raspberrypi xf86-video-fbdev
aur_install_packages pi-bluetooth
}
install_de() {
case $DESKTOP_ENV in
xfce4) install_xfce4;;
xfce4-mods) install_xfce4_mods;;
mate) install_mate;;
lite | none) echo 'Skip install desktop environment.';;
*) echo 'Choose deepin by default.' && install_xfce4_mods;;
esac
}
install_sddm() {
pacman -S --noconfirm sddm
systemctl enable sddm.service
}
install_network_manager() {
pacman -S --noconfirm networkmanager
systemctl enable NetworkManager.service
}
install_ssh_server() {
pacman -S --noconfirm openssh
systemctl enable sshd
}
install_browser() {
pacman -S --noconfirm chromium
}
install_xfce4() {
pacman -S --noconfirm git xorg-server xorg-xrefresh xfce4 xfce4-goodies \
xarchiver gvfs gvfs-smb sshfs \
ttf-roboto arc-gtk-theme \
blueman pulseaudio-bluetooth pavucontrol \
network-manager-applet gnome-keyring
systemctl disable dhcpcd
install_network_manager
install_sddm
systemctl enable bluetooth brcm43438
}
install_xfce4_mods() {
install_xfce4
aur_install_packages paper-icon-theme
pacman -S --noconfirm curl
mkdir -p /usr/share/wallpapers
curl https://img2.goodfon.com/original/2048x1820/3/b6/android-5-0-lollipop-material-5355.jpg \
--output /usr/share/wallpapers/android-5-0-lollipop-material-5355.jpg
git clone https://github.com/yangxuan8282/dotfiles /home/${SUDO_USER}/src/dotfiles
cp -a /home/${SUDO_USER}/src/dotfiles/config /home/${SUDO_USER}/.config
chown -R ${SUDO_USER}:${SUDO_USER} /home/${SUDO_USER}/.config
rm -rf /home/${SUDO_USER}/src/dotfiles
}
install_mate() {
pacman -S --noconfirm mate mate-extra network-manager-applet gnome-keyring
install_network_manager
install_sddm
}
install_termite() {
pacman -S --noconfirm termite
aur_install_packages ttf-roboto-mono
mkdir -p /home/${SUDO_USER}/.config/termite
cp /etc/xdg/termite/config /home/${SUDO_USER}/.config/termite/config
sed -i 's/font = Monospace 9/font = RobotoMono 11/g' /home/${SUDO_USER}/.config/termite/config
chown -R ${SUDO_USER}:${SUDO_USER} /home/${SUDO_USER}/.config
}
install_docker() {
pacman -S --noconfirm docker docker-compose
gpasswd -a $SUDO_USER docker
systemctl enable docker
}
setup_miscs() {
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
echo "en_US.UTF-8 UTF-8" | tee --append /etc/locale.gen
locale-gen
echo LANG=en_US.UTF-8 > /etc/locale.conf
echo alarm > /etc/hostname
echo "127.0.1.1 alarm.localdomain alarm" | tee --append /etc/hosts
chmod +x /usr/local/bin/resize2fs_once
systemctl enable resize2fs-once
}
setup_chroot() {
arch-chroot mnt /bin/bash <<-EOF
set -xe
source /root/env_file
source /root/functions
rm -f /root/functions /root/env_file
pacman -Syu --noconfirm
pacman -S --noconfirm archlinuxarm-keyring
pacman-key --init
pacman-key --populate archlinuxarm
echo "root:toor" | chpasswd
add_sudo_user
install_kernel
setup_miscs
install_docker
enable_systemd_timesyncd
pacman -S --noconfirm packer
install_drivers
add_vchiq_udev_rules > /etc/udev/rules.d/raspberrypi.rules
install_ssh_server
install_termite
install_de
install_browser
install_bootloader
EOF
}
umounts() {
umount mnt/boot
umount mnt
losetup -d "$LOOP_DEV"
}
#======================= F u n c t i o n s =======================#
pass_function() {
sed -nE '/^#===.*F u n c t i o n s.*===#/,/^#===.*F u n c t i o n s.*===#/p' "$0"
}
gen_image
LOOP_DEV=$(losetup --partscan --show --find "${OUTPUT_IMG}")
BOOT_DEV="$LOOP_DEV"p1
ROOT_DEV="$LOOP_DEV"p2
do_format
setup_mirrors
do_pacstrap
IMGID="$(dd if="${OUTPUT_IMG}" skip=440 bs=1 count=4 2>/dev/null | xxd -e | cut -f 2 -d' ')"
BOOT_PARTUUID="${IMGID}-01"
ROOT_PARTUUID="${IMGID}-02"
gen_resize2fs_once_systemd > mnt/etc/systemd/system/resize2fs-once.service
gen_resize2fs_once_scripts > mnt/usr/local/bin/resize2fs_once
gen_fstabs
gen_env > mnt/root/env_file
pass_function > mnt/root/functions
setup_chroot
umounts
delete_mirrors
cat >&2 <<-EOF
---
Installation is complete
Flash to usb disk with: dd if=${OUTPUT_IMG} of=/dev/TARGET_DEV bs=4M status=progress
EOF
#!/bin/sh
#genetate pixel [i386/amd64] image: chmod +x gen-pixel.sh && sudo ./gen-pixel.sh
#resize with: sudo fdisk /dev/sdX; (d,2,n,p,2,ENTER,ENTER,w); sudo reboot; sudo resize2fs /dev/sdX2
#depends: dosfstools debootstrap
set -eu
die() {
printf '\033[1;31mERROR:\033[0m %s\n' "$@" >&2 # bold red
exit 1
}
if [ "$(id -u)" -ne 0 ]; then
die 'This script must be run as root!'
fi
export DEBIAN_FRONTEND=noninteractive
BUILD_DATE="$(date +%Y-%m-%d)"
usage() {
cat <<EOF
Usage: gen-pixel.sh [options]
Valid options are:
-a ARCH Options: i386, amd64 (default is amd64).
-b DEBIAN_BRANCH Debian branch to install (default is stretch).
-m DEBIAN_MIRROR URI of the mirror to fetch packages from
(default is http://mirrors.ustc.edu.cn/debian/).
-u SUDO_USER The sudo user (default is pi).
-o OUTPUT_IMG Output img file
(default is BUILD_DATE-pixel-ARCH-DEBIAN_BRANCH.img).
-h Show this help message and exit.
EOF
}
while getopts 'a:b:m:u:o:h' OPTION; do
case "$OPTION" in
a) ARCH="$OPTARG";;
b) DEBIAN_BRANCH="$OPTARG";;
m) DEBIAN_MIRROR="$OPTARG";;
u) SUDO_USER="$OPTARG";;
o) OUTPUT="$OPTARG";;
h) usage; exit 0;;
esac
done
: ${DEBIAN_BRANCH:="stretch"}
: ${DEBIAN_MIRROR:="http://mirrors.ustc.edu.cn/debian/"}
: ${ARCH:="amd64"}
: ${SUDO_USER:="pi"}
: ${OUTPUT_IMG:="${BUILD_DATE}-pixel-${ARCH}-${DEBIAN_BRANCH}.img"}
get_kernel_suffix() {
case "$1" in
i386) echo '686-pae';;
amd64) echo 'amd64';;
*) echo "$1";;
esac
}
_ARCH="$(get_kernel_suffix $ARCH)"
gen_image() {
fallocate -l $(( 4 * 1024 * 1024 *1024 )) "$OUTPUT_IMG"
cat > fdisk.cmd <<-EOF
o
n
p
1
+500MB
t
c
a
n
p
2
w
EOF
fdisk "$OUTPUT_IMG" < fdisk.cmd
rm -f fdisk.cmd
}
do_format() {
mkfs.fat -F32 "$BOOT_DEV"
mkfs.ext4 "$ROOT_DEV"
mkdir -p mnt
mount "$ROOT_DEV" mnt
mkdir -p mnt/boot
mount "$BOOT_DEV" mnt/boot
}
do_debootstrap() {
debootstrap --arch="$ARCH" "$DEBIAN_BRANCH" mnt "$DEBIAN_MIRROR"
}
gen_wpa_supplicant_conf() {
cat <<EOF
country=CN
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
EOF
}
gen_sources_list() {
cat <<EOF
deb "$DEBIAN_MIRROR" "$DEBIAN_BRANCH" main contrib non-free
deb http://security.debian.org/ "$DEBIAN_BRANCH"/updates main contrib non-free
deb "$DEBIAN_MIRROR" "$DEBIAN_BRANCH"-updates main contrib non-free
#deb-src "$DEBIAN_MIRROR" "$DEBIAN_BRANCH" main contrib non-free
#deb-src http://security.debian.org/ "$DEBIAN_BRANCH"/updates main contrib non-free
#deb-src "$DEBIAN_MIRROR" "$DEBIAN_BRANCH"-updates main contrib non-free
EOF
}
gen_keyboard_layout() {
cat <<EOF
# KEYBOARD CONFIGURATION FILE
# Consult the keyboard(5) manual page.
XKBMODEL="pc105"
XKBLAYOUT="us"
XKBVARIANT=""
XKBOPTIONS=""
BACKSPACE="guess"
EOF
}
gen_fstabs() {
echo "PARTUUID=${BOOT_PARTUUID} /boot vfat defaults 0 2
PARTUUID=${ROOT_PARTUUID} / ext4 defaults,noatime 0 1"
}
gen_env() {
echo "LOOP_DEV=${LOOP_DEV}
export DEBIAN_FRONTEND=noninteractive
SUDO_USER=${SUDO_USER}
_ARCH=${_ARCH}
DEBIAN_BRANCH=${DEBIAN_BRANCH}"
}
setup_chroot() {
chroot mnt /bin/bash <<-EOF
set -xe
source /root/env_file
rm -f /root/env_file
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
apt-get update && apt-get install -y locales
echo "en_US.UTF-8 UTF-8" | tee --append /etc/locale.gen
locale-gen
echo raspberrypi > /etc/hostname
echo "127.0.1.1 raspberrypi.localdomain raspberrypi" | tee --append /etc/hosts
apt-get install -y dirmngr
echo "deb http://mirrors.ustc.edu.cn/archive.raspberrypi.org/debian/ ${DEBIAN_BRANCH} main ui" | tee /etc/apt/sources.list.d/raspi.list
apt-key adv --keyserver keyserver.ubuntu.com --recv 82B129927FA3303E
apt-get update && apt-get upgrade -y
apt-get install -y linux-image-"$_ARCH" systemd-sysv grub2-common grub-pc grub-efi-amd64-bin efibootmgr
apt-get install -y dhcpcd5 wpasupplicant
mv /etc/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant.conf
apt-get install -y libfm-modules raspberrypi-ui-mods lxterminal rpi-chromium-mods rc-gui raspi-config
apt-get install -y broadcom-sta-dkms fcitx-pinyin fonts-droid-fallback bash-completion nano htop geany firmware-intel-sound
useradd -g sudo -ms /bin/bash "$SUDO_USER"
usermod -g netdev "$SUDO_USER"
systemctl set-default graphical.target
ln -fs /etc/systemd/system/autologin@.service /etc/systemd/system/getty.target.wants/getty@tty1.service
sed /etc/lightdm/lightdm.conf -i -e "s/^\(#\|\)autologin-user=.*/autologin-user="$SUDO_USER"/"
systemctl enable dhcpcd.service
echo "${SUDO_USER}:raspberry" | chpasswd
echo "${SUDO_USER} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
sed -i 's/#force_color_prompt=yes/force_color_prompt=yes/g' /home/"$SUDO_USER"/.bashrc
grub-install --target=i386-pc --recheck --boot-directory /boot ${LOOP_DEV}
grub-install --target=x86_64-efi --efi-directory=/boot --boot-directory=/boot --removable
grub-mkconfig -o /boot/grub/grub.cfg
rm -rf /var/lib/apt/lists/*
EOF
}
mounts() {
mount -t proc /proc mnt/proc
mount -t sysfs /sys mnt/sys
mount -o bind /dev mnt/dev
}
umounts() {
umount mnt/dev
umount mnt/sys
umount mnt/proc
umount mnt/boot
umount mnt
losetup -d "$LOOP_DEV"
}
gen_image
LOOP_DEV=$(losetup --partscan --show --find "${OUTPUT_IMG}")
BOOT_DEV="$LOOP_DEV"p1
ROOT_DEV="$LOOP_DEV"p2
do_format
do_debootstrap
gen_wpa_supplicant_conf > mnt/etc/wpa_supplicant.conf
gen_sources_list > mnt/etc/apt/sources.list
gen_keyboard_layout > mnt/etc/default/keyboard
IMGID="$(dd if="${OUTPUT_IMG}" skip=440 bs=1 count=4 2>/dev/null | xxd -e | cut -f 2 -d' ')"
BOOT_PARTUUID="${IMGID}-01"
ROOT_PARTUUID="${IMGID}-02"
gen_fstabs > mnt/etc/fstab
gen_env > mnt/root/env_file
mounts
setup_chroot
umounts
cat >&2 <<-EOF
---
Installation is complete
Flash to usb disk with: dd if=${OUTPUT_IMG} of=/dev/TARGET_DEV bs=4M status=progress
EOF
#!/bin/sh
#genetate pixel [rpi] image: chmod +x gen-pixel.sh && sudo ./gen-pixel.sh
#depends: dosfstools debootstrap
set -eu
die() {
printf '\033[1;31mERROR:\033[0m %s\n' "$@" >&2 # bold red
exit 1
}
if [ "$(id -u)" -ne 0 ]; then
die 'This script must be run as root!'
fi
export DEBIAN_FRONTEND=noninteractive
BUILD_DATE="$(date +%Y-%m-%d)"
usage() {
cat <<EOF
Usage: gen-pixel.sh [options]
Valid options are:
-b DEBIAN_BRANCH Debian branch to install (default is stretch).
-m DEBIAN_MIRROR URI of the mirror to fetch packages from
(default is http://mirrors.ustc.edu.cn/debian/).
-u SUDO_USER The sudo user (default is pi).
-o OUTPUT_IMG Output img file
(default is BUILD_DATE-pixel-rpi-ARCH-DEBIAN_BRANCH.img).
-h Show this help message and exit.
EOF
}
while getopts 'b:m:u:o:h' OPTION; do
case "$OPTION" in
b) DEBIAN_BRANCH="$OPTARG";;
m) DEBIAN_MIRROR="$OPTARG";;
u) SUDO_USER="$OPTARG";;
o) OUTPUT="$OPTARG";;
h) usage; exit 0;;
esac
done
: ${DEBIAN_BRANCH:="stretch"}
: ${DEBIAN_MIRROR:="http://mirrors.ustc.edu.cn/debian/"}
: ${SUDO_USER:="pi"}
: ${OUTPUT_IMG:="${BUILD_DATE}-pixel-rpi-${DEBIAN_BRANCH}.img"}
#======================= F u n c t i o n s =======================#
gen_image() {
fallocate -l $(( 3 * 1024 * 1024 *1024 )) "$OUTPUT_IMG"
cat > fdisk.cmd <<-EOF
o
n
p
1
+100MB
t
c
a
n
p
2
w
EOF
fdisk "$OUTPUT_IMG" < fdisk.cmd
rm -f fdisk.cmd
}
do_format() {
mkfs.fat -F32 "$BOOT_DEV"
mkfs.ext4 "$ROOT_DEV"
mkdir -p mnt
mount "$ROOT_DEV" mnt
mkdir -p mnt/boot
mount "$BOOT_DEV" mnt/boot
}
do_debootstrap() {
debootstrap --arch="armhf" "$DEBIAN_BRANCH" mnt "$DEBIAN_MIRROR"
}
gen_wpa_supplicant_conf() {
cat <<EOF
country=CN
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
EOF
}
gen_keyboard_layout() {
cat <<EOF
# KEYBOARD CONFIGURATION FILE
# Consult the keyboard(5) manual page.
XKBMODEL="pc105"
XKBLAYOUT="us"
XKBVARIANT=""
XKBOPTIONS=""
BACKSPACE="guess"
EOF
}
gen_fstabs() {
echo "PARTUUID=${BOOT_PARTUUID} /boot vfat defaults 0 2
PARTUUID=${ROOT_PARTUUID} / ext4 defaults,noatime 0 1"
}
add_user_groups() {
for USER_GROUP in input spi i2c gpio; do
groupadd -f -r $USER_GROUP
done
for USER_GROUP in adm dialout cdrom audio users sudo video games plugdev input gpio spi i2c netdev; do
adduser pi $USER_GROUP
done
}
gen_resize2fs_once_scripts() {
cat <<'EOF'
#!/bin/sh
### BEGIN INIT INFO
# Provides: resize2fs_once
# Required-Start:
# Required-Stop:
# Default-Start: 3
# Default-Stop:
# Short-Description: Resize the root filesystem to fill partition
# Description:
### END INIT INFO
. /lib/lsb/init-functions
case "$1" in
start)
log_daemon_msg "Starting resize2fs_once"
ROOT_DEV=$(findmnt / -o source -n) &&
resize2fs $ROOT_DEV &&
update-rc.d resize2fs_once remove &&
rm /etc/init.d/resize2fs_once &&
log_end_msg $?
;;
*)
echo "Usage: $0 start" >&2
exit 3
;;
esac
EOF
}
gen_cmdline_txt() {
cat <<EOF
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=${ROOT_PARTUUID} rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet init=/usr/lib/raspi-config/init_resize.sh
EOF
}
gen_env() {
echo "LOOP_DEV=${LOOP_DEV}
export DEBIAN_FRONTEND=noninteractive
SUDO_USER=${SUDO_USER}
DEBIAN_BRANCH=${DEBIAN_BRANCH}"
}
setup_chroot() {
chroot mnt /bin/bash <<-EOF
set -xe
source /root/env_file
source /root/functions
rm -f /root/env_file /root/functions
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
apt-get update && apt-get install -y locales
echo "en_US.UTF-8 UTF-8" | tee --append /etc/locale.gen
locale-gen
echo raspberrypi > /etc/hostname
echo "127.0.1.1 raspberrypi.localdomain raspberrypi" | tee --append /etc/hosts
apt-get install -y dirmngr
echo "deb http://mirrors.ustc.edu.cn/raspbian/raspbian/ ${DEBIAN_BRANCH} main contrib non-free rpi" > /etc/apt/sources.list
echo "deb http://mirrors.ustc.edu.cn/archive.raspberrypi.org/debian/ ${DEBIAN_BRANCH} main ui" > /etc/apt/sources.list.d/raspi.list
apt-key adv --keyserver keyserver.ubuntu.com --recv 9165938D90FDDD2E
apt-key adv --keyserver keyserver.ubuntu.com --recv 82B129927FA3303E
apt-get update && apt-get upgrade -y
apt-get install -y ssh
apt-get install -y dhcpcd5 wpasupplicant net-tools wireless-tools firmware-atheros firmware-brcm80211 firmware-libertas firmware-misc-nonfree firmware-realtek raspberrypi-net-mods
apt-get install -y raspberrypi-ui-mods lxterminal rpi-chromium-mods rc-gui raspi-config omxplayer fake-hwclock htop screen geany fcitx-pinyin fonts-wqy-zenhei
mv /etc/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant.conf
sed -i '7s|^.*$| PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games"|' /etc/profile
useradd -g sudo -ms /bin/bash "$SUDO_USER"
add_user_groups
systemctl set-default graphical.target
ln -fs /etc/systemd/system/autologin@.service /etc/systemd/system/getty.target.wants/getty@tty1.service
sed /etc/lightdm/lightdm.conf -i -e "s/^\(#\|\)autologin-user=.*/autologin-user="$SUDO_USER"/"
systemctl enable dhcpcd.service
echo "${SUDO_USER}:raspberry" | chpasswd
echo "${SUDO_USER} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
sed -i 's/#force_color_prompt=yes/force_color_prompt=yes/g' /home/"$SUDO_USER"/.bashrc
gen_resize2fs_once_scripts > /etc/init.d/resize2fs_once
chmod +x /etc/init.d/resize2fs_once
systemctl enable resize2fs_once
echo "dtparam=audio=yes" > /boot/config.txt
rm -rf /var/lib/apt/lists/*
EOF
}
mounts() {
mount -t proc /proc mnt/proc
mount -t sysfs /sys mnt/sys
mount -o bind /dev mnt/dev
}
umounts() {
umount mnt/dev
umount mnt/sys
umount mnt/proc
umount mnt/boot
umount mnt
losetup -d "$LOOP_DEV"
}
#======================= F u n c t i o n s =======================#
pass_function() {
sed -nE '/^#===.*F u n c t i o n s.*===#/,/^#===.*F u n c t i o n s.*===#/p' "$0"
}
gen_image
LOOP_DEV=$(losetup --partscan --show --find "${OUTPUT_IMG}")
BOOT_DEV="$LOOP_DEV"p1
ROOT_DEV="$LOOP_DEV"p2
do_format
do_debootstrap
gen_wpa_supplicant_conf > mnt/etc/wpa_supplicant.conf
gen_keyboard_layout > mnt/etc/default/keyboard
IMGID="$(dd if="${OUTPUT_IMG}" skip=440 bs=1 count=4 2>/dev/null | xxd -e | cut -f 2 -d' ')"
BOOT_PARTUUID="${IMGID}-01"
ROOT_PARTUUID="${IMGID}-02"
gen_fstabs > mnt/etc/fstab
gen_cmdline_txt > mnt/boot/cmdline.txt
gen_env > mnt/root/env_file
pass_function > mnt/root/functions
mounts
setup_chroot
umounts
cat >&2 <<-EOF
---
Installation is complete
Flash to usb disk with: dd if=${OUTPUT_IMG} of=/dev/TARGET_DEV bs=4M status=progress
EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment