]> git.friedersdorff.com Git - max/disk_creator.git/blob - disk_creator.sh
4ee7b5f7b1c1ff60094fb9a88c26c32d7eff47db
[max/disk_creator.git] / disk_creator.sh
1 #!/bin/bash
2
3 usage() {
4         echo "Usage:"
5         echo "disk_creator.sh OS_IMAGE USB_DRIVE"
6         echo
7         echo "Example:"
8         echo "disk_creator.sh ~/Downloads/xubuntu-18.04.2-desktop-amd64.iso /dev/sdd"
9         echo
10         echo "Create a live usb drive on the device '/dev/sdd' with the os found in"
11         echo "~/Downloads/xubuntu-18.04.2-desktop-amd64.iso"
12 }
13
14 if [ $# -ne 2 ]; then
15         echo "ERROR: expected exactly 2 arguments"
16         usage
17         exit 1
18 fi
19
20 if [ ! -b $2 ]; then
21         echo "ERROR: $2 is not a block device"
22         usage
23         exit 1
24 fi
25
26 if [ ! -f $1 ]; then
27         echo "ERROR: $1 is not a regular file"
28         usage
29         exit 1
30 fi
31
32 # The name of the USB drive you want to create
33 usb_drive="$2"
34
35 # The location of the linux distribution you want to use
36 os_image="$1"
37
38 # Removing leading directory/folder name
39 image_name="${os_image##*/}"
40 # Removing the filename extension
41 os_name="$(echo ${image_name%.*} | tr '-' ' ' | tr '_' ' ')"
42
43 # Querying the block size, the logical size of entities on the USB drive
44 block_size=$(cat /sys/block/${usb_drive#/dev/}/queue/hw_sector_size)
45
46 # Calculate the size of the partition to hold the iso and boot loader.  Allow
47 # 50MiB for the bootloader (this is way overkill).
48 live_part_size="$(ls -l ${os_image} | 
49         awk -v block_size=${block_size} \
50         '{print (($5/block_size) + (50*1024*1024/block_size))}')"
51
52 # Calculate the start of the 'usbdata' partition
53 let usbdata_part_start="${live_part_size} + 2048 + 3*1024*1024*1024/${block_size}"
54
55 # Find out the location of the linux kernel and the initramfs (initial ramdisk
56 # file system) in the os image file. We need these locations later when 
57 # configuring grub
58 modprobe loop
59 loop_dev="$(losetup --show -f ${os_image})"
60 l_mount="$(mktemp -d)"
61 mount -o ro "${loop_dev}" "${l_mount}"
62 kernel="$(find ${l_mount} -iname *vmlinuz* -printf '%P\n')"
63 initramfs="$(find ${l_mount} -iname *initr* -printf '%P\n')"
64 umount "${l_mount}"
65 rmdir "${l_mount}"
66 losetup -d "${loop_dev}"
67
68 if [ $(echo "${kernel}" | wc -l) -gt 1 ]; then
69         echo "Too many possible linux kernels found:"
70         echo $kernel
71 fi
72
73 if [ $(echo "${initramfs}" | wc -l) -gt 1 ]; then
74         echo "Too many possible initramfs found:"
75         echo $initramfs
76 fi
77
78 # Partition the usb drive. The partition listed first can be read by linux
79 # and windows operating systems.  It is located at the 'end' of the drive
80 # The partition listed second contains the operating system and boot loader,
81 # it is located at the 'beginning' of the drive. The partition listed last fills
82 # the space between the other two, and is used to record changes made to the 
83 # operating system
84 sfdisk "${usb_drive}" << EOF
85
86 label: gpt
87
88 start=$usbdata_part_start, type=11
89 start=2048, size=$live_part_size, type=1
90 type=20
91 EOF
92
93 # Format each partition with the relevant filesystem.
94 mkfs.ntfs --fast -L usbdata "${usb_drive}1"
95 mkfs.fat -F 32 "${usb_drive}2"
96 mkfs.ext4 -q -F -L casper-rw "${usb_drive}3"
97
98 # Create a temporary directory
99 m_point=$(mktemp -d)
100
101 # Mount the drive to the temporary directory, create some folders/directories,
102 # copy the os image, and install the boot loader.
103 mount "${usb_drive}2" "${m_point}"
104 mkdir "${m_point}"/{boot,iso_boot}
105 cp "${os_image}" "${m_point}/iso_boot" && sync
106 grub-install "${usb_drive}" \
107         --target=x86_64-efi \
108         --efi-directory="${m_point}" \
109         --boot-directory="${m_point}/boot" \
110         --removable
111
112 # Install the configuration file for the bootloader
113 cat <<EOF> "${m_point}/boot/grub/grub.cfg"
114 set timeout=10
115 set default=0
116 insmod loopback
117 insmod all_video
118
119 menuentry "Run ${os_name} Persistent, in RAM" {
120         loopback loop /iso_boot/${image_name}
121         set gfxpayload=keep
122         linux (loop)/${kernel} boot=casper iso-scan/filename=/iso_boot/${image_name} quiet splash persistent toram ---
123         initrd (loop)/${initramfs}
124 }
125
126 menuentry "Run ${os_name} - Persistent" {
127         loopback loop /iso_boot/${image_name}
128         set gfxpayload=keep
129         linux (loop)/${kernel} boot=casper iso-scan/filename=/iso_boot/${image_name} quiet splash persistent ---
130         initrd (loop)/${initramfs}
131 }
132
133 menuentry "Run ${os_name}" {
134         loopback loop /iso_boot/${image_name}
135         set gfxpayload=keep
136         linux (loop)/${kernel} boot=casper iso-scan/filename=/iso_boot/${image_name} quiet splash ---
137         initrd (loop)/${initramfs}
138 }
139 EOF
140
141 # Clean up
142 umount "${m_point}"
143 rmdir "${m_point}"