diff options
author | Darren Hart <dvhart@linux.intel.com> | 2011-11-23 17:56:12 -0800 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2011-11-30 22:18:08 +0000 |
commit | eb4aa3483b1129a7137983ed54596030a5ccba2b (patch) | |
tree | 92a8309a4b4c5d51bdd9efe0da502b62ae913f23 | |
parent | bcbd57aae576fa262c83f435bccf3bc3184e5506 (diff) | |
download | poky-eb4aa3483b1129a7137983ed54596030a5ccba2b.tar.gz |
bootimg: Add grub-efi support
Create a new grub-efi.bbclass and integrate it into bootimg alongside the
syslinux support. This new class uses the output from the grub-efi-native
recipe. Thanks goes to Josef Ahmad <josef.ahmad@intel.com> for the original
build_grub_cfg() routine.
The EFI features are only added to the image if MACHINE_FEATURES contains
"efi". The resulting images are therefor either legacy boot only (like they
were originally) or legacy boot and EFI boot.
A new "dummy.bbclass" was added to allow for the conditional include
of grub-efi. This makes it so if efi support is not to be built in, we
don't spend time building grub-efi-native just because the include adds
the dependency.
There is a bug in the mkdosfs tool from the dosfstools package which causes
it to crash when the directory passed with the -d parameter contains
sub-directories. An /EFI/BOOT directory is required for a proper EFI
installation. Until it is fixed, we install to the top level directory
for the hddimg.
(From OE-Core rev: be95f54495bf9e03062f86b929c66cab6e385a03)
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
Signed-off-by: Josef Ahmad <josef.ahmad@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r-- | meta/classes/bootimg.bbclass | 13 | ||||
-rw-r--r-- | meta/classes/dummy.bbclass | 2 | ||||
-rw-r--r-- | meta/classes/grub-efi.bbclass | 140 |
3 files changed, 155 insertions, 0 deletions
diff --git a/meta/classes/bootimg.bbclass b/meta/classes/bootimg.bbclass index 0554ffa00a..ce95801bff 100644 --- a/meta/classes/bootimg.bbclass +++ b/meta/classes/bootimg.bbclass | |||
@@ -35,7 +35,12 @@ ISODIR = "${S}/cd" | |||
35 | BOOTIMG_VOLUME_ID ?= "boot" | 35 | BOOTIMG_VOLUME_ID ?= "boot" |
36 | BOOTIMG_EXTRA_SPACE ?= "512" | 36 | BOOTIMG_EXTRA_SPACE ?= "512" |
37 | 37 | ||
38 | EFI = ${@base_contains("MACHINE_FEATURES", "efi", "1", "0", d)} | ||
39 | EFI_CLASS = ${@base_contains("MACHINE_FEATURES", "efi", "grub-efi", "dummy", d)} | ||
40 | |||
38 | inherit syslinux | 41 | inherit syslinux |
42 | inherit ${EFI_CLASS} | ||
43 | |||
39 | 44 | ||
40 | build_iso() { | 45 | build_iso() { |
41 | # Only create an ISO if we have an INITRD and NOISO was not set | 46 | # Only create an ISO if we have an INITRD and NOISO was not set |
@@ -47,6 +52,9 @@ build_iso() { | |||
47 | install -d ${ISODIR} | 52 | install -d ${ISODIR} |
48 | 53 | ||
49 | syslinux_iso_populate | 54 | syslinux_iso_populate |
55 | if [ "${EFI}" = "1" ]; then | ||
56 | grubefi_iso_populate | ||
57 | fi | ||
50 | 58 | ||
51 | mkisofs -V ${BOOTIMG_VOLUME_ID} \ | 59 | mkisofs -V ${BOOTIMG_VOLUME_ID} \ |
52 | -o ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.iso \ | 60 | -o ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.iso \ |
@@ -63,6 +71,9 @@ build_hddimg() { | |||
63 | if [ "${NOHDD}" != "1" ] ; then | 71 | if [ "${NOHDD}" != "1" ] ; then |
64 | install -d ${HDDDIR} | 72 | install -d ${HDDDIR} |
65 | syslinux_hddimg_populate | 73 | syslinux_hddimg_populate |
74 | if [ "${EFI}" = "1" ]; then | ||
75 | grubefi_hddimg_populate | ||
76 | fi | ||
66 | 77 | ||
67 | # Determine the block count for the final image | 78 | # Determine the block count for the final image |
68 | BLOCKS=`du -bks ${HDDDIR} | cut -f 1` | 79 | BLOCKS=`du -bks ${HDDDIR} | cut -f 1` |
@@ -83,6 +94,8 @@ build_hddimg() { | |||
83 | 94 | ||
84 | python do_bootimg() { | 95 | python do_bootimg() { |
85 | bb.build.exec_func('build_syslinux_cfg', d) | 96 | bb.build.exec_func('build_syslinux_cfg', d) |
97 | if d.getVar("EFI", True) == "1": | ||
98 | bb.build.exec_func('build_grub_cfg', d) | ||
86 | bb.build.exec_func('build_hddimg', d) | 99 | bb.build.exec_func('build_hddimg', d) |
87 | bb.build.exec_func('build_iso', d) | 100 | bb.build.exec_func('build_iso', d) |
88 | } | 101 | } |
diff --git a/meta/classes/dummy.bbclass b/meta/classes/dummy.bbclass new file mode 100644 index 0000000000..8c300717d0 --- /dev/null +++ b/meta/classes/dummy.bbclass | |||
@@ -0,0 +1,2 @@ | |||
1 | # An empty bbclass to facilitate dynamic inherit, include, | ||
2 | # and require statements. | ||
diff --git a/meta/classes/grub-efi.bbclass b/meta/classes/grub-efi.bbclass new file mode 100644 index 0000000000..333e6c53c7 --- /dev/null +++ b/meta/classes/grub-efi.bbclass | |||
@@ -0,0 +1,140 @@ | |||
1 | # grub-efi.bbclass | ||
2 | # Copyright (c) 2011, Intel Corporation. | ||
3 | # All rights reserved. | ||
4 | # | ||
5 | # Released under the MIT license (see packages/COPYING) | ||
6 | |||
7 | # Provide grub-efi specific functions for building bootable images. | ||
8 | |||
9 | # External variables | ||
10 | # ${INITRD} - indicates a filesystem image to use as an initrd (optional) | ||
11 | # ${ROOTFS} - indicates a filesystem image to include as the root filesystem (optional) | ||
12 | # ${LABELS} - a list of targets for the automatic config | ||
13 | # ${APPEND} - an override list of append strings for each label | ||
14 | # ${GRUB_OPTS} - additional options to add to the config, ';' delimited # (optional) | ||
15 | # ${GRUB_TIMEOUT} - timeout before executing the deault label (optional) | ||
16 | |||
17 | do_bootimg[depends] += "grub-efi-${TARGET_ARCH}-native:do_deploy" | ||
18 | |||
19 | GRUBCFG = "grub.cfg" | ||
20 | GRUB_TIMEOUT ?= "10" | ||
21 | #FIXME: build this from the machine config | ||
22 | GRUB_OPTS ?= "serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1" | ||
23 | |||
24 | # FIXME: add EFI/BOOT to GRUB_HDDDIR once the mkdosfs subdir bug is resolved | ||
25 | # http://bugzilla.yoctoproject.org/show_bug.cgi?id=1783 | ||
26 | EFIDIR = "/EFI/BOOT" | ||
27 | GRUB_HDDDIR = "${HDDDIR}" | ||
28 | GRUB_ISODIR = "${ISODIR}${EFIDIR}" | ||
29 | |||
30 | grubefi_populate() { | ||
31 | DEST=$1 | ||
32 | |||
33 | install -d ${DEST} | ||
34 | |||
35 | install -m 0644 ${STAGING_DIR_HOST}/kernel/bzImage ${DEST}/vmlinuz | ||
36 | |||
37 | if [ -n "${INITRD}" ] && [ -s "${INITRD}" ]; then | ||
38 | install -m 0644 ${INITRD} ${DEST}/initrd | ||
39 | fi | ||
40 | |||
41 | if [ -n "${ROOTFS}" ] && [ -s "${ROOTFS}" ]; then | ||
42 | install -m 0644 ${ROOTFS} ${DEST}/rootfs.img | ||
43 | fi | ||
44 | |||
45 | GRUB_IMAGE="bootia32.efi" | ||
46 | if [ "${TARGET_ARCH}" = "x86_64" ]; then | ||
47 | GRUB_IMAGE="bootx64.efi" | ||
48 | fi | ||
49 | install -m 0644 ${DEPLOY_DIR_IMAGE}/${GRUB_IMAGE} ${DEST} | ||
50 | |||
51 | install -m 0644 ${GRUBCFG} ${DEST} | ||
52 | } | ||
53 | |||
54 | grubefi_iso_populate() { | ||
55 | grubefi_populate ${GRUB_ISODIR} | ||
56 | |||
57 | # FIXUP the <EFIDIR> token in the config | ||
58 | # FIXME: This can be dropped once mkdosfs is fixed | ||
59 | sed -i "s@<EFIDIR>@${EFIDIR}@g" ${GRUB_ISODIR}/${GRUBCFG} | ||
60 | } | ||
61 | |||
62 | grubefi_hddimg_populate() { | ||
63 | grubefi_populate ${GRUB_HDDDIR} | ||
64 | |||
65 | # FIXUP the <EFIDIR> token in the config | ||
66 | # FIXME: This can be dropped once mkdosfs is fixed | ||
67 | sed -i "s@<EFIDIR>@@g" ${GRUB_HDDDIR}/${GRUBCFG} | ||
68 | } | ||
69 | |||
70 | # FIXME: The <EFIDIR> token can be replaced with ${EFIDIR} once the | ||
71 | # mkdosfs bug is resolved. | ||
72 | python build_grub_cfg() { | ||
73 | import sys | ||
74 | |||
75 | workdir = d.getVar('WORKDIR', True) | ||
76 | if not workdir: | ||
77 | bb.error("WORKDIR not defined, unable to package") | ||
78 | return | ||
79 | |||
80 | labels = d.getVar('LABELS', True) | ||
81 | if not labels: | ||
82 | bb.debug(1, "LABELS not defined, nothing to do") | ||
83 | return | ||
84 | |||
85 | if labels == []: | ||
86 | bb.debug(1, "No labels, nothing to do") | ||
87 | return | ||
88 | |||
89 | cfile = d.getVar('GRUBCFG', True) | ||
90 | if not cfile: | ||
91 | raise bb.build.FuncFailed('Unable to read GRUBCFG') | ||
92 | |||
93 | #bb.mkdirhier(os.path.dirname(cfile)) | ||
94 | |||
95 | try: | ||
96 | cfgfile = file(cfile, 'w') | ||
97 | except OSError: | ||
98 | raise bb.build.funcFailed('Unable to open %s' % (cfile)) | ||
99 | |||
100 | cfgfile.write('# Automatically created by OE\n') | ||
101 | |||
102 | opts = d.getVar('GRUB_OPTS', True) | ||
103 | if opts: | ||
104 | for opt in opts.split(';'): | ||
105 | cfgfile.write('%s\n' % opt) | ||
106 | |||
107 | cfgfile.write('default=%s\n' % (labels.split()[0])) | ||
108 | |||
109 | timeout = d.getVar('GRUB_TIMEOUT', True) | ||
110 | if timeout: | ||
111 | cfgfile.write('timeout=%s\n' % timeout) | ||
112 | else: | ||
113 | cfgfile.write('timeout=50\n') | ||
114 | |||
115 | for label in labels.split(): | ||
116 | localdata = d.createCopy() | ||
117 | |||
118 | overrides = localdata.getVar('OVERRIDES', True) | ||
119 | if not overrides: | ||
120 | raise bb.build.FuncFailed('OVERRIDES not defined') | ||
121 | |||
122 | localdata.setVar('OVERRIDES', label + ':' + overrides) | ||
123 | bb.data.update_data(localdata) | ||
124 | |||
125 | cfgfile.write('\nmenuentry \'%s\'{\n' % (label)) | ||
126 | cfgfile.write('linux <EFIDIR>/vmlinuz LABEL=%s' % (label)) | ||
127 | |||
128 | append = localdata.getVar('APPEND', True) | ||
129 | initrd = localdata.getVar('INITRD', True) | ||
130 | |||
131 | if append: | ||
132 | cfgfile.write('%s' % (append)) | ||
133 | cfgfile.write('\n') | ||
134 | |||
135 | if initrd: | ||
136 | cfgfile.write('initrd <EFIDIR>/initrd') | ||
137 | cfgfile.write('\n}\n') | ||
138 | |||
139 | cfgfile.close() | ||
140 | } | ||