summaryrefslogtreecommitdiffstats
path: root/src/arch
diff options
context:
space:
mode:
authorMichael Brown2009-04-24 04:16:18 +0200
committerMichael Brown2009-04-24 04:19:47 +0200
commite960fac8d037601ac6f7f7b8de80566d33ac6712 (patch)
tree0cfa98267b6dfa9138880f1933d1e5e366ca40ef /src/arch
parent[doc] Remove obsolete README.pixify (diff)
downloadipxe-e960fac8d037601ac6f7f7b8de80566d33ac6712.tar.gz
ipxe-e960fac8d037601ac6f7f7b8de80566d33ac6712.tar.xz
ipxe-e960fac8d037601ac6f7f7b8de80566d33ac6712.zip
[multiboot] Work around raw-flag bug in Solaris kernels
Solaris kernels are multiboot images with the "raw" flag set, indicating that the loader should use the raw address fields within the multiboot header rather than looking for an ELF header. However, the Solaris kernel contains garbage data in the raw address fields, and requires us to use the ELF header instead. Work around this by always using the ELF header if present. This renders the "raw" flag somewhat redundant.
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/i386/image/multiboot.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/src/arch/i386/image/multiboot.c b/src/arch/i386/image/multiboot.c
index 52bb10f6..1edf6af7 100644
--- a/src/arch/i386/image/multiboot.c
+++ b/src/arch/i386/image/multiboot.c
@@ -360,6 +360,13 @@ static int multiboot_load_raw ( struct image *image,
userptr_t buffer;
int rc;
+ /* Sanity check */
+ if ( ! ( hdr->mb.flags & MB_FLAG_RAW ) ) {
+ DBGC ( image, "MULTIBOOT %p is not flagged as a raw image\n",
+ image );
+ return -EINVAL;
+ }
+
/* Verify and prepare segment */
offset = ( hdr->offset - hdr->mb.header_addr + hdr->mb.load_addr );
filesz = ( hdr->mb.load_end_addr ?
@@ -432,14 +439,14 @@ static int multiboot_load ( struct image *image ) {
return -ENOTSUP;
}
- /* Load the actual image */
- if ( hdr.mb.flags & MB_FLAG_RAW ) {
- if ( ( rc = multiboot_load_raw ( image, &hdr ) ) != 0 )
- return rc;
- } else {
- if ( ( rc = multiboot_load_elf ( image ) ) != 0 )
- return rc;
- }
+ /* There is technically a bit MB_FLAG_RAW to indicate whether
+ * this is an ELF or a raw image. In practice, grub will use
+ * the ELF header if present, and Solaris relies on this
+ * behaviour.
+ */
+ if ( ( ( rc = multiboot_load_elf ( image ) ) != 0 ) &&
+ ( ( rc = multiboot_load_raw ( image, &hdr ) ) != 0 ) )
+ return rc;
return 0;
}