create_arm_image.sh 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013
  1. #!/bin/bash
  2. # Copyright (C) 2017-2018 Daniel Tartavel-jeannot <contact@librepc.com>
  3. # Jean-Baptiste Biernacki <j.biernacki@free.fr>
  4. #
  5. # This program is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation; either version 2 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. #Change the local to the most global
  18. export LC_ALL=C
  19. function WaitToContinue() {
  20. read -p "Break... Press [ENTER] to continue." GARBAGE
  21. }
  22. function title() {
  23. echo -e "\e[1;32m${1}\e[0m"
  24. }
  25. function info() {
  26. echo -e "\e[36m${1}\e[0m"
  27. }
  28. function warning() {
  29. echo -e "\e[1;35m${1}\e[0m"
  30. }
  31. function error() {
  32. echo -e "\e[1;31m${1}\e[0m"
  33. }
  34. function help() {
  35. echo -e "${CMDNAME} [option] [size of image in Go]"
  36. echo -e "Options:"
  37. echo -e "--all create ready to burn image of Mageia ${MAGEIA_VERSION}"
  38. echo -e "--clean Clean all (suppress all) to make a new image"
  39. echo -e "--size size of image default: 7Go"
  40. echo -e "--build-path Path to the build directory of the image of Mageia ${MAGEIA_VERSION}"
  41. echo -e "--target target system (for now rpi, odroid)"
  42. echo -e "--target-version version of the target (0, 1, 2, 3 for rpi, 3 or 4 for odroid)"
  43. echo -e "--config Path to config files"
  44. echo -e "--bootfs filesystem of boot partition (ext4 or vfat) default: ext4"
  45. echo -e "--nonfree activate nonfree repos"
  46. echo -e "--tainted activate tainted repos"
  47. echo -e "\nBuild levels:"
  48. echo -e "--create-chroot Create the chroot directory"
  49. echo -e "--install-basesystem install base system"
  50. echo -e "--add-urpmimedia add mirrors for urpmi"
  51. echo -e "--chroot chroot to arm directory and launch packages installation"
  52. echo -e "--create-image Create the image of Mageia ${MAGEIA_VERSION}"
  53. echo "--config Path to config files (rpi1 rpi2 rpi3 rpi3+ xu4)"
  54. echo -e "\nFor image size, make sure it fit on physical support. (Default size is 7 Go)"
  55. }
  56. function verify_disk_space()
  57. {
  58. title "Verifying if there is enough space on disk to make the image"
  59. DISK_SPACE=$(/usr/bin/df -BG --output=avail "${INSTALL_PATH}" | sed '1d;s/[^0-9]//g')
  60. info "Free disk space: ${DISK_SPACE}G"
  61. if [ ${DISK_SPACE} -lt ${IMAGE_SIZE} ]; then
  62. warning "image size is greater than disk space"
  63. info "correct the problem and relaunch the script with parameter --create-rpi-image"
  64. info "${0} --size ${IMAGE_SIZE} --create-rpi-image"
  65. return 1
  66. fi
  67. return 0
  68. }
  69. # creation of install path and copy of qemu ( installing it if not yet installed )
  70. function createchroot()
  71. {
  72. title "Making chroot"
  73. if ! [ -f /bin/qemu-arm-static ]; then
  74. title "Qemu package not present : installing qemu packages"
  75. /usr/bin/dnf --assumeyes --setopt=install_weak_deps=False install qemu-user-static
  76. if [ ${?} -ne 0 ]; then
  77. error "line ${LINENO} can't install qemu-user-static : exiting"
  78. exit ${ERR_1}
  79. fi
  80. fi
  81. # Starting qemu service if not started
  82. /bin/systemctl is-active systemd-binfmt.service
  83. if [ ${?} -ne 0 ]; then
  84. title "Starting systemd-binfmt.service"
  85. /bin/systemctl start systemd-binfmt.service
  86. if [ ${?} -ne 0 ]; then
  87. error "line ${LINENO} can't start qemu-user-static : exiting"
  88. exit ${ERR_1}
  89. fi
  90. fi
  91. return 0
  92. }
  93. # enabling extra Mageia repositories
  94. function genusemirroroptions()
  95. {
  96. DNF_MIRROROPTS="--nogpgcheck --releasever=${MAGEIA_VERSION}"
  97. if [ ! -z "${MIRROR}" ]; then
  98. DNF_MIRROROPTS="${DNF_MIRROROPTS} --disablerepo=\* --repofrompath=mgarel,${MIRROR}/media/core/release/ --repofrompath=mgaup,${MIRROR}/media/core/updates/ --enablerepo=mgarel --enablerepo=mgaup"
  99. if [ ${NONFREE} -eq 1 ]; then
  100. DNF_MIRROROPTS="${DNF_MIRROROPTS} --repofrompath=mgarel-nonfree,${MIRROR}/media/nonfree/release/ --repofrompath=mgaup-nonfree,${MIRROR}/media/nonfree/updates/ --enablerepo=mgarel-nonfree --enablerepo=mgaup-nonfree"
  101. fi
  102. if [ ${TAINTED} -eq 1 ]; then
  103. DNF_MIRROROPTS="${DNF_MIRROROPTS} --repofrompath=mgarel-tainted,${MIRROR}/media/tainted/release/ --repofrompath=mgaup-tainted,${MIRROR}/media/tainted/updates/ --enablerepo=mgarel-tainted --enablerepo=mgaup-tainted"
  104. fi
  105. fi
  106. export DNF_MIRROROPTS
  107. return 0
  108. }
  109. # enabling extra Mageia repositories
  110. function enableextrarepos()
  111. {
  112. if [ "${MAGEIA_VERSION}" = "cauldron" ]; then
  113. extrasect_baseprefix="cauldron"
  114. extrasect_updatesprefix="cauldron-updates"
  115. else
  116. extrasect_baseprefix="mageia"
  117. extrasect_updatesprefix="updates"
  118. fi
  119. if [ ${NONFREE} -eq 1 ]; then
  120. title "activating non-free repos"
  121. /usr/bin/dnf --installroot="${BUILD_PATH}" config-manager --set-enabled "${extrasect_baseprefix}-${ARM_VERSION}-nonfree" --set-enabled "${extrasect_updatesprefix}-${ARM_VERSION}-nonfree"
  122. err=${?}
  123. if [ ${err} -ne 0 ]; then
  124. error "line ${LINENO} error ${err} - can't activate nonfree repositories : exiting"
  125. exit ${ERR_1}
  126. fi
  127. fi
  128. if [ ${TAINTED} -eq 1 ]; then
  129. title "activating tainted repos"
  130. /usr/bin/dnf --installroot="${BUILD_PATH}" config-manager --set-enabled "${extrasect_baseprefix}-${ARM_VERSION}-tainted" --set-enabled "${extrasect_updatesprefix}-${ARM_VERSION}-tainted"
  131. err=${?}
  132. if [ ${err} -ne 0 ]; then
  133. error "line ${LINENO} error ${err} - can't activate tainted repositories : exiting"
  134. exit ${ERR_1}
  135. fi
  136. fi
  137. return 0
  138. }
  139. # adding Mageia urpmi repositories
  140. function addurpmimedia()
  141. {
  142. title "Creating media ${MIRROR}"
  143. info "Removing old media"
  144. /sbin/urpmi.removemedia --urpmi-root "${BUILD_PATH}" -a
  145. info "Adding media"
  146. if [ ! -z "${MIRROR}" ] ; then
  147. /sbin/urpmi.addmedia --urpmi-root "${BUILD_PATH}" --distrib "${MIRROR}"
  148. else
  149. info "MIRROR variable not set, using mirrorlist."
  150. /sbin/urpmi.addmedia --urpmi-root "${BUILD_PATH}" --distrib --mirrorlist "http://mirrors.mageia.org/api/mageia.${MAGEIA_VERSION}.${ARM_VERSION}.list"
  151. fi
  152. err=${?}
  153. if [ ${err} -ne 0 ]; then
  154. error "line ${LINENO} error ${err} - can't add medias from ${MIRROR} : exiting"
  155. exit ${ERR_1}
  156. fi
  157. if [ ${NONFREE} -eq 1 ]; then
  158. title "activating non-free repos"
  159. /sbin/urpmi.update --urpmi-root "${BUILD_PATH}" --no-ignore Nonfree\ Release Nonfree\ Updates
  160. err=${?}
  161. if [ ${err} -ne 0 ]; then
  162. error "line ${LINENO} error ${err} - can't activate medias nonfree : exiting"
  163. exit ${ERR_1}
  164. fi
  165. fi
  166. if [ ${TAINTED} -eq 1 ]; then
  167. title "activating tainted repos"
  168. /sbin/urpmi.update --urpmi-root "${BUILD_PATH}" --no-ignore Tainted\ Release Tainted\ Updates
  169. err=${?}
  170. if [ ${err} -ne 0 ]; then
  171. error "line ${LINENO} error ${err} - can't activate medias tainted : exiting"
  172. exit ${ERR_1}
  173. fi
  174. fi
  175. return 0
  176. }
  177. function installbasesystem()
  178. {
  179. # Create Build path
  180. if ! [ -d "${BUILD_PATH}" ]; then
  181. warning "Build path ( ${BUILD_PATH} ) does not exist, do you want to create it ? [Y|n] "
  182. read yn
  183. if [ -z ${yn} ] || [ ${yn} = "Y" ] || [ ${yn} = "y" ]; then
  184. title "Creating ${BUILD_PATH}"
  185. /bin/mkdir -p "${BUILD_PATH}/usr/bin" "${BUILD_PATH}/usr/lib/binfmt.d"
  186. if [ ${?} -ne 0 ]; then
  187. error "line ${LINENO} can't create ${BUILD_PATH} : exiting"
  188. exit ${ERR_1}
  189. fi
  190. else
  191. exit ${ERR_1}
  192. fi
  193. else
  194. info "Build path exists"
  195. fi
  196. title "installing basesystem"
  197. /usr/bin/dnf --installroot="${BUILD_PATH}" --setopt=ignorearch=True ${DNF_MIRROROPTS} --assumeyes install shadow-utils basesystem-minimal
  198. if [ ${?} -ne 0 ]; then
  199. error "line ${LINENO} error installing shadow-utils or basesystem-minimal : exiting"
  200. exit ${ERR_1}
  201. fi
  202. #/usr/bin/dnf --installroot="${BUILD_PATH}" --setopt=ignorearch=True ${DNF_MIRROROPTS} --assumeyes install basesystem-minimal
  203. #if [ ${?} -ne 0 ]; then
  204. # error "line ${LINENO} error installing basesystem-minimal : exiting"
  205. # exit ${ERR_1}
  206. #fi
  207. /usr/bin/dnf --installroot="${BUILD_PATH}" --setopt=ignorearch=True ${DNF_MIRROROPTS} --assumeyes install dnf dnf-plugins-core locales u-boot
  208. if [ ${?} -ne 0 ]; then
  209. error "line ${LINENO} error installing dnf or locales : exiting"
  210. exit ${ERR_1}
  211. fi
  212. /usr/bin/dnf --installroot="${BUILD_PATH}" --setopt=ignorearch=True ${DNF_MIRROROPTS} --assumeyes install urpmi
  213. if [ ${?} -ne 0 ]; then
  214. error "line ${LINENO} error installing urpmi : exiting"
  215. exit ${ERR_1}
  216. fi
  217. return 0
  218. }
  219. function preparechroot()
  220. {
  221. title "Preparing chrooting in ${BUILD_PATH}"
  222. #Copying qemu
  223. /bin/cp /bin/qemu-arm-static "${BUILD_PATH}/usr/bin/"
  224. if [ ${?} -ne 0 ]; then
  225. error "line ${LINENO} can't copy /bin/qemu-user-static to ${BUILD_PATH}/usr/bin/ : exiting"
  226. exit ${ERR_1}
  227. fi
  228. /bin/cp /usr/lib/binfmt.d/qemu-arm-static.conf "${BUILD_PATH}/usr/lib/binfmt.d"
  229. if [ ${?} -ne 0 ]; then
  230. error "line ${LINENO} can't copy /usr/lib/binfmt.d/qemu-arm-static.conf to ${BUILD_PATH}/usr/lib/binfmt.d : exiting"
  231. exit ${ERR_1}
  232. fi
  233. info "making /etc/hostname"
  234. echo "${HOSTNAME}" > "${BUILD_PATH}/etc/hostname"
  235. info "copying second stage script in ${BUILD_PATH}"
  236. #echo "/bin/cp ${CONFIG_PATH}/second_stage_install.sh ${BUILD_PATH}/"
  237. cp --preserve=mode "${CONFIG_PATH}/second_stage_install.sh" "${BUILD_PATH}/second_stage_install.sh"
  238. if [ ${?} -ne 0 ]; then
  239. error "line ${LINENO} error copying ${CONFIG_PATH}/second_stage_install.sh : exiting"
  240. exit ${ERR_1}
  241. fi
  242. info "Preparation for setting root and user account"
  243. if [ -n "${ROOT_PWD}" ]; then #If root password defined, it will be setted at the end of the chroot of the second_stage_install.sh script
  244. echo -e " /bin/passwd << EOF\n${ROOT_PWD}\n${ROOT_PWD}\nEOF\n" >>"${BUILD_PATH}/second_stage_install.sh"
  245. else
  246. info "No root password... One password will be set at the first login."
  247. echo -e " /bin/passwd -d root\n /bin/passwd -e root\n" >>"${BUILD_PATH}/second_stage_install.sh"
  248. fi
  249. if [ -n "${ID_USER}" ]; then #If user ID defined, it will be setted at the end of the chroot of the second_stage_install.sh script
  250. echo -e " /sbin/useradd ${ID_USER}\n" >>"${BUILD_PATH}/second_stage_install.sh"
  251. if [ -n "${PASSWORD}" ]; then
  252. echo -e " /bin/passwd ${ID_USER} << EOF\n${PASSWORD}\n${PASSWORD}\nEOF" >>"${BUILD_PATH}/second_stage_install.sh"
  253. else
  254. echo -e " /bin/passwd -d ${ID_USER}\n" >>"${BUILD_PATH}/second_stage_install.sh"
  255. fi
  256. else
  257. info "No user defined, no user account created."
  258. fi
  259. # info "Copying skel in root directory"
  260. # /bin/rsync -rlptH "${BUILD_PATH}/etc/skel/" "${BUILD_PATH}/root/"
  261. #This line break the default .bashrc file from the package "rootfiles" and the values as PATH (and /usr/sbin programs).
  262. postPrepareChroot
  263. if [ ${?} -ne 0 ]; then
  264. error "line ${LINENO} error in postPrepareChroot function."
  265. exit ${ERR_1}
  266. fi
  267. return 0
  268. }
  269. function jumpchroot()
  270. {
  271. title "chrooting to ${BUILD_PATH}"
  272. info "mounting dev, sys, proc directories in chroot"
  273. /bin/mount -B /dev "${BUILD_PATH}/dev"
  274. if [ ${?} -ne 0 ]; then
  275. error "line ${LINENO} error mounting ${BUILD_PATH}/dev : exiting"
  276. exit ${ERR_1}
  277. fi
  278. /bin/mount -B /sys "${BUILD_PATH}/sys"
  279. if [ ${?} -ne 0 ]; then
  280. error "line ${LINENO} error mounting ${BUILD_PATH}/sys : exiting"
  281. exit ${ERR_1}
  282. fi
  283. /bin/mount -B /proc "${BUILD_PATH}/proc"
  284. if [ ${?} -ne 0 ]; then
  285. error "line ${LINENO} error mounting ${BUILD_PATH}/proc : exiting"
  286. exit ${ERR_1}
  287. fi
  288. info "Copying resolv.conf"
  289. /bin/cp -v --preserve=mode /etc/resolv.conf "${BUILD_PATH}/etc/"
  290. if [ ${?} -ne 0 ]; then
  291. error "line ${LINENO} error copying ${BUILD_PATH}/etc/resolv.conf : exiting"
  292. exit ${ERR_1}
  293. fi
  294. if [ "$OPT" = "chroot" ]; then
  295. /sbin/chroot "${BUILD_PATH}"
  296. else
  297. /sbin/chroot --userspec root:root "${BUILD_PATH}" /bin/bash -v -c 'bash /second_stage_install.sh 2>&1'
  298. fi
  299. RET=${?}
  300. if [ ${RET} -ne 0 ]; then
  301. error "line ${LINENO} Warning : chrooting to ${BUILD_PATH} retrurn an error ${RET}"
  302. ERRORN=$((${ERRORN}+1))
  303. fi
  304. info "unmounting dev, sys, proc"
  305. /bin/umount -lf "${BUILD_PATH}/dev"
  306. if [ ${?} -ne 0 ]; then
  307. warning "line ${LINENO} Warning : error unmounting ${BUILD_PATH}/dev, continuing anyway"
  308. ERRORN=$((${ERRORN}+1))
  309. fi
  310. /bin/umount -lf "${BUILD_PATH}/sys"
  311. if [ ${?} -ne 0 ]; then
  312. warning "line ${LINENO} Warning : error unmounting ${BUILD_PATH}/sys, continuing anyway"
  313. ERRORN=$((${ERRORN}+1))
  314. fi
  315. /bin/umount -lf "${BUILD_PATH}/proc"
  316. if [ ${?} -ne 0 ]; then
  317. warning "line ${LINENO} Warning : error unmounting ${BUILD_PATH}/proc, continuing anyway"
  318. ERRORN=$((${ERRORN}+1))
  319. fi
  320. return 0
  321. }
  322. function createImageWrap()
  323. {
  324. title "Wrap image creation"
  325. preImgCreation
  326. if [ ${?} -ne 0 ]; then
  327. error "line ${LINENO} error in the process ${CONFIG_PATH}/specialFunctions.sh ."
  328. exit ${ERR_1}
  329. fi
  330. createimage
  331. if [ -z "${BOOTFS}" ]; then
  332. BOOTFS="ext4"
  333. fi
  334. formatpartitions ${BOOTFS} ext4
  335. return 0
  336. }
  337. function createimage()
  338. {
  339. title " in ${IMAGE}"
  340. if [ -f "${INSTALL_PATH}/${IMAGE}" ]; then
  341. warning "Deleting previous image"
  342. /bin/rm -f "${INSTALL_PATH}/${IMAGE}"
  343. if [ ${?} -ne 0 ]; then
  344. error "line ${LINENO} error can't remove previous image at ${INSTALL_PATH}/${IMAGE} : exiting"
  345. exit ${ERR_1}
  346. fi
  347. fi
  348. warning "please wait until end of image creation"
  349. /bin/dd if=/dev/zero of="${INSTALL_PATH}/${IMAGE}" bs=1MB count=$(( ${IMAGE_SIZE} * 1024 ))
  350. if [ ${?} -ne 0 ]; then
  351. error "line ${LINENO} can't make image at ${INSTALL_PATH}/${IMAGE} : exiting"
  352. exit ${ERR_1}
  353. fi
  354. loopingImage
  355. bunrningBootloader
  356. if [ ${?} -ne 0 ]; then
  357. error "line ${LINENO} error in the process ${CONFIG_PATH}/specialFunctions.sh ."
  358. exit ${ERR_1}
  359. fi
  360. info "making partitions"
  361. echo -e "${FDISK_SCRIPT}" | /sbin/fdisk ${DEVICE}
  362. #Activate 'pY' : /dev/loopXpY
  363. partx -vu "${DEVICE}"
  364. #Previous function give us a list of partition. It is easy to get it and define prior this list the partition.
  365. #But... How to distinguish between the boot p1 and the root p2 if both are empty and ext4 ? ...
  366. if [ 1 -eq ${SEPARATE_BOOT_PARTITION} ]; then
  367. BOOTP="${DEVICE}p1"
  368. ROOTP="${DEVICE}p2"
  369. else
  370. ROOTP="${DEVICE}p1"
  371. fi
  372. return 0
  373. }
  374. function loopingImage()
  375. {
  376. title "Looping image ..."
  377. # Mettre en place et contrôler des périphériques boucle.
  378. # -f, --find trouver le premier périphérique inutilisé
  379. # --show afficher le nom du périphérique après configuration (avec -f)
  380. DEVICE=$(/sbin/losetup -f --show "${INSTALL_PATH}/${IMAGE}")
  381. return 0
  382. }
  383. function formatpartitions()
  384. {
  385. info "Formatting partitions"
  386. if [ 1 -eq ${SEPARATE_BOOT_PARTITION} ]; then
  387. info "Boot : ${BOOTP} as ${1}"
  388. "/sbin/mkfs.${1}" "${BOOTP}"
  389. if [ ${?} -ne 0 ]; then
  390. error "line ${LINENO} error formating ${BOOTP} : exiting"
  391. /sbin/losetup -d "${DEVICE}"
  392. exit ${ERR_1}
  393. fi
  394. BOOT_UUID=$(blkid -s UUID -o value UUID "${BOOTP}")
  395. info "Boot UUID: ${BOOT_UUID}"
  396. fi
  397. info "Root : ${ROOTP} as ${2}"
  398. "/sbin/mkfs.${2}" "${ROOTP}"
  399. if [ ${?} -ne 0 ]; then
  400. error "line ${LINENO} error formating ${ROOTP} : exiting"
  401. /sbin/losetup -d "${DEVICE}"
  402. exit ${ERR_1}
  403. fi
  404. ROOT_UUID=$(blkid -s UUID -o value UUID "${ROOTP}")
  405. info "Root UUID: ${ROOT_UUID}"
  406. return 0
  407. }
  408. function generateExtlinux()
  409. {
  410. info "Generate extlinux if extlinux.conf exists."
  411. if [ -e "${CONFIG_PATH}/extlinux.conf" ]; then
  412. info "\tFound extlinux.conf"
  413. if [ ! -d "${BUILD_PATH}/boot/extlinux" ]; then
  414. info "making /boot/extlinux/extlinux.conf"
  415. /bin/rm -rf "${BUILD_PATH}/boot/extlinux"
  416. mkdir -p "${BUILD_PATH}/boot/extlinux"
  417. fi
  418. if [ ! -f "${BUILD_PATH}/boot/extlinux/extlinux.conf" ]; then
  419. info "\tTuning extlinux.conf"
  420. cp "${CONFIG_PATH}/extlinux.conf" "${BUILD_PATH}/boot/extlinux/extlinux.conf"
  421. #In order to use the UUID, a initrd file is necessary.
  422. sed -i -e "s/<UUID>/${ROOT_UUID}/g" "${BUILD_PATH}/boot/extlinux/extlinux.conf"
  423. sed -i -e "s/<BOOT_ARGS>/${BOOT_ARGS}/g" "${BUILD_PATH}/boot/extlinux/extlinux.conf"
  424. KERNEL_ID=$(basename ${BUILD_PATH}/usr/lib/linux-*)
  425. sed -i -e "s/<FDTDIR>/${KERNEL_ID}/g" "${BUILD_PATH}/boot/extlinux/extlinux.conf"
  426. fi
  427. fi
  428. }
  429. function copyingsystem()
  430. {
  431. generateExtlinux
  432. info "Remove second_stage_install.sh"
  433. /bin/rm -f "${BUILD_PATH}/second_stage_install.sh"
  434. if [ 1 -eq ${SEPARATE_BOOT_PARTITION} ]; then
  435. ARM_BOOT="${BUILD_PATH}/mnt/arm_boot"
  436. if ! [ -d "${ARM_BOOT}" ]; then
  437. rm -rf "${ARM_BOOT}"
  438. mkdir -p "${ARM_BOOT}"
  439. fi
  440. info "copying Mageia image to root partition"
  441. /bin/rsync -rlptogDH --exclude "${ARM_BOOT}/" --exclude "qemu-arm-static*" "${BUILD_PATH}/" "${ROOT}/"
  442. /bin/rsync -rlptogDH "${ARM_BOOT}/" "${BOOT}/"
  443. /bin/rsync -rlptogDH "${BUILD_PATH}/boot/" "${BOOT}/"
  444. else
  445. info "copying Mageia image to root partition"
  446. /bin/rsync -rlptogDH --exclude "qemu-arm-static*" "${BUILD_PATH}/" "${ROOT}/"
  447. fi
  448. copyingCustomSystem
  449. if [ ${?} -ne 0 ]; then
  450. error "line ${LINENO} error in the process ${CONFIG_PATH}/specialFunctions.sh ."
  451. exit ${ERR_1}
  452. fi
  453. copyingcommon
  454. sync
  455. warning "You can now burn the image ( ${INSTALL_PATH}/${IMAGE} ) on SD card"
  456. return 0
  457. }
  458. function mountPartitions(){
  459. info "mounting partitions, making mountpoint if necessary"
  460. if [ 1 -eq ${SEPARATE_BOOT_PARTITION} ]; then
  461. if ! [ -d "${BOOT}" ]; then
  462. /bin/mkdir "${BOOT}"
  463. if [ ${?} -ne 0 ]; then
  464. error "line ${LINENO} error making directory ${BOOT} : exiting"
  465. exit ${ERR_1}
  466. fi
  467. fi
  468. /bin/mount "${BOOTP}" "${BOOT}"
  469. if [ ${?} -ne 0 ]; then
  470. error "line ${LINENO} error mounting ${BOOTP} : exiting"
  471. exit ${ERR_1}
  472. fi
  473. fi
  474. if ! [ -d "${ROOT}" ]; then
  475. /bin/mkdir "${ROOT}"
  476. if [ ${?} -ne 0 ]; then
  477. error "line ${LINENO} error making directory ${ROOT} : exiting"
  478. exit ${ERR_1}
  479. fi
  480. fi
  481. /bin/mount "${ROOTP}" "${ROOT}"
  482. if [ ${?} -ne 0 ]; then
  483. error "line ${LINENO} error mounting ${ROOTP} : exiting"
  484. exit ${ERR_1}
  485. fi
  486. }
  487. function unmountingPartitions()
  488. {
  489. title "Unmounting partitions..."
  490. # Syncing devices before unmounting
  491. /usr/bin/sync
  492. if [ -z "${BOOTP}" ] && [ -z "${ROOTP}" ] ; then
  493. warning "Root partition and Boot partition not defined !"
  494. for LOOP in $(losetup -l -O NAME,BACK-FILE -n | grep "${IMAGE}" | cut -d ' ' -f 1 ) ; do
  495. IFS=$'\n'
  496. for PARTITION in $(mount -l | grep ${LOOP}); do
  497. MOUNTPOINT=$(echo "$PARTITION" | cut -d ' ' -f 3)
  498. PARTITION=$(echo "$PARTITION" | cut -d ' ' -f 1)
  499. info "unmount ${PARTITION} and remove ${MOUNTPOINT}"
  500. /usr/bin/umount "${PARTITION}"
  501. if [ ${?} -eq 0 ]; then
  502. /bin/rmdir "${MOUNTPOINT}"
  503. else
  504. error "line ${LINENO} error unmounting ${BOOT}..."
  505. fi
  506. done
  507. unset IFS
  508. done
  509. else
  510. if [ ! -z "${BOOTP}" ]; then
  511. /usr/bin/umount "${BOOTP}"
  512. if [ ${?} -eq 0 ]; then
  513. /bin/rmdir "${BOOT}"
  514. else
  515. error "line ${LINENO} error unmounting ${BOOT}..."
  516. fi
  517. fi
  518. /usr/bin/umount "${ROOTP}"
  519. if [ ${?} -eq 0 ]; then
  520. /bin/rmdir "${ROOT}"
  521. else
  522. error "line ${LINENO} error unmounting ${ROOT}..."
  523. fi
  524. fi
  525. return 0
  526. }
  527. function unloopingImage(){
  528. title "Unlooping image..."
  529. # Syncing devices before unmounting
  530. /usr/bin/sync
  531. # [root@jabztop mageia4arm (master)]# losetup -l -O NAME,BACK-FILE -n
  532. # /dev/loop0 /home/jibz/workspaces/mageia4arm/build/Mageia-7-bananaPro1.img (deleted)
  533. info "Looped devices to unmount : $(losetup -l -O NAME,BACK-FILE -n | grep "${IMAGE}" | cut -d ' ' -f 1 ) "
  534. for LOOP in $(losetup -l -O NAME,BACK-FILE -n | grep "${IMAGE}" | cut -d ' ' -f 1 ) ; do
  535. info "removing ${LOOP}"
  536. for PARTITION in ${LOOP}p* ; do
  537. partx -dv "${PARTITION}"
  538. done
  539. # losetup -d "${LOOP}"
  540. kpartx -d "${INSTALL_PATH}/${IMAGE}"
  541. done
  542. return 0
  543. }
  544. # Copying files common to all systems
  545. function copyingcommon()
  546. {
  547. title "Copying common files and configuration"
  548. rsync -rlptDH "${SOURCE_PATH}/common/" "${ROOT}/"
  549. rsync -rlptDH "${SOURCE_PATH}/tools/"*.sh "${ROOT}/usr/local/bin/"
  550. chown root:root "${ROOT}/usr/local/bin/"
  551. return 0
  552. }
  553. function mkfstab()
  554. {
  555. title "making /etc/fstab"
  556. ### BUG : /mnt/arm_boot is set to vfat for all plateforms, odroid configuration says ext4.
  557. #echo -e "proc /proc proc defaults 0 0\nUUID=${BOOT_UUID} /mnt/arm_boot vfat defaults 0 0\nUUID=${ROOT_UUID} / ext4 defaults 0 0" > "${BUILD_PATH}/etc/fstab"
  558. #echo -e "proc\t/proc\tproc\tdefaults\t0\t0\nUUID=${BOOT_UUID}\t/mnt/arm_boot\t${BOOTFS}\tdefaults\t0\t0\nUUID=${ROOT_UUID}\t/\text4\tdefaults\t0\t0" > "${BUILD_PATH}/etc/fstab"
  559. if [ 1 -eq ${SEPARATE_BOOT_PARTITION} ]; then
  560. echo -e "proc\t/proc\tproc\tdefaults\t0\t0\nUUID=${BOOT_UUID}\t/mnt/arm_boot\t${BOOTFS}\tdefaults\t0\t0\nUUID=${ROOT_UUID}\t/\text4\tdefaults\t0\t0" > "${BUILD_PATH}/etc/fstab"
  561. else
  562. echo -e "proc\t/proc\tproc\tdefaults\t0\t0\nUUID=${ROOT_UUID}\t/\text4\tdefaults\t0\t0" > "${BUILD_PATH}/etc/fstab"
  563. fi
  564. return 0
  565. }
  566. # cleaning build space
  567. function clean()
  568. {
  569. title "Cleaning"
  570. unmountingPartitions
  571. unloopingImage
  572. # Removing old Build directory
  573. if [ -d "${BUILD_PATH}" ]; then
  574. info "Removing ${BUILD_PATH}"
  575. /bin/rm -Rf "${BUILD_PATH}"
  576. else
  577. warning "${BUILD_PATH} does not exists"
  578. fi
  579. # removing old image
  580. if [ -e "${INSTALL_PATH}/${IMAGE}" ]; then
  581. info "Removing ${IMAGE}"
  582. /bin/rm -f "${INSTALL_PATH}/${IMAGE}"
  583. else
  584. warning "${IMAGE} does not exists"
  585. fi
  586. return 0
  587. }
  588. function preImgCreation()
  589. {
  590. error "This function is called if no sourced file about fdisk was lauched."
  591. return 1
  592. }
  593. function postPrepareChroot()
  594. {
  595. error "This function is called if no sourced file is containing postPrepareChroot function."
  596. return 1
  597. }
  598. function bunrningBootloader()
  599. {
  600. error "This function is called if no sourced file is containing bunrningBootloader function."
  601. return 1
  602. }
  603. function copyingCustomSystem()
  604. {
  605. error "This function is called if no sourced file is containing bunrningBootloader function."
  606. return 1
  607. }
  608. ERRORN=0
  609. ERR_1=1
  610. ERR_DEFAULT_CONFIG=2
  611. ERR_NO_CONFIG_FILE=3
  612. ERR_NOT_ROOT=4
  613. ERR_DEPENDENCY_MISSING=5
  614. ERR_NO_SPACE=6
  615. ERR_7=7
  616. ERR_8=8
  617. ERR_9=9
  618. SEPARATE_BOOT_PARTITION=1
  619. #######################
  620. # PROGRAMM START HERE #
  621. #######################
  622. info ${0}
  623. #Check dependencies :
  624. #if [ -e /usr/bin/qemu-arm-static ]; then
  625. # error "qemu-user-static package is needed."
  626. # exit ${ERR_DEPENDENCY_MISSING}
  627. #fi
  628. #if [ 0 -ne $(id -u) ]; then
  629. # error "Script need to be run as root."
  630. # exit ${ERR_NOT_ROOT}
  631. #fi
  632. SOURCE_PATH="$(/bin/dirname "$(readlink -f "${0}")")"
  633. INSTALL_PATH="$(pwd)/build"
  634. # FILES_PATH="${SOURCE_PATH}/files"
  635. PLATFORMS_PATH="${SOURCE_PATH}/platforms"
  636. CMDNAME=$(/bin/basename "${0}")
  637. if [ ${#} == 0 ]; then
  638. help
  639. exit
  640. fi
  641. # parsing commandline
  642. TEMP=$(getopt -o h,a --long all,help,clean,create-chroot,add-urpmimedia,create-image,,config:,target:,target-version:,chroot,bootfs:,install-basesystem,update-mirror,build-path:,size:,nonfree,tainted -n ${CMDNAME} -- "${@}")
  643. if [ ${?} -ne 0 ] ; then error "line ${LINENO} Failed parsing options." >&2 ; exit ${ERR_1} ; fi
  644. eval set -- "${TEMP}"
  645. echo "${TEMP}"
  646. # Note the quotes around `$TEMP': they are essential! Or not, $( ) do the same as ` `. But there are the ` ' used ?
  647. while true; do
  648. case "${1}" in
  649. -h|--help)
  650. help
  651. exit 0
  652. ;;
  653. -a|--all)
  654. OPT="all"
  655. shift 1
  656. ;;
  657. --clean)
  658. OPT="clean"
  659. shift
  660. ;;
  661. --size)
  662. IMAGE_SIZE_P=${2}
  663. shift 2
  664. ;;
  665. --build-path)
  666. INSTALL_PATH_P=$(readlink -f "${2}")
  667. shift 2
  668. ;;
  669. --chroot)
  670. if [ -z ${OPT} ]; then
  671. OPT="chroot"
  672. fi
  673. shift
  674. ;;
  675. --create-chroot)
  676. if [ -z ${OPT} ]; then
  677. OPT="createchroot"
  678. fi
  679. shift
  680. ;;
  681. --add-urpmimedia)
  682. if [ -z ${OPT} ]; then
  683. OPT="addurpmimedia"
  684. fi
  685. shift
  686. ;;
  687. --update-mirror)
  688. if [ -z ${OPT} ]; then
  689. OPT="updatemirror"
  690. fi
  691. shift
  692. ;;
  693. --install-basesystem)
  694. if [ -z ${OPT} ]; then
  695. OPT="installbasesystem"
  696. fi
  697. shift
  698. ;;
  699. --create-image)
  700. if [ -z ${OPT} ]; then
  701. CREATEIMAGE=true
  702. OPT="createimage"
  703. fi
  704. shift
  705. ;;
  706. --target)
  707. TARGET_P=${2}
  708. shift 2
  709. ;;
  710. --target-version)
  711. TARGET_VERSION_P=${2}
  712. shift 2
  713. ;;
  714. --config)
  715. CONFIG_PATH="${PLATFORMS_PATH}/${2}"
  716. shift 2
  717. ;;
  718. --bootfs)
  719. BOOTFS_P=${2}
  720. shift 2
  721. ;;
  722. --nonfree)
  723. NONFREE_P=1
  724. shift
  725. ;;
  726. --tainted)
  727. TAINTED_P=1
  728. shift
  729. ;;
  730. --)
  731. shift
  732. break;;
  733. *)
  734. error "Parameter ${1} does not exists "
  735. exit ${ERR_1};;
  736. esac
  737. done
  738. # path of config file
  739. if ! [ -d "${CONFIG_PATH}" ]; then
  740. info " Config path does not exists, defaulting to ./platforms/${TARGET}"
  741. CONFIG_PATH="${PLATFORMS_PATH}/${TARGET}"
  742. warning "Do you want to create it and to copy the template file in? [Y|n] "
  743. read yn
  744. if [ -z ${yn} ] || [ ${yn} = "Y" ] || [ ${yn} = "y" ]; then
  745. /usr/bin/mkdir "${CONFIG_PATH}/"
  746. /usr/bin/cp --preserve=mode "${SOURCE_PATH}/mageia4arm.cfg.template" "${CONFIG_PATH}/mageia4arm.cfg"
  747. warning "You need now to modify the config file (${CONFIG_PATH}/mageia4arm.cfg) and relaunch the script"
  748. exit ${ERR_DEFAULT_CONFIG}
  749. else
  750. error "Error: Can't continue without config file, exiting"
  751. exit ${ERR_NO_CONFIG_FILE}
  752. fi
  753. fi
  754. if [ -e "${CONFIG_PATH}/mageia4arm.cfg" ]; then
  755. info "using ${CONFIG_PATH}/mageia4arm.cfg as config"
  756. source "${CONFIG_PATH}/mageia4arm.cfg" #NOTE1 : Here is sourced a file with variables.
  757. else
  758. warning "Config file does not exists, do you want to copy template ? [Y|n] "
  759. read yn
  760. if [ -z ${yn} ] || [ ${yn} = "Y" ] || [ ${yn} = "y" ]; then
  761. /usr/bin/cp --preserve=mode "${SOURCE_PATH}/mageia4arm.cfg.template" "${CONFIG_PATH}/mageia4arm.cfg"
  762. warning "You need now to modify the config file (${CONFIG_PATH}/mageia4arm.cfg) and relaunch the script"
  763. exit ${ERR_DEFAULT_CONFIG}
  764. fi
  765. fi
  766. if ! [ -z "${IMAGE_SIZE_P}" ]; then
  767. IMAGE_SIZE=${IMAGE_SIZE_P}
  768. fi
  769. if ! [ -z "${INSTALL_PATH_P}" ]; then
  770. INSTALL_PATH=${INSTALL_PATH_P}
  771. fi
  772. if ! [ -z "${TARGET_P}" ]; then
  773. TARGET=${TARGET_P}
  774. fi
  775. if ! [ -z "${TARGET_VERSION_P}" ]; then
  776. TARGET_VERSION=${TARGET_VERSION_P}
  777. fi
  778. if ! [ -z "${BOOTFS_P}" ]; then
  779. BOOTFS=${BOOTFS_P}
  780. fi
  781. if ! [ -z "${NONFREE_P}" ]; then
  782. NONFREE=${NONFREE_P}
  783. else
  784. NONFREE=0
  785. fi
  786. if ! [ -z "${TAINTED_P}" ]; then
  787. TAINTED=${TAINTED_P}
  788. else
  789. TAINTED=0
  790. fi
  791. info "Option: "${OPT}
  792. IMAGE="Mageia-${MAGEIA_VERSION}-${TARGET}${TARGET_VERSION}.img"
  793. BOOT="/mnt/boot"
  794. ROOT="/mnt/root"
  795. BUILD_PATH="${INSTALL_PATH}/build-${TARGET}${TARGET_VERSION}"
  796. ARM_VERSION="armv7hl"
  797. # Assigne a script for creating a particular target image (rpi, odroid, ...)
  798. if [ -e "${CONFIG_PATH}/specialFunctions.sh" ]; then
  799. source "${CONFIG_PATH}/specialFunctions.sh"
  800. fi
  801. info "target : ${TARGET}"
  802. info "target_version : ${TARGET_VERSION}"
  803. info "source path: ${SOURCE_PATH}"
  804. info "Install path: ${INSTALL_PATH}"
  805. info "Build path: ${BUILD_PATH}"
  806. info "Commande : ${CMDNAME}"
  807. info "Firmware path : ${FIRMWARE_PATH}"
  808. info "Firmware dir : ${FIRMWARE_DIR}"
  809. # Defining default image size to 7 go
  810. if [[ "${IMAGE_SIZE}" -lt 2 ]] || [[ "${IMAGE_SIZE}" -gt 128 ]]; then
  811. IMAGE_SIZE=7
  812. fi
  813. # change dir to install path and create it if not existing
  814. if [ "${OPT}" != "clean" ]; then
  815. info "cd ${INSTALL_PATH}"
  816. if ! [ -e "${INSTALL_PATH}" ]; then
  817. /bin/mkdir -p "${INSTALL_PATH}"
  818. if [ -z ${?} ]; then
  819. error "line ${LINENO} can't make directory ${INSTALL_PATH} , exiting"
  820. exit ${ERR_1}
  821. fi
  822. fi
  823. cd "${INSTALL_PATH}"
  824. if [ -z ${?} ]; then
  825. error "line ${LINENO} can't change to directory ${INSTALL_PATH} , exiting"
  826. exit ${ERR_1}
  827. fi
  828. fi
  829. #if no parameters then display help message
  830. if [ -z ${OPT} ]; then
  831. OPT="--help"
  832. fi
  833. info "Image size is: ${IMAGE_SIZE} GB"
  834. case ${OPT} in
  835. "clean")
  836. clean
  837. ;;
  838. "all")
  839. verify_disk_space
  840. if [ ${?} -ne 0 ]; then
  841. echo -e "Not enough space on disk\nDo you want to continue anyway ? [Y,n]"
  842. read yn
  843. if [ ${yn} = "n" ]; then
  844. exit ${ERR_NO_SPACE}
  845. fi
  846. fi
  847. createImageWrap #Create the empty .img
  848. createchroot #Check qemu and activate it
  849. genusemirroroptions #Generate mirror options, if needed
  850. installbasesystem #Generate the rootfs, rootfiles, ...
  851. enableextrarepos
  852. addurpmimedia
  853. mkfstab
  854. preparechroot
  855. jumpchroot
  856. #Check before is useless (with $MIRROR
  857. info "Use mirrorlist to light one server."
  858. MIRROR=
  859. genusemirroroptions
  860. enableextrarepos
  861. addurpmimedia
  862. mountPartitions
  863. copyingsystem
  864. unmountingPartitions
  865. unloopingImage
  866. ;;
  867. "createchroot")
  868. createchroot
  869. ;;
  870. "chroot")
  871. jumpchroot
  872. ;;
  873. "addurpmimedia")
  874. addurpmimedia
  875. ;;
  876. "createimage")
  877. verify_disk_space
  878. if [ ${?} -ne 0 ]; then
  879. warning "Not enough space on disk"
  880. exit ${ERR_NO_SPACE}
  881. fi
  882. createImageWrap
  883. ;;
  884. "installbasesystem")
  885. installbasesystem
  886. ;;
  887. esac
  888. if [ ${ERRORN} -ne 0 ]; then
  889. warning "Some errors occurs : ${ERRORN} errors"
  890. fi
  891. exit ${ERRORN}