| 41 | = Grub2 = |
| 42 | |
| 43 | Most of method of the previous is mostly based on grub legacy. And most Linux distributions have updated to Grub2. So in the following, we just introduce how to build a i386 simulation environment based on Grub2 and QEMU. |
| 44 | |
| 45 | This is tested on Ubuntu-13.04 and the Grub2 also has been installed. |
| 46 | |
| 47 | #!/bin/bash |
| 48 | # This is a shell script to create a QEMU simulation environment |
| 49 | # based on Grub2 for RTEMS. |
| 50 | |
| 51 | |
| 52 | image="disk.img" |
| 53 | |
| 54 | # Quit when error occurs. |
| 55 | set -e |
| 56 | |
| 57 | create="yes" |
| 58 | update="no" |
| 59 | |
| 60 | # Hack to make everything owned by the original user. |
| 61 | user=`who am i | awk '{print $1}'` |
| 62 | group=`groups $user | awk '{print $3}'` |
| 63 | |
| 64 | usage() { |
| 65 | cat <<EOF |
| 66 | Usage: mkimage.sh [OPTIONS] [FILE] |
| 67 | Create/Update a bootable hard-disk image with Grub2. |
| 68 | -h, --help printf this message and exit |
| 69 | -c, --create create the disk image, default |
| 70 | -u, --update mount the image to /mnt |
| 71 | FILE the file you want to create or update, default ${image} |
| 72 | EOF |
| 73 | } |
| 74 | |
| 75 | |
| 76 | # Check the arguments |
| 77 | while test $# -gt 0 |
| 78 | do |
| 79 | option=$1 |
| 80 | shift |
| 81 | |
| 82 | case "$option" in |
| 83 | # help |
| 84 | -h | --help ) |
| 85 | usage |
| 86 | exit 0 ;; |
| 87 | |
| 88 | # create the disk image |
| 89 | -c | --create ) |
| 90 | create="yes" ;; |
| 91 | |
| 92 | # update the kernel/grub.cfg |
| 93 | -u | --update ) |
| 94 | update="yes" |
| 95 | create="no" ;; |
| 96 | |
| 97 | -* ) |
| 98 | echo "Unrecognized option $option" 1>&2 |
| 99 | echo 1>&2 |
| 100 | usage |
| 101 | exit 1 ;; |
| 102 | * ) |
| 103 | image="$option" ;; |
| 104 | esac |
| 105 | done |
| 106 | |
| 107 | create_image() { |
| 108 | # Create the actual disk image - 128MB |
| 109 | dd if=/dev/zero of=${image} bs=512 count=32130 2>/dev/null |
| 110 | chown ${user}:${group} ${image} |
| 111 | echo "Create disk image ${image}" |
| 112 | # Setup the loopback device, and reture the devie name. |
| 113 | lodev=`losetup -f --show ${image}` |
| 114 | trap 'losetup -d ${lodev}; exit $?' INT TERM EXIT |
| 115 | loname=${lodev##*/} |
| 116 | # Make the partition table, partition and set it bootable. |
| 117 | parted -a minimal --script ${lodev} mklabel msdos mkpart primary ext2 1M 100% \ |
| 118 | set 1 boot on 2>/dev/null |
| 119 | echo "Create an msdos partion table, set bootable bit" |
| 120 | |
| 121 | ##### +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| 122 | # Get the start sectors. |
| 123 | start=`fdisk -lu ${lodev} | grep "${loname}p1" | awk '{ print $3}'` |
| 124 | # Find the first unused loop device. |
| 125 | lonxt=`losetup -f` |
| 126 | # Create a loop device for this partition, like /dev/sda and /dev/sda0 work. |
| 127 | losetup -o $(expr 512 \* ${start}) ${lonxt} ${lodev} |
| 128 | trap 'losetup -d ${lonxt}; losetup -d ${lodev}; exit $?' INT TERM EXIT |
| 129 | ##### +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| 130 | |
| 131 | ##### +++++++++++++++++ The other method, we need kpartx support ++++++++++++++++ |
| 132 | # Notify the kernel about the new partion. Map the partition from the image file. |
| 133 | # kpartx -av ${lodev} &>/dev/null |
| 134 | # sleep a sec, wait for kpartx to create the device nodes. |
| 135 | # sleep 1 |
| 136 | # Find the first unused loop device. |
| 137 | # lonxt=`losetup -f` |
| 138 | # Create a loop device for this partition, like /dev/sda and /dev/sda0 work. |
| 139 | # losetup ${lonxt} /dev/mapper/${loname}p1 |
| 140 | ##### +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| 141 | |
| 142 | # Make an ext2 filesystem on the first partition. |
| 143 | mkfs.ext2 ${lonxt} &>/dev/null |
| 144 | echo "Create new filesystem ext2" |
| 145 | # Mount the filesystem via loopback. |
| 146 | mount ${lonxt} /mnt |
| 147 | trap 'umount /mnt; losetup -d ${lonxt}; losetup -d ${lodev}; exit $?' INT TERM EXIT |
| 148 | mkdir -p /mnt/boot/grub |
| 149 | echo 'source (hd1,msdos1)/grub.cfg'>/mnt/boot/grub/grub.cfg |
| 150 | |
| 151 | ##### +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| 152 | # --root-directory=/mnt equal to --boot-directory=/mnt/boot |
| 153 | # --no-floppy or --allow-floppy |
| 154 | # grub-install --allow-floppy --boot-directory=/mnt/boot \ |
| 155 | # --disk-module=biosdisk \ |
| 156 | # --modules="ext2 part_msdos" --force ${lodev} |
| 157 | ##### +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| 158 | |
| 159 | |
| 160 | ##### +++++++++++++++++ The other method, we do it step by step +++++++++++++++++ |
| 161 | mkdir -p /mnt/boot/grub/i386-pc |
| 162 | cp /usr/lib/grub/i386-pc/* /mnt/boot/grub/i386-pc |
| 163 | |
| 164 | # Make a bootable image of GRUB. |
| 165 | grub-mkimage -d /usr/lib/grub/i386-pc -O i386-pc --output=core.img \ |
| 166 | --prefix=\(,msdos1\)/boot/grub ext2 part_msdos biosdisk search_fs_uuid |
| 167 | mv core.img /mnt/boot/grub/i386-pc |
| 168 | # Set up a device to boot using GRUB. |
| 169 | grub-bios-setup --allow-floppy --force --directory=/mnt/boot/grub/i386-pc \ |
| 170 | --device-map= ${lodev} |
| 171 | ##### +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| 172 | echo "Grub2 installed" |
| 173 | |
| 174 | sync |
| 175 | trap - INT TERM EXIT |
| 176 | umount /mnt |
| 177 | losetup -d ${lonxt} |
| 178 | ##### +++++++++++++++++ The other method, we need kpartx support ++++++++++++++++ |
| 179 | # kpartx -dv ${lodev} 2>/dev/null |
| 180 | # sleep 1 |
| 181 | ##### +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| 182 | losetup -d ${lodev} |
| 183 | echo "Done" |
| 184 | } |
| 185 | |
| 186 | |
| 187 | update_image() { |
| 188 | # You can use the following script update the image. |
| 189 | start=`fdisk -lu ${image} | grep "${image}1" | awk '{ print $3}'` |
| 190 | mount -o loop,offset=$(expr 512 \* ${start}) ${image} /mnt |
| 191 | exit 0 |
| 192 | cp kernel /mnt |
| 193 | cp grub.cfg /mnt/boot/grub |
| 194 | sync |
| 195 | umount mnt |
| 196 | } |
| 197 | |
| 198 | |
| 199 | if [ "${create}" = "yes" ]; then |
| 200 | echo "Create a bootable hard-disk image with Grub2" |
| 201 | create_image |
| 202 | fi |
| 203 | |
| 204 | if [ "${update}" = "yes" ]; then |
| 205 | echo "Update the bootable hard-disk image" |
| 206 | update_image |
| 207 | fi |