1 /* ----------------------------------------------------------------------- *
3 * Copyright 2008 H. Peter Anvin - All Rights Reserved
4 * Copyright 2009 Intel Corporation; author: H. Peter Anvin
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
9 * Boston MA 02110-1301, USA; either version 2 of the License, or
10 * (at your option) any later version; incorporated herein by reference.
12 * ----------------------------------------------------------------------- */
17 * Loader for the Microsoft System Deployment Image (SDI) format.
18 * Based on a historical patch by Remi Lefevre.
33 #include <syslinux/loadfile.h>
34 #include <syslinux/movebits.h>
35 #include <syslinux/bootrm.h>
37 typedef uint8_t guid_t
[16];
43 uint64_t BootCodeOffset
;
44 uint64_t BootCodeSize
;
51 uint64_t RuntimeOEMrev
;
53 uint64_t PageAlignment
; /* BLOB alignment value in pages */
54 uint64_t Reserved3
[48];
58 #define SDI_LOAD_ADDR (16 << 20) /* 16 MB */
59 #define SDI_SIGNATURE ('$' + ('S' << 8) + ('D' << 16) + ('I' << 24))
61 static inline void error(const char *msg
)
66 static int boot_sdi(void *ptr
, size_t len
)
68 const struct SDIHeader
*hdr
= ptr
;
69 struct syslinux_memmap
*mmap
= NULL
, *amap
= NULL
;
70 struct syslinux_rm_regs regs
;
71 struct syslinux_movelist
*ml
= NULL
;
73 /* **** Basic sanity checking **** */
74 if (hdr
->Signature
!= SDI_SIGNATURE
) {
75 fputs("No $SDI signature in file\n", stdout
);
78 if (memcmp(hdr
->Version
, "0001", 4)) {
80 fputs("Warning: unknown SDI version: ", stdout
);
81 for (i
= 0; i
< 4; i
++)
82 putchar(hdr
->Version
[i
]);
84 /* Then try anyway... */
88 mmap
= syslinux_memory_map();
89 amap
= syslinux_dup_memmap(mmap
);
93 /* **** Map the BOOT BLOB to 0x7c00 **** */
94 if (!hdr
->BootCodeOffset
) {
95 fputs("No BOOT BLOB in image\n", stdout
);
98 if (!hdr
->BootCodeSize
) {
99 fputs("BOOT BLOB is empty\n", stdout
);
102 if (len
< hdr
->BootCodeOffset
+ hdr
->BootCodeSize
) {
103 fputs("BOOT BLOB extends beyond file\n", stdout
);
107 if (syslinux_memmap_type(amap
, 0x7c00, hdr
->BootCodeSize
) != SMT_FREE
) {
108 fputs("BOOT BLOB too large for memory\n", stdout
);
111 if (syslinux_add_memmap(&amap
, 0x7c00, hdr
->BootCodeSize
, SMT_ALLOC
))
113 if (syslinux_add_movelist(&ml
, 0x7c00, (addr_t
) ptr
+ hdr
->BootCodeOffset
,
117 /* **** Map the entire image to SDI_LOAD_ADDR **** */
118 if (syslinux_memmap_type(amap
, SDI_LOAD_ADDR
, len
) != SMT_FREE
) {
119 fputs("Image too large for memory\n", stdout
);
122 if (syslinux_add_memmap(&amap
, SDI_LOAD_ADDR
, len
, SMT_ALLOC
))
124 if (syslinux_add_movelist(&ml
, SDI_LOAD_ADDR
, (addr_t
) ptr
, len
))
127 /* **** Set up registers **** */
128 memset(®s
, 0, sizeof regs
);
131 regs
.edx
.l
= SDI_LOAD_ADDR
| 0x41;
133 fputs("Booting...\n", stdout
);
134 syslinux_shuffle_boot_rm(ml
, mmap
, 0, ®s
);
137 syslinux_free_memmap(amap
);
138 syslinux_free_memmap(mmap
);
139 syslinux_free_movelist(ml
);
144 * Check that the sum of all bytes from first 512 bytes (SDI header)
147 int has_valid_header(unsigned char *header
)
149 unsigned char checksum
;
153 for (i
= 0; i
< sizeof(struct SDIHeader
); i
++)
154 checksum
+= header
[i
];
158 int main(int argc
, char *argv
[])
163 openconsole(&dev_null_r
, &dev_stdcon_w
);
166 error("Usage: sdi.c32 sdi_file\n");
170 fputs("Loading ", stdout
);
171 fputs(argv
[1], stdout
);
172 fputs("... ", stdout
);
173 if (zloadfile(argv
[1], &data
, &data_len
)) {
177 fputs("ok\n", stdout
);
179 if (!has_valid_header(data
)) {
180 error("SDI header is corrupted\n");
184 boot_sdi(data
, data_len
);
185 error("Invalid SDI file or insufficient memory\n");