-
Notifications
You must be signed in to change notification settings - Fork 7
/
MiSTer-sd-installer-linux.sh
executable file
·217 lines (177 loc) · 7.77 KB
/
MiSTer-sd-installer-linux.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#!/usr/bin/env bash
read -rd '' splash <<_EOF_
####################################################################################
# MiSTer installation script for Linux by rwk. #
# based on Michael Smith (shmitty) <[email protected]> macOS script #
# #
# Thanks to rattboi who posted Naomi Peori's MiSTer SD Card Info file on the #
# SmokeMonster Elite fpga-general discord channel and everyone involved and in and #
# using the MiSTer project. #
# #
# IMPORTANT: Use this script at your own risk. It WILL WIPE ALL DATA on the device #
# you specify. On standard Linux this is usually /dev/mmcblkX or /dev/sdX but make #
# sure to double check. #
# #
# Prerequisites: #
# * git #
# * wget #
# * unrar #
# * mkfs.exfat #
# (install using your packet manager: e.g., apt-get install git wget unrar). #
# (if something else is missing install it ...) #
####################################################################################
_EOF_
echo "${splash}"
[[ "${EUID}" -ne 0 ]] && { echo "Error: This script needs to be run as root" ; exit 1 ; }
print_block() {
printf '#%.0s' {1..80} ; echo
echo "${1}" | fold -s -w 80
printf '#%.0s' {1..80} ; echo
echo
}
# Print a formatted error message and exit 1.
die_with_error() {
error="${1}"
if [[ -z "${error}" ]]; then
error="One or more setup commands failed. Aborting installation."
fi
print_block "ERROR: ${error}"
exit 1
}
# Verify a prerequisite command exists, die if it doesn't.
check_prereqs() {
for cmd in "${@}"; do
command -v "${cmd}" >/dev/null 2>&1 || die_with_error "I require '${cmd}' but it's not installed. Aborting."
done
}
# Sanity checks for temporary directories.
verify_absent_or_directory() {
for dir in "${@}"; do
if [[ -e "${dir}" ]] && [[ ! -d "${dir}" ]]; then
die_with_error "Required temporary path \"${dir}\" exists but is not a directory. Aborting."
fi
done
}
# Script configuration
DOWNLOAD_DIRECTORY="./download"
MNT_DIRECTORY="./mnt_MiSTer_Data"
verify_absent_or_directory "${DOWNLOAD_DIRECTORY}" "${MNT_DIRECTORY}"
# TODO(m): Remove hardcoded versions.
# URLs
RELEASE_URL='https://github.com/MiSTer-devel/SD-Installer-Win64_MiSTer/raw/master/release_20200908.rar'
RECENT_MISTER_URL='https://github.com/MiSTer-devel/Main_MiSTer/raw/master/releases/MiSTer_20210224'
RECENT_MENU_MISTER_URL='https://github.com/MiSTer-devel/Menu_MiSTer/raw/master/releases/menu_20210222.rbf'
# Sanity checks
if [ -z "${1}" ]; then
USBKEYS=($(
grep -Hv ^0$ /sys/block/*/removable |
sed s/removable:.*$/device\\/uevent/ |
xargs grep -H ^DRIVER=sd |
sed s/device.uevent.*$/size/ |
xargs grep -Hv ^0$ |
cut -d / -f 4
))
echo ""
echo "Usage: ${0} [DEVICE]"
echo ""
echo "Please read README.md and specify an SD card device."
echo ""
echo "Available removable storage devices:"
for dev in "${USBKEYS[@]}" ;do
echo "${dev}" \"$(
sed -e s/\ *$//g <"/sys/block/${dev}/device/model"
)\" ;
done
exit 1
fi
# Fail if mount point is a non-empty directory.
if [[ "$(ls -A "${MNT_DIRECTORY}" &> /dev/null)" ]]; then
die_with_error "Temporary mount directory \"${MNT_DIRECTORY}\" exists and is not empty. Aborting installation."
fi
# Check prerequisites
check_prereqs git wget unrar mkfs.exfat
# From here on, any non-zero exit code will call die_with_error(). Append any
# line with " || true" to inhibit dying on error.
trap die_with_error ERR
# Set SD card device
DEVICE="${1}"
[[ "${DEVICE}" =~ "/dev/"* ]] || DEVICE="/dev/${DEVICE}"
# Check if the device exists
if [ ! -b "${DEVICE}" ]; then
echo ""
echo "Error: Block device ${DEVICE} not found."
echo ""
exit 1
fi
echo "This will erase ${DEVICE} are you sure you want to continue ? [y/n]"
IFS="" read -r ans
if [ "${ans}" != "${ans#[Yy]}" ] ;then
echo "Okay ! Here we go !"
else
exit 1
fi
mkdir -p ${DOWNLOAD_DIRECTORY}
print_block "Fetching installation files..."
wget -nv --progress=bar --show-progress -O "${DOWNLOAD_DIRECTORY}/release.rar" "${RELEASE_URL}"
echo ""
print_block "Extracting installation files..."
unrar x -y "${DOWNLOAD_DIRECTORY}/release.rar" "${DOWNLOAD_DIRECTORY}"
echo ""
print_block "Unmounting potentially mounted partitions (sudo may ask for your password)"
sudo umount "${DEVICE}"* || true
echo ""
# Note : Uboot and FSBL code is loaded from partition with a2 ID (can be any of the 4 partitions in the MBR) see :
# https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/hb/cyclone-v/cv_5v4.pdf
# Page 3481 (Section A-13) "Flash Memory Devices for Booting"
# However Uboot (the Uboot that comes with MiSTer) will try to boot linux from partition 1
# Here we create a partition 1 that takes all the remaining space of the SD card from sector 4096+
# and partition 2 which spans from sector 2048 to 4095 (for Uboot and the FSBL code)
print_block "Creating SD Card partition table"
sudo sfdisk --force "${DEVICE}" << EOF
4096;
2048,2048
EOF
echo ""
# Having the partitions in reverse order relative to their position on the disk is a bit dodgy, this
# was done so that the first partition could be extended to the end of the disk while the second
# partition would only span 1M ... If someone has a better solution go ahead
# We set the special partition magic ID (a2) as said in the manual using sfdisk and sed
print_block "Setting partition table, sfdisk may complain, don't worry"
sudo sfdisk -d "${DEVICE}" | sed '0,/type=.*$/s//type=7/' | sed '0,/type=.*$/! s/type=.*$/type=a2/' | sudo sfdisk --force "${DEVICE}" || true
echo ""
print_block "Writing uboot image to the UBOOT partition" # Partition 2 (but at the start of the disk)
UBOOT_PART="$(ls "${DEVICE}"*2)"
sudo dd if="${DOWNLOAD_DIRECTORY}/files/linux/uboot.img" of="${UBOOT_PART}" bs=32k
echo ""
print_block "Creating the MiSTer_Data partition" # Partition 1 (since Uboot will load Linux from Part 1, see env)
mkfs.exfat -h 2>&1 | grep -q '\-s ' && \
sudo mkfs.exfat -s 32 -n "MiSTer_Data" "${DEVICE}"*1 || \
sudo mkfs.exfat -c 32K -L "MiSTer_Data" "${DEVICE}"*1
echo ""
print_block "Syncing"
sudo sync
echo ""
print_block "Mounting the disk"
mkdir -p "${MNT_DIRECTORY}"
sudo mount -t exfat "${DEVICE}"*1 "${MNT_DIRECTORY}"
echo ""
print_block "Copying MiSTer files..."
cp -Rv "${DOWNLOAD_DIRECTORY}/files/"* "${MNT_DIRECTORY}"
echo ""
print_block "Downloading and installing a recent MiSTer binary..."
wget -nv --progress=bar --show-progress -O "${MNT_DIRECTORY}/MiSTer" "${RECENT_MISTER_URL}"
echo ""
print_block "Downloading and installing a recent MiSTer menu core..."
wget -nv --progress=bar --show-progress -O "${MNT_DIRECTORY}/menu.rbf" "${RECENT_MENU_MISTER_URL}"
echo ""
print_block "Syncing data to SD card before ejection"
sudo sync
echo ""
print_block "Unmounting SD card..."
sudo umount "${MNT_DIRECTORY}"
rmdir "${MNT_DIRECTORY}"
echo ""
echo ""
print_block "All done. Put the SD card into your MiSTer and start it up.
Connect a keyboard to the MiSTer and hit F12 to bring up the menu.
Refer to the MiSTer wiki for further information."