mirror of
git://soft.sys114.com/odroid-stamper
synced 2025-12-19 00:18:42 +09:00
The first commit for the script tool 'ODROID-STAMPER'
Signed-off-by: Dongjin Kim <tobetter@gmail.com>
This commit is contained in:
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
.gitignore
|
||||
*.swp
|
||||
*.md5sum
|
||||
|
||||
downloads/
|
||||
rootfs/
|
||||
out/
|
||||
@@ -1 +1,8 @@
|
||||
# odroid-stamper
|
||||
# ODROID-STAMPER
|
||||
|
||||
**ODROID-STAMPER** is a shell script tool to generate Ubuntu OS image for ODROID SBCs, currently it only support ODROID-XU4 and ODROID-N2.
|
||||
|
||||
$ sudo apt install git wget dialog pv lynx
|
||||
$ git clone https://github.com/tobetter/odroid-stamper.git
|
||||
$ cd odroid-stamper
|
||||
$ sudo ./odroid-stamper
|
||||
|
||||
19
boards/odroidc2/functions
Normal file
19
boards/odroidc2/functions
Normal file
@@ -0,0 +1,19 @@
|
||||
get_machine_name() {
|
||||
echo "Hardkernel ODROID-C2"
|
||||
}
|
||||
|
||||
get_kernel_package() {
|
||||
echo "linux-image-odroid-upstream"
|
||||
}
|
||||
|
||||
get_bootscript_package() {
|
||||
echo ""
|
||||
}
|
||||
|
||||
get_reserved_sectors() {
|
||||
echo 2048
|
||||
}
|
||||
|
||||
download_uboot() {
|
||||
return false
|
||||
}
|
||||
2
boards/odroidc2/packages
Normal file
2
boards/odroidc2/packages
Normal file
@@ -0,0 +1,2 @@
|
||||
flash-kernel
|
||||
openssh-server
|
||||
22
boards/odroidn2/functions
Normal file
22
boards/odroidn2/functions
Normal file
@@ -0,0 +1,22 @@
|
||||
get_machine_name() {
|
||||
echo "Hardkernel ODROID-N2"
|
||||
}
|
||||
|
||||
get_kernel_package() {
|
||||
echo "linux-image-odroidn2"
|
||||
}
|
||||
|
||||
get_bootscript_package() {
|
||||
echo "bootscript-odroidn2"
|
||||
}
|
||||
|
||||
get_reserved_sectors() {
|
||||
echo 2048
|
||||
}
|
||||
|
||||
download_uboot() {
|
||||
url="https://api.github.com/repos/hardkernel/u-boot/releases"
|
||||
curl -s ${url} | grep odroidn2 \
|
||||
| grep browser_download_url | cut -d'"' -f 4 | head -1 \
|
||||
| wget -O ${1} -qi -
|
||||
}
|
||||
1
boards/odroidn2/packages
Normal file
1
boards/odroidn2/packages
Normal file
@@ -0,0 +1 @@
|
||||
openssh-server
|
||||
22
boards/odroidxu4/functions
Normal file
22
boards/odroidxu4/functions
Normal file
@@ -0,0 +1,22 @@
|
||||
get_machine_name() {
|
||||
echo "Hardkernel Odroid XU4"
|
||||
}
|
||||
|
||||
get_kernel_package() {
|
||||
echo "linux-image-odroid-memeka"
|
||||
}
|
||||
|
||||
get_bootscript_package() {
|
||||
echo "bootscript-odroid-exynos5422"
|
||||
}
|
||||
|
||||
get_reserved_sectors() {
|
||||
echo 3072
|
||||
}
|
||||
|
||||
download_uboot() {
|
||||
url="https://api.github.com/repos/tobetter/u-boot/releases"
|
||||
curl -s ${url} | grep odroid-xu3 \
|
||||
| grep browser_download_url | cut -d'"' -f 4 | head -1 \
|
||||
| wget -O ${1} -qi -
|
||||
}
|
||||
3
boards/odroidxu4/packages
Normal file
3
boards/odroidxu4/packages
Normal file
@@ -0,0 +1,3 @@
|
||||
flash-kernel
|
||||
u-boot-exynos
|
||||
openssh-server
|
||||
1
configs/bionic-gnome-desktop
Normal file
1
configs/bionic-gnome-desktop
Normal file
@@ -0,0 +1 @@
|
||||
EXTRA_SPACE=1024
|
||||
1
configs/bionic-mate-desktop
Normal file
1
configs/bionic-mate-desktop
Normal file
@@ -0,0 +1 @@
|
||||
EXTRA_SPACE=1024
|
||||
1
configs/bionic-minimal
Normal file
1
configs/bionic-minimal
Normal file
@@ -0,0 +1 @@
|
||||
EXTRA_SPACE=600
|
||||
1
configs/bionic-xfce4-desktop
Normal file
1
configs/bionic-xfce4-desktop
Normal file
@@ -0,0 +1 @@
|
||||
EXTRA_SPACE=1024
|
||||
1
configs/disco-gnome-desktop
Normal file
1
configs/disco-gnome-desktop
Normal file
@@ -0,0 +1 @@
|
||||
EXTRA_SPACE=1024
|
||||
1
configs/disco-mate-desktop
Normal file
1
configs/disco-mate-desktop
Normal file
@@ -0,0 +1 @@
|
||||
EXTRA_SPACE=1024
|
||||
1
configs/disco-minimal
Normal file
1
configs/disco-minimal
Normal file
@@ -0,0 +1 @@
|
||||
EXTRA_SPACE=600
|
||||
1
configs/disco-xfce4-desktop
Normal file
1
configs/disco-xfce4-desktop
Normal file
@@ -0,0 +1 @@
|
||||
EXTRA_SPACE=1024
|
||||
5
debian/changelog
vendored
Normal file
5
debian/changelog
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
odroid-stamper (0.1) experimental; urgency=medium
|
||||
|
||||
* Initial release.
|
||||
|
||||
-- Dongjin Kim <tobetter@gmail.com> Wed, 30 Oct 2019 01:38:29 +0900
|
||||
1
debian/compat
vendored
Normal file
1
debian/compat
vendored
Normal file
@@ -0,0 +1 @@
|
||||
9
|
||||
19
debian/control
vendored
Normal file
19
debian/control
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Source: odroid-stamper
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Maintainer: Dongjin Kim <tobettter@gmail.com>
|
||||
Uploaders: Dongjin Kim <tobetter@gmail.com>
|
||||
Build-Depends: debhelper (>= 9), dash
|
||||
Standards-Version: 3.9.6
|
||||
Vcs-Browser:
|
||||
Vcs-Git:
|
||||
Rules-Requires-Root: no
|
||||
|
||||
Package: odroid-stamper
|
||||
Architecture: any
|
||||
Depends: lynx, dialog, pv
|
||||
Description: Utility to create or install a OS to a storage
|
||||
The odroid-stamper is a script that will help to create an OS image with
|
||||
update packages or install to a memory card on ODROID single board computer
|
||||
itself that does not necessary to download and fusing an OS image with a
|
||||
desktop.
|
||||
6
debian/copyright
vendored
Normal file
6
debian/copyright
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
odroid-stamper is written by Dongjin Kim <tobetter@gmail.com>
|
||||
|
||||
This package is under the GNU General Public License, version 2, which
|
||||
can usually be found in /usr/share/common-licenses/GPL-2 on Debian
|
||||
systems.
|
||||
7
debian/odroid-stamper.install
vendored
Normal file
7
debian/odroid-stamper.install
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
odroid-stamper usr/sbin/
|
||||
functions usr/share/odroid-stamper
|
||||
menu usr/share/odroid-stamper
|
||||
boards usr/share/odroid-stamper
|
||||
default usr/share/odroid-stamper
|
||||
configs usr/share/odroid-stamper
|
||||
fixups usr/share/odroid-stamper
|
||||
4
debian/rules
vendored
Executable file
4
debian/rules
vendored
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
%:
|
||||
dh $@
|
||||
73
default
Normal file
73
default
Normal file
@@ -0,0 +1,73 @@
|
||||
get_board() {
|
||||
if [ -f /proc/device-tree/model ]; then
|
||||
model=$(cat /proc/device-tree/model)
|
||||
case ${model} in
|
||||
"Hardkernel ODROID-N2")
|
||||
echo "odroidn2"
|
||||
;;
|
||||
*)
|
||||
echo ""
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
get_arch() {
|
||||
case ${1} in
|
||||
odroidc2 | odroidn2)
|
||||
echo "arm64"
|
||||
;;
|
||||
odroidxu4)
|
||||
echo "armhf"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
default_distro() {
|
||||
[ -z ${DISTRO} ] && DISTRO="bionic"
|
||||
echo ${DISTRO}
|
||||
}
|
||||
|
||||
default_flavour() {
|
||||
[ -z ${FLAVOUR} ] && FLAVOUR="minimal"
|
||||
echo ${FLAVOUR}
|
||||
}
|
||||
|
||||
default_target_device() {
|
||||
echo ${TARGET_DEVICE}
|
||||
}
|
||||
|
||||
allow_root_login() {
|
||||
echo false
|
||||
}
|
||||
|
||||
default_root_passwd() {
|
||||
[ -z ${DEFAULT_ROOT_PASSWD} ] && DEFAULT_ROOT_PASSWD="odroid"
|
||||
echo ${DEFAULT_ROOT_PASSWD}
|
||||
}
|
||||
|
||||
default_user() {
|
||||
[ -z ${DEFAULT_USER} ] && DEFAULT_USER="odroid"
|
||||
echo ${DEFAULT_USER}
|
||||
}
|
||||
|
||||
default_user_passwd() {
|
||||
[ -z ${DEFAULT_PASSWD} ] && DEFAULT_PASSWD="odroid"
|
||||
echo ${DEFAULT_PASSWD}
|
||||
}
|
||||
|
||||
default_config() {
|
||||
cat>${1}<<__EOF
|
||||
BOARD=$(get_board)
|
||||
ARCH=$(get_arch $(get_board))
|
||||
DISTRO=$(default_distro)
|
||||
FLAVOUR=$(default_flavour)
|
||||
TARGET_DEVICE=$(default_target_device)
|
||||
DEFAULT_USER=$(default_user)
|
||||
DEFAULT_PASSWD=$(default_user_passwd)
|
||||
DEFAULT_ROOT_PASSWD=$(default_root_passwd)
|
||||
ALLOW_ROOT_LOGIN=$(allow_root_login)
|
||||
__EOF
|
||||
}
|
||||
|
||||
# vim: set ft=sh ts=4 sw=4 expandtab:
|
||||
2
fixups/S00-startup
Executable file
2
fixups/S00-startup
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
|
||||
6
fixups/S10-network
Executable file
6
fixups/S10-network
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
cat>/etc/resolv.conf<<__EOF
|
||||
nameserver 8.8.8.8
|
||||
nameserver 8.8.4.4
|
||||
__EOF
|
||||
8
fixups/S20-install-packages
Executable file
8
fixups/S20-install-packages
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
apt update && apt upgrade -y
|
||||
apt install -y \
|
||||
odroid-base \
|
||||
@@DEFAULT_FLAVOUR_PACKAGES@@ \
|
||||
@@DEFAULT_KERNEL_PACKAGE@@ \
|
||||
@@DEFAULT_BOOTSCRIPT_PACKAGE@@
|
||||
20
fixups/S70-fixup-fstab
Executable file
20
fixups/S70-fixup-fstab
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
|
||||
uuid_boot=$(blkid --output export @@DEFAULT_DEV_BOOT@@ | grep ^UUID)
|
||||
uuid_root=$(blkid --output export @@DEFAULT_DEV_ROOTFS@@ | grep ^UUID)
|
||||
|
||||
sed -i "/LABEL=\"rootfs\"/d" /etc/fstab
|
||||
sed -i "/LABEL=\"BOOT\"/d" /etc/fstab
|
||||
|
||||
if [ "x${uuid_root}" != "x" ]; then
|
||||
cat <<__EOF | tee -a /etc/fstab >/dev/null
|
||||
${uuid_root} / ext4 rw,relatime,data=ordered 0 0
|
||||
__EOF
|
||||
fi
|
||||
|
||||
if [ "x${uuid_boot}" != "x" ]; then
|
||||
cat <<__EOF | tee -a /etc/fstab >/dev/null
|
||||
${uuid_boot} /boot ext2 rw,relatime,errors=continue 0 0
|
||||
__EOF
|
||||
fi
|
||||
|
||||
7
fixups/S70-fixup-hostname
Executable file
7
fixups/S70-fixup-hostname
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo "I: set default hostname to @@DEFAULT_HOSTNAME@@"
|
||||
echo @@DEFAULT_HOSTNAME@@ > /etc/hostname
|
||||
|
||||
sed -i "/127.0.1.1/d" /etc/hosts
|
||||
echo "127.0.1.1 @@DEFAULT_HOSTNAME@@" >> /etc/hosts
|
||||
3
fixups/S70-fixup-sshkey
Executable file
3
fixups/S70-fixup-sshkey
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
rm -f /etc/ssh/ssh_host_rsa_key
|
||||
16
fixups/S80-setup-default-user
Executable file
16
fixups/S80-setup-default-user
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "@@ALLOW_ROOT_LOGIN@@" = "true" ]; then
|
||||
echo "I: set default root password"
|
||||
echo "root:@@DEFAULT_ROOT_PASSWD@@" | chpasswd
|
||||
else
|
||||
if ! adduser @@DEFAULT_USER@@ sudo >/dev/null 2>&1; then
|
||||
echo "@@DEFAULT_USER@@ ALL=(ALL) ALL" >> /etc/sudoers
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "I: create default user account"
|
||||
adduser --gecos @@DEFAULT_USER@@ --disabled-login @@DEFAULT_USER@@
|
||||
|
||||
echo "I: set default user password"
|
||||
echo "@@DEFAULT_USER@@:@@DEFAULT_USER_PASSWD@@" | chpasswd
|
||||
10
fixups/S90-flash-kernel
Executable file
10
fixups/S90-flash-kernel
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo flash-kernel flash-kernel/linux_cmdline string @@LINUX_KERNEL_CMDLINE@@ | \
|
||||
debconf-set-selections
|
||||
|
||||
cat>/etc/default/flash-kernel<<__EOF
|
||||
LINUX_KERNEL_CMDLINE="@@LINUX_KERNEL_CMDLINE@@"
|
||||
LINUX_KERNEL_CMDLINE_DEFAULTS="@@LINUX_KERNEL_CMDLINE_DEFAULTS@@"
|
||||
__EOF
|
||||
/usr/sbin/flash-kernel --machine "@@DEFAULT_MACHINE_NAME@@"
|
||||
33
fixups/S99-firstboot
Executable file
33
fixups/S99-firstboot
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/bin/sh
|
||||
|
||||
get_uuid_rootfs() {
|
||||
uuid=$(blkid --output export @@DEFAULT_DEV_ROOTFS@@ | \
|
||||
grep ^UUID | cut -d'=' -f2)
|
||||
echo ${uuid}
|
||||
}
|
||||
|
||||
if [ -f /root/firstboot.sh ]; then
|
||||
chmod +x /root/firstboot.sh
|
||||
chown root:root /root/firstboot.sh
|
||||
|
||||
sed -i "s,@@UUID_ROOTFS@@,$(get_uuid_rootfs),g" /root/firstboot.sh
|
||||
fi
|
||||
|
||||
cat <<__EOF | tee -a /lib/systemd/system/firstboot.service >/dev/null
|
||||
[Unit]
|
||||
Description=FirstBoot
|
||||
After=network.target
|
||||
Before=rc-local.service
|
||||
ConditionFileNotEmpty=/root/firstboot.sh
|
||||
|
||||
[Service]
|
||||
ExecStart=/root/firstboot.sh
|
||||
ExecStartPost=/bin/mv /root/firstboot.sh /root/firstboot.sh.done
|
||||
Type=oneshot
|
||||
RemainAfterExit=no
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
__EOF
|
||||
|
||||
systemctl enable firstboot.service
|
||||
381
functions
Normal file
381
functions
Normal file
@@ -0,0 +1,381 @@
|
||||
rootfs_mnt=${TOPDIR}/rootfs
|
||||
fixups_dir=/var/fixups
|
||||
|
||||
do_unmount() {
|
||||
echo "I: unmounting devices..."
|
||||
|
||||
umount -f ${rootfs_mnt}/sys 2>/dev/null
|
||||
umount -f ${rootfs_mnt}/proc 2>/dev/null
|
||||
umount -f ${rootfs_mnt}/dev/pts 2>/dev/null
|
||||
umount -f ${rootfs_mnt}/dev 2>/dev/null
|
||||
umount -f ${rootfs_mnt}/boot 2>/dev/null
|
||||
umount -f ${rootfs_mnt} 2>/dev/null
|
||||
rm -rf ${rootfs_mnt}
|
||||
|
||||
if [ ! -b ${TARGET_DEVICE} ]; then
|
||||
losetup -d ${LOOPBACK} 2>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
do_unmount
|
||||
}
|
||||
|
||||
trap_ctrlc() {
|
||||
echo "<Ctrl-C> is detected..."
|
||||
do_unmount
|
||||
exit 1
|
||||
}
|
||||
|
||||
panic() {
|
||||
echo "E: ${1}"
|
||||
cleanup
|
||||
exit 1
|
||||
}
|
||||
|
||||
fixup_arch() {
|
||||
case "${1}" in
|
||||
arm64)
|
||||
echo "aarch64"
|
||||
;;
|
||||
armhf)
|
||||
echo "arm"
|
||||
;;
|
||||
*)
|
||||
panic "Unknown architecture..."
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
qemu_binary() {
|
||||
if [ "x$(fixup_arch ${1})" != "x$(uname -m)" ]; then
|
||||
echo "/usr/bin/qemu-$(fixup_arch ${ARCH})-static"
|
||||
fi
|
||||
}
|
||||
|
||||
ask_password() {
|
||||
printf '%s\n' "$(dialog --output-fd 1 \
|
||||
--passwordbox "Enter your sudo password" 12 50)" | sudo -Svp ''
|
||||
}
|
||||
|
||||
get_part_boot() {
|
||||
if [ ! -b ${TARGET_DEVICE} ]; then
|
||||
echo "${LOOPBACK}p1"
|
||||
else
|
||||
echo "${TARGET_DEVICE}-part1"
|
||||
fi
|
||||
}
|
||||
|
||||
get_part_root() {
|
||||
if [ ! -b ${TARGET_DEVICE} ]; then
|
||||
echo "${LOOPBACK}p2"
|
||||
else
|
||||
echo "${TARGET_DEVICE}-part2"
|
||||
fi
|
||||
}
|
||||
|
||||
get_kernel_cmdline() {
|
||||
uuid=$(blkid --output export $(get_part_root) | grep ^UUID)
|
||||
[ "${uuid}" != "" ] && echo "root=${uuid} rootwait ro quiet"
|
||||
}
|
||||
|
||||
get_kernel_cmdline_defaults() {
|
||||
echo ""
|
||||
}
|
||||
|
||||
get_flavour_packages() {
|
||||
[ -f boards/${BOARD}/packages ] && \
|
||||
DEFAULT_FLAVOUR_PACKAGES=`cat boards/${BOARD}/packages | \
|
||||
sort | tr "\n" " "`
|
||||
echo ${DEFAULT_FLAVOUR_PACKAGES}
|
||||
}
|
||||
|
||||
get_lookback_device() {
|
||||
echo `losetup -a | grep ${1} | cut -d':' -f1`
|
||||
}
|
||||
|
||||
do_mount() {
|
||||
local rootfs=${1}
|
||||
|
||||
echo "I: mounting to ${rootfs_mnt}"
|
||||
|
||||
umount ${rootfs_mnt} 2>/dev/null
|
||||
mkdir -p ${rootfs_mnt}
|
||||
|
||||
if [ ! -b ${TARGET_DEVICE} ]; then
|
||||
devs=$(get_lookback_device ${rootfs})
|
||||
[ -z "${devs}" ] || losetup -d ${devs}
|
||||
|
||||
losetup -fP ${rootfs} || panic "failed to setup loopback image"
|
||||
LOOPBACK=$(get_lookback_device ${rootfs})
|
||||
fi
|
||||
|
||||
mkfs.ext2 -F -L BOOT $(get_part_boot) 2>/dev/null \
|
||||
|| panic "failed to create partition '$(get_part_boot)'"
|
||||
mkfs.ext4 -F -L rootfs $(get_part_root) 2>/dev/null \
|
||||
|| panic "failed to create partition '$(get_part_root)'"
|
||||
|
||||
mount $(get_part_root) ${rootfs_mnt}
|
||||
mkdir -p ${rootfs_mnt}/boot
|
||||
mkdir -p ${rootfs_mnt}/dev
|
||||
mkdir -p ${rootfs_mnt}/dev/pts
|
||||
mkdir -p ${rootfs_mnt}/proc
|
||||
mkdir -p ${rootfs_mnt}/sys
|
||||
|
||||
mount $(get_part_boot) ${rootfs_mnt}/boot
|
||||
mount -o bind /dev ${rootfs_mnt}/dev
|
||||
mount -o bind /dev/pts ${rootfs_mnt}/dev/pts
|
||||
mount -o bind /proc ${rootfs_mnt}/proc
|
||||
mount -o bind /sys ${rootfs_mnt}/sys
|
||||
}
|
||||
|
||||
do_create_partition() {
|
||||
local disk=${1}
|
||||
local mbytes=${2}
|
||||
local bootsize=256
|
||||
|
||||
if [ ! -b ${disk} ]; then
|
||||
echo "I: creating the disk image file '${disk}' (${mbytes}MiB)"
|
||||
dd if=/dev/zero bs=1M count=${mbytes} \
|
||||
| pv -s $((${mbytes} * 1024 * 1024)) \
|
||||
| dd of=${disk} >/dev/null
|
||||
else
|
||||
for d in `readlink -f ${disk}*`; do
|
||||
umount -f ${d} 2>/dev/null
|
||||
done
|
||||
|
||||
echo "I: removing the current partition table in '${disk}'"
|
||||
dd if=/dev/zero of=${disk} bs=512 count=1 >/dev/null
|
||||
fi
|
||||
|
||||
boot_pstart=$(get_reserved_sectors)
|
||||
[ "x${boot_pstart}" = "x" ] && boot_pstart=2048
|
||||
boot_pend=$((${boot_pstart} + ${bootsize} * 1024 * 1024 / 512 - 1))
|
||||
|
||||
[ "${BASH_VERSION}" = "" ] || BACKSLASH_ESCAPE="-e"
|
||||
|
||||
echo "I: creating a partition table to '${disk}'"
|
||||
echo ${BACKSLASH_ESCAPE} \
|
||||
"n\np\n\n${boot_pstart}\n${boot_pend}\n" \
|
||||
"n\np\n\n$((${boot_pend} + 1))\n\nw\n" \
|
||||
| fdisk ${disk} >/dev/null
|
||||
# sleep 1
|
||||
partprobe
|
||||
}
|
||||
|
||||
do_extract() {
|
||||
local tarball=${1}
|
||||
[ -f ${tarball} ] || panic "missing file ${tarball}"
|
||||
|
||||
echo "I: extracting ${tarball} to ${rootfs_mnt}..."
|
||||
pv ${tarball} \
|
||||
| tar xzf - --strip-component=1 -C ${rootfs_mnt} \
|
||||
|| panic "E: error while extracting"
|
||||
}
|
||||
|
||||
do_preinstall() {
|
||||
echo "I: running preinstall scripts and copy default files..."
|
||||
mkdir -p ${rootfs_mnt}${fixups_dir}
|
||||
cp -a fixups/* ${rootfs_mnt}${fixups_dir}
|
||||
|
||||
FIXUPS=`ls -A1 ${rootfs_mnt}${fixups_dir}/*`
|
||||
for fixup in ${FIXUPS}; do
|
||||
sed -i \
|
||||
-e "s,@@DEFAULT_BOARD@@,${BOARD},g" \
|
||||
-e "s,@@DEFAULT_HOSTNAME@@,${DISTRO}-${FLAVOUR},g" \
|
||||
-e "s,@@DEFAULT_FLAVOUR_PACKAGES@@,$(get_flavour_packages),g" \
|
||||
-e "s,@@DEFAULT_KERNEL_PACKAGE@@,$(get_kernel_package),g" \
|
||||
-e "s,@@DEFAULT_BOOTSCRIPT_PACKAGE@@,$(get_bootscript_package),g" \
|
||||
-e "s,@@DEFAULT_MACHINE_NAME@@,$(get_machine_name),g" \
|
||||
-e "s,@@LINUX_KERNEL_CMDLINE@@,$(get_kernel_cmdline),g" \
|
||||
-e "s,@@LINUX_KERNEL_CMDLINE_DEFAULTS@@,$(get_kernel_cmdline_defaults),g" \
|
||||
-e "s,@@DEFAULT_DEV_BOOT@@,$(get_part_boot),g" \
|
||||
-e "s,@@DEFAULT_DEV_ROOTFS@@,$(get_part_root),g" \
|
||||
-e "s,@@ALLOW_ROOT_LOGIN@@,$(allow_root_login),g" \
|
||||
-e "s,@@DEFAULT_ROOT_PASSWD@@,$(default_root_passwd),g" \
|
||||
-e "s,@@DEFAULT_USER@@,$(default_user),g" \
|
||||
-e "s,@@DEFAULT_USER_PASSWD@@,$(default_user_passwd),g" \
|
||||
${fixup}
|
||||
done
|
||||
|
||||
QEMU_BINARY=$(qemu_binary ${ARCH})
|
||||
|
||||
if [ ! "x${QEMU_BINARY}" = "x" ]; then
|
||||
cp ${QEMU_BINARY} ${rootfs_mnt}/${QEMU_BINARY} || panic "error"
|
||||
fi
|
||||
|
||||
cp -a overlay/root/firstboot.sh ${rootfs_mnt}/root/
|
||||
cp -a overlay/boot/boot-logo.bmp.gz ${rootfs_mnt}/boot/
|
||||
}
|
||||
|
||||
do_postinstall() {
|
||||
echo "I: removing preinstall scripts..."
|
||||
if [ ! "x${QEMU_BINARY}" = "x" ]; then
|
||||
rm -f ${rootfs_mnt}/${QEMU_BINARY}
|
||||
fi
|
||||
rm -rf ${rootfs_mnt}${fixups_dir}
|
||||
}
|
||||
|
||||
do_cleanup() {
|
||||
rm -f ${rootfs_mnt}/SHA256SUMS
|
||||
rm -rf ${rootfs_mnt}/boot/filesystem.*
|
||||
}
|
||||
|
||||
get_install_fixups() {
|
||||
echo `ls -A1 ${rootfs_mnt}${fixups_dir}/S* | sort`
|
||||
}
|
||||
|
||||
do_run_fixups() {
|
||||
for fixup in $(get_install_fixups); do
|
||||
chroot ${rootfs_mnt} ${QEMU_BINARY} \
|
||||
/bin/sh ${fixups_dir}/$(basename ${fixup}) || \
|
||||
panic "error when running the fixup"
|
||||
done
|
||||
}
|
||||
|
||||
do_query_latest_tarball() {
|
||||
local host_url=${1}
|
||||
local arch=${2}
|
||||
local codename=${3}
|
||||
local flavour=${4}
|
||||
|
||||
echo $(lynx -dump -listonly ${host_url}/tarball/${arch}/${codename}/ | \
|
||||
grep tar.gz | grep ${flavour} | sort -r | head -n 1 | \
|
||||
awk '{print $2}')
|
||||
}
|
||||
|
||||
do_download_tarball() {
|
||||
local url=${1}
|
||||
local tarball=${2}
|
||||
local download=true
|
||||
|
||||
[ "x${url}" = "x" ] && panic "unknown url file"
|
||||
[ "x${tarball}" = "x" ] && panic "unknown tarball file"
|
||||
|
||||
if [ -f ${tarball} ]; then
|
||||
wget ${url%.tar.gz}.md5sums.txt --quiet -O .foo.md5sums.txt || \
|
||||
panic "failed to download MD5SUM file '${rul}'"
|
||||
hash_remote=$(cat .foo.md5sums.txt | \
|
||||
grep $(basename ${tarball}) | awk '{print $1}')
|
||||
hash_local=$(md5sum ${tarball} | awk '{print $1}')
|
||||
if [ "${hash_remote}" = "${hash_local}" ]; then
|
||||
download=false
|
||||
else
|
||||
rm -f ${tarball}
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "${download}" = true ]; then
|
||||
wget ${url} -O ${tarball} || \
|
||||
panic "failed to download tarball '${url}'"
|
||||
fi
|
||||
}
|
||||
|
||||
do_create_image() {
|
||||
local baseimage=${1}
|
||||
local tarball=${2}
|
||||
|
||||
[ "x${baseimage}" = "x" ] && paninc "no given image file name"
|
||||
[ "x${tarball}" = "x" ] && paninc "no given tarball"
|
||||
[ "x${EXTRA_SPACE}" = "x" ] && EXTRA_SPACE=0
|
||||
|
||||
echo "I: calculating the minimal space for root file system"
|
||||
local bytes=$(zcat ${tarball} | wc -c)
|
||||
bytes=$((${bytes} + $((${EXTRA_SPACE} * 1048576))))
|
||||
|
||||
do_create_partition ${baseimage} $(($((${bytes} + 1048575)) / 1048576))
|
||||
do_mount ${baseimage}
|
||||
do_extract ${tarball}
|
||||
do_preinstall
|
||||
do_run_fixups
|
||||
do_postinstall
|
||||
do_cleanup
|
||||
}
|
||||
|
||||
do_flash_bootloader() {
|
||||
local disk=${1}
|
||||
local uboot_tarball=${download_dir}/u-boot.tar.gz
|
||||
|
||||
echo "I: Downloading U-boot binaries"
|
||||
download_uboot ${uboot_tarball} \
|
||||
|| panic "failed to download bootloader release"
|
||||
rm -rf ${download_dir}/sd_fuse
|
||||
tar xzvf ${uboot_tarball} -C ${download_dir} || false
|
||||
if [ -f ${download_dir}/sd_fuse/sd_fusing.sh ]; then
|
||||
(cd ${download_dir}/sd_fuse;
|
||||
sed -i "/eject/d" ./sd_fusing.sh;
|
||||
chmod +x ./sd_fusing.sh;
|
||||
./sd_fusing.sh ${disk} 2>/dev/null
|
||||
)
|
||||
fi
|
||||
}
|
||||
|
||||
do_finalize_image() {
|
||||
local disk=${1}
|
||||
local osimage=${2}
|
||||
|
||||
[ "x${PUBLISH}" = "xtrue" ] && COMPRESS=true
|
||||
|
||||
if [ -f ${disk} ]; then
|
||||
echo "I: finalizing OS image - '${osimage}'"
|
||||
mv -f ${disk} ${osimage} || panic "failed to target image file"
|
||||
if [ "x${COMPRESS}" = "xtrue" ]; then
|
||||
echo "I: compressing OS image to ${osimage}"
|
||||
xz ${osimage} || panic "failed to create compressed image file"
|
||||
osimage=${osimage}.xz
|
||||
fi
|
||||
md5sum ${osimage} > ${osimage}.md5sum
|
||||
fi
|
||||
}
|
||||
|
||||
do_custom_installer() {
|
||||
local download_dir=${1}
|
||||
local out_dir=${2}
|
||||
|
||||
mkdir -p ${download_dir} ${out_dir}
|
||||
|
||||
echo "I: querying decent base files for ${ARCH}/${DISTRO}/${FLAVOUR}"
|
||||
url=$(do_query_latest_tarball http://ppa.linuxfactory.or.kr/images \
|
||||
${ARCH} ${DISTRO} ${FLAVOUR})
|
||||
[ "x${url}" = "x" ] && panic "Invalid URL - ${url}"
|
||||
|
||||
tarball=${download_dir}/$(basename ${url})
|
||||
do_download_tarball ${url} ${tarball}
|
||||
do_create_image ${TARGET_DEVICE} ${tarball}
|
||||
|
||||
case $(readlink -f ${TARGET_DEVICE}) in
|
||||
/dev/sd*)
|
||||
echo "W: bootloader won't be flashed to USB storage"
|
||||
;;
|
||||
*)
|
||||
if [ -b ${TARGET_DEVICE} ]; then
|
||||
disk=${TARGET_DEVICE}
|
||||
else
|
||||
disk=${LOOPBACK}
|
||||
fi
|
||||
do_flash_bootloader ${disk}
|
||||
do_finalize_image ${TARGET_DEVICE} ${OUTFILE}.img
|
||||
|
||||
if [ "x${PUBLISH}" = "xtrue" ]; then
|
||||
do_publish "192.168.0.2" \
|
||||
"/srv/ppa.linuxfactory.or.kr/html/images/raw" \
|
||||
${OUTFILE}
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
do_publish() {
|
||||
local host=${1}
|
||||
local dir=${2}/${ARCH}/${DISTRO}
|
||||
local osimage=${3}
|
||||
|
||||
files=`ls ${osimage}.*`
|
||||
if [ ! "x${files}" = "x" ]; then
|
||||
ssh ${host} mkdir -p ${dir} && \
|
||||
scp ${files} ${host}:/${dir} || \
|
||||
panic "failed to connect to remote server"
|
||||
fi
|
||||
}
|
||||
|
||||
# vim: set ft=sh ts=4 sw=4 expandtab:
|
||||
145
menu
Normal file
145
menu
Normal file
@@ -0,0 +1,145 @@
|
||||
do_finish() {
|
||||
echo ${BOARD}
|
||||
echo ${DISTRO}-${FLAVOUR}
|
||||
if [ ! -f configs/${DISTRO}-${FLAVOUR} ]; then
|
||||
echo XXX
|
||||
fi
|
||||
exit 0
|
||||
}
|
||||
|
||||
do_menu_target() {
|
||||
local n=1
|
||||
local DEVICE_LIST="File 0"
|
||||
|
||||
for disk in $(ls /dev/disk/by-id | grep -v '\-part*' | grep 'mmc\|usb'); do
|
||||
DEVICE_LIST="${DEVICE_LIST} ${disk} ${n}"
|
||||
n=$((n+1))
|
||||
done
|
||||
|
||||
CHOICE=$(dialog --clear --title "Devices" \
|
||||
--menu "X" 16 70 10 \
|
||||
${DEVICE_LIST} \
|
||||
2>&1 >/dev/tty)
|
||||
ret=$?
|
||||
if [ ${ret} = 0 ]; then
|
||||
if [ -b /dev/disk/by-id/${CHOICE} ]; then
|
||||
# TARGET_DEVICE=$(readlink -f /dev/disk/by-id/${CHOICE})
|
||||
TARGET_DEVICE="/dev/disk/by-id/${CHOICE}"
|
||||
else
|
||||
TARGET_DEVICE=${out_dir}/binary.img
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
do_menu_board() {
|
||||
CHOICE=$(dialog --clear --title "Target model" \
|
||||
--menu "X" 15 70 10 \
|
||||
"odroidc2" "Hardkernel ODROID-C2" \
|
||||
"odroidxu4" "Hardkernel ODROID-XU4" \
|
||||
"odroidn2" "Hardkernel ODROID-N2" \
|
||||
2>&1 >/dev/tty)
|
||||
|
||||
ret=$?
|
||||
if [ ${ret} = 0 ]; then
|
||||
BOARD=${CHOICE}
|
||||
case ${BOARD} in
|
||||
odroidc2)
|
||||
ARCH=arm64
|
||||
;;
|
||||
odroidxu4)
|
||||
ARCH=armhf
|
||||
;;
|
||||
odroidn2)
|
||||
ARCH=arm64
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
do_menu_distro() {
|
||||
CHOICE=$(dialog --clear --title "Ubuntu distribution" \
|
||||
--menu "X" 15 70 10 \
|
||||
"bionic" "Ubuntu Bionic (18.04)" \
|
||||
"disco" "Ubuntu Disco (19.04)" \
|
||||
2>&1 >/dev/tty)
|
||||
|
||||
ret=$?
|
||||
if [ ${ret} = 0 ]; then
|
||||
DISTRO=${CHOICE}
|
||||
fi
|
||||
}
|
||||
|
||||
do_menu_flavour() {
|
||||
CHOICE=$(dialog --clear --title "Ubuntu flavour" \
|
||||
--menu "X" 15 70 10 \
|
||||
"minimal" "Minimal" \
|
||||
"gnome-desktop" "GNOME" \
|
||||
"lxde-desktop" "LXDE" \
|
||||
"mate-desktop" "MATE" \
|
||||
"xfce4-desktop" "XFCE" \
|
||||
2>&1 >/dev/tty)
|
||||
|
||||
ret=$?
|
||||
if [ ${ret} = 0 ]; then
|
||||
FLAVOUR=${CHOICE}
|
||||
fi
|
||||
}
|
||||
|
||||
do_menu_root_passwd() {
|
||||
DEFAULT_ROOT_PASSWD=$(dialog --title "Default root password" --clear \
|
||||
--inputbox "Enter the password of root" 8 60 \
|
||||
${DEFAULT_ROOT_PASSWD} 2>&1 >/dev/tty)
|
||||
}
|
||||
|
||||
do_menu_default_user() {
|
||||
DEFAULT_USER=$(dialog --title "Default user account" --clear \
|
||||
--inputbox "Enter the default account " 8 60 \
|
||||
${DEFAULT_USER} 2>&1 >/dev/tty)
|
||||
}
|
||||
|
||||
do_menu_default_user_passwd() {
|
||||
DEFAULT_PASSWD=$(dialog --title "Default user password" --clear \
|
||||
--inputbox "Enter the password of default account " 8 60 \
|
||||
${DEFAULT_PASSWD} 2>&1 >/dev/tty)
|
||||
}
|
||||
|
||||
do_menu() {
|
||||
while true; do
|
||||
IMAGE_FILE=ubuntu-${DISTRO}-${FLAVOUR}-${BOARD}-`date +%Y%m%d`
|
||||
CHOICE=$(dialog --clear --backtitle "ODROID-STAMPER" \
|
||||
--title "Custom Ubuntu Recipe" \
|
||||
--extra-button --extra-label "Done" \
|
||||
--menu "Please customize the installation." 15 70 10 \
|
||||
0 "Target (${TARGET_DEVICE})" \
|
||||
1 "Board (${BOARD})" \
|
||||
2 "Distro (${DISTRO})" \
|
||||
3 "Flavour (${FLAVOUR})" \
|
||||
4 "Password of root" \
|
||||
5 "Default user" \
|
||||
6 "Password of default user" \
|
||||
2>&1 >/dev/tty)
|
||||
|
||||
ret=$?
|
||||
if [ ${ret} = 3 ]; then
|
||||
clear
|
||||
default_config ${DEFAULT_CONFIG}
|
||||
OUTFILE=${out_dir}/${IMAGE_FILE}
|
||||
break
|
||||
elif [ ${ret} = 0 ]; then
|
||||
case ${CHOICE} in
|
||||
0) do_menu_target "Target";;
|
||||
1) do_menu_board "Board";;
|
||||
2) do_menu_distro "Distro";;
|
||||
3) do_menu_flavour "Flavour";;
|
||||
4) do_menu_root_passwd;;
|
||||
5) do_menu_default_user;;
|
||||
6) do_menu_default_user_passwd;;
|
||||
esac
|
||||
else
|
||||
clear
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# vim: set ft=sh ts=4 sw=4 expandtab:
|
||||
37
odroid-stamper
Executable file
37
odroid-stamper
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/bin/sh
|
||||
|
||||
#set -x
|
||||
|
||||
ODROID_STAMPER_DIR="/usr/share/odroid-stamper"
|
||||
|
||||
#TOPDIR=${ODROID_STAMPER_CHECKOUT:-${ODROID_STAMPER_DIR}}
|
||||
TOPDIR=$PWD
|
||||
|
||||
DEFAULT_CONFIG=${TOPDIR}/.config
|
||||
|
||||
download_dir="/var/cache/odroid-stamper/downloads"
|
||||
out_dir=${PWD}
|
||||
|
||||
. ${TOPDIR}/menu
|
||||
. ${TOPDIR}/default
|
||||
. ${TOPDIR}/functions
|
||||
|
||||
if [ ! -f ${DEFAULT_CONFIG} ]; then
|
||||
default_config ${DEFAULT_CONFIG}
|
||||
fi
|
||||
|
||||
. ${DEFAULT_CONFIG}
|
||||
|
||||
do_menu
|
||||
|
||||
[ -f ${TOPDIR}/configs/${DISTRO}-${FLAVOUR} ] && \
|
||||
. ${TOPDIR}/configs/${DISTRO}-${FLAVOUR}
|
||||
. ${TOPDIR}/boards/${BOARD}/functions
|
||||
|
||||
trap "trap_ctrlc" 2
|
||||
trap "cleanup" 0
|
||||
trap "panic" 1 3 15
|
||||
|
||||
do_custom_installer ${download_dir} ${out_dir}
|
||||
|
||||
# vim: set ft=sh ts=4 sw=4 expandtab
|
||||
BIN
overlay/boot/boot-logo.bmp.gz
Normal file
BIN
overlay/boot/boot-logo.bmp.gz
Normal file
Binary file not shown.
20
overlay/root/firstboot.sh
Executable file
20
overlay/root/firstboot.sh
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||
|
||||
. /lib/init/vars.sh
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
rootdev=`blkid -U @@UUID_ROOTFS@@`
|
||||
|
||||
dev=${rootdev%??}
|
||||
lba_start=`fdisk -l ${dev} | grep p2 | awk '{print $2}'`
|
||||
lba_finish=$((`fdisk -l ${dev} | grep Disk | grep sectors | awk '{printf $7}'` - 2048))
|
||||
|
||||
echo -e "p\nd\n2\nn\np\n2\n${lba_start}\n${lba_finish}\np\nw\n" | \
|
||||
fdisk ${dev} >/dev/null
|
||||
resize2fs ${rootdev}
|
||||
|
||||
rm -f /etc/ssh/ssh_host* && ssh-keygen -A
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user