5f0bb51c4efb54e96bffa14bca529c5a9543d34f
[genkernel.git] / gen_bootloader.sh
1 set_bootloader() {
2         case "${BOOTLOADER}" in
3                 grub)
4                         set_bootloader_grub
5                         ;;
6                 *)
7                         print_warning "Bootloader ${BOOTLOADER} is not currently supported"
8                         ;;
9         esac
10 }
11
12 set_bootloader_read_fstab() {
13         local ROOTFS=$(awk 'BEGIN{RS="((#[^\n]*)?\n)"}( $2 == "/" ) { print $1; exit }' /etc/fstab)
14         local BOOTFS=$(awk 'BEGIN{RS="((#[^\n]*)?\n)"}( $2 == "'${BOOTDIR}'") { print $1; exit }' /etc/fstab)
15
16         # If ${BOOTDIR} is not defined in /etc/fstab, it must be the same as /
17         [ -z "${BOOTFS}" ] && BOOTFS=${ROOTFS}
18
19         echo "${ROOTFS} ${BOOTFS}"
20 }
21
22 set_bootloader_grub_read_device_map() {
23         # Read GRUB device map
24         [ ! -d ${TEMP} ] && mkdir ${TEMP}
25         echo "quit" | grub --batch --device-map=${TEMP}/grub.map &>/dev/null
26         echo "${TEMP}/grub.map"
27 }
28
29 set_bootloader_grub() {
30         local GRUB_CONF="${BOOTDIR}/grub/grub.conf"
31
32         print_info 1 "Adding kernel to ${GRUB_CONF}..."
33
34         if [ ! -e ${GRUB_CONF} ]
35         then
36                 local GRUB_BOOTFS
37                 if [ -n "${BOOTFS}" ]
38                 then
39                         GRUB_BOOTFS=$BOOTFS
40                 else
41                         GRUB_BOOTFS=$(set_bootloader_read_fstab | cut -d' ' -f2)
42                 fi
43
44                 # Get the GRUB mapping for our device
45                 local GRUB_BOOT_DISK1=$(echo ${GRUB_BOOTFS} | sed -e 's#\(/dev/.\+\)[[:digit:]]\+#\1#')
46                 local GRUB_BOOT_DISK=$(awk '{if ($2 == "'${GRUB_BOOT_DISK1}'") {gsub(/(\(|\))/, "", $1); print $1;}}' ${TEMP}/grub.map)
47                 local GRUB_BOOT_PARTITION=$(($(echo ${GRUB_BOOTFS} | sed -e 's#/dev/.\+\([[:digit:]]?*\)#\1#') - 1))
48
49                 if [ -n "${GRUB_BOOT_DISK}" -a -n "${GRUB_BOOT_PARTITION}" ]
50                 then
51
52                         # Create grub configuration directory and file if it doesn't exist.
53                         [ ! -d `dirname ${GRUB_CONF}` ] && mkdir -p `dirname ${GRUB_CONF}`
54
55                         touch ${GRUB_CONF}
56                         echo 'default 0' >> ${GRUB_CONF}
57                         echo 'timeout 5' >> ${GRUB_CONF}
58                         echo "root (${GRUB_BOOT_DISK},${GRUB_BOOT_PARTITION})" >> ${GRUB_CONF}
59                         echo >> ${GRUB_CONF}
60
61                         # Add grub configuration to grub.conf   
62                         echo "# Genkernel generated entry, see GRUB documentation for details" >> ${GRUB_CONF}
63                         echo "title=Gentoo Linux ($KV)" >> ${GRUB_CONF}
64                         if [ "${BUILD_INITRD}" -eq '0' ]
65                         then
66                                 echo -e "\tkernel /kernel-${KNAME}-${ARCH}-${KV} root=${GRUB_ROOTFS}" >> ${GRUB_CONF}
67                         else
68                                 echo -e "\tkernel /kernel-${KNAME}-${ARCH}-${KV} root=/dev/ram0 init=/linuxrc real_root=${GRUB_ROOTFS}" >> ${GRUB_CONF}
69                                 if [ "${PAT}" -gt '4' ]
70                                 then
71                                     echo -e "\tinitrd /initramfs-${KNAME}-${ARCH}-${KV}" >> ${GRUB_CONF}
72                                 fi
73                         fi
74                         echo >> ${GRUB_CONF}
75                 else
76                         print_error 1 "Error! ${BOOTDIR}/grub/grub.conf does not exist and the correct settings can not be automatically detected."
77                         print_error 1 "Please manually create your ${BOOTDIR}/grub/grub.conf file."
78                 fi
79
80         else
81                 # The grub.conf already exists, so let's try to duplicate the default entry
82                 set_bootloader_grub_duplicate_default "${GRUB_CONF}"
83         fi
84
85 }
86
87 set_bootloader_grub_duplicate_default_replace_kernel_initrd() {
88         sed -r -e "/^[[:space:]]*kernel/s/kernel-[[:alnum:][:punct:]]+/kernel-${KNAME}-${ARCH}-${KV}/" - |
89         sed -r -e "/^[[:space:]]*initrd/s/init(rd|ramfs)-[[:alnum:][:punct:]]+/init\1-${KNAME}-${ARCH}-${KV}/"
90 }
91
92 set_bootloader_grub_duplicate_default() {
93         local GRUB_CONF=$1
94         local GRUB_CONF_TMP="${GRUB_CONF}.tmp"
95         
96         line_count=$(wc -l < "${GRUB_CONF}")
97         line_nums="$(grep -n "^title" "${GRUB_CONF}" | cut -d: -f1)"
98         if [ -z "${line_nums}" ]; then
99                 print_error 1 "No current 'title' entries found in your grub.conf...skipping update"
100                 return 0
101         fi
102         line_nums="${line_nums} $((${line_count}+1))"
103
104         # Find default entry
105         default=$(sed -rn '/^[[:space:]]*default[[:space:]=]/s/^.*default[[:space:]=]+([[:alnum:]]+).*$/\1/p' "${GRUB_CONF}")
106         if ! echo ${default} | grep -q '^[0-9]\+$'; then
107                 print_error 1 "We don't support non-numeric (such as 'saved') default values...skipping update"
108                 return 0
109         fi
110
111         # Grub defaults are 0 based, cut is 1 based
112         # Figure out where the default entry lives
113         startstop=$(echo ${line_nums} | cut -d" " -f$((${default}+1))-$((${default}+2)))
114         startline=$(echo ${startstop} | cut -d" " -f1)
115         stopline=$(echo ${startstop} | cut -d" " -f2)
116
117         # Write out the bits before the default entry
118         sed -n 1,$((${startline}-1))p "${GRUB_CONF}" > "${GRUB_CONF_TMP}"
119
120         # Put in our title
121         echo "title=Gentoo Linux (${KV})" >> "${GRUB_CONF_TMP}"
122
123         # Pass the default entry (minus the title) through to the replacement function and pipe the output to GRUB_CONF_TMP
124         sed -n $((${startline}+1)),$((${stopline}-1))p "${GRUB_CONF}" | set_bootloader_grub_duplicate_default_replace_kernel_initrd >> "${GRUB_CONF_TMP}"
125
126         # Finish off with everything including the previous default entry
127         sed -n ${startline},${line_count}p "${GRUB_CONF}" >> "${GRUB_CONF_TMP}"
128
129         cp "${GRUB_CONF}" "${GRUB_CONF}.bak"
130         cp "${GRUB_CONF_TMP}" "${GRUB_CONF}"
131         rm "${GRUB_CONF_TMP}"
132 }