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.
32 #include <syslinux/loadfile.h>
33 #include <syslinux/movebits.h>
34 #include <syslinux/bootrm.h>
38 # define dprintf printf
40 # define dprintf(f, ...) ((void)0)
43 typedef uint8_t guid_t
[16];
49 uint64_t BootCodeOffset
;
50 uint64_t BootCodeSize
;
57 uint64_t RuntimeOEMrev
;
59 uint64_t PageAlignment
; /* BLOB alignment value in pages */
60 uint64_t Reserved3
[48];
64 #define SDI_LOAD_ADDR (16 << 20) /* 16 MB */
65 #define SDI_SIGNATURE ('$' + ('S' << 8) + ('D' << 16) + ('I' << 24))
67 static inline void error(const char *msg
)
72 static int boot_sdi(void *ptr
, size_t len
)
74 const struct SDIHeader
*hdr
= ptr
;
75 struct syslinux_memmap
*mmap
= NULL
, *amap
= NULL
;
76 struct syslinux_rm_regs regs
;
77 struct syslinux_movelist
*ml
= NULL
;
79 /* **** Basic sanity checking **** */
80 if (hdr
->Signature
!= SDI_SIGNATURE
) {
81 fputs("No $SDI signature in file\n", stdout
);
84 if (memcmp(hdr
->Version
, "0001", 4)) {
86 fputs("Warning: unknown SDI version: ", stdout
);
87 for (i
= 0; i
< 4; i
++)
88 putchar(hdr
->Version
[i
]);
90 /* Then try anyway... */
94 mmap
= syslinux_memory_map();
95 amap
= syslinux_dup_memmap(mmap
);
99 /* **** Map the BOOT BLOB to 0x7c00 **** */
100 if (!hdr
->BootCodeOffset
) {
101 fputs("No BOOT BLOB in image\n", stdout
);
104 if (!hdr
->BootCodeSize
) {
105 fputs("BOOT BLOB is empty\n", stdout
);
108 if (len
< hdr
->BootCodeOffset
+ hdr
->BootCodeSize
) {
109 fputs("BOOT BLOB extends beyond file\n", stdout
);
113 if (syslinux_memmap_type(amap
, 0x7c00, hdr
->BootCodeSize
) != SMT_FREE
) {
114 fputs("BOOT BLOB too large for memory\n", stdout
);
117 if (syslinux_add_memmap(&amap
, 0x7c00, hdr
->BootCodeSize
, SMT_ALLOC
))
119 if (syslinux_add_movelist(&ml
, 0x7c00, (addr_t
) ptr
+ hdr
->BootCodeOffset
,
123 /* **** Map the entire image to SDI_LOAD_ADDR **** */
124 if (syslinux_memmap_type(amap
, SDI_LOAD_ADDR
, len
) != SMT_FREE
) {
125 fputs("Image too large for memory\n", stdout
);
128 if (syslinux_add_memmap(&amap
, SDI_LOAD_ADDR
, len
, SMT_ALLOC
))
130 if (syslinux_add_movelist(&ml
, SDI_LOAD_ADDR
, (addr_t
) ptr
, len
))
133 /* **** Set up registers **** */
134 memset(®s
, 0, sizeof regs
);
137 regs
.edx
.l
= SDI_LOAD_ADDR
| 0x41;
139 fputs("Booting...\n", stdout
);
140 syslinux_shuffle_boot_rm(ml
, mmap
, 0, ®s
);
143 syslinux_free_memmap(amap
);
144 syslinux_free_memmap(mmap
);
145 syslinux_free_movelist(ml
);
150 * Check that the sum of all bytes from first 512 bytes (SDI header)
153 int has_valid_header(unsigned char *header
)
155 unsigned char checksum
;
159 for (i
= 0; i
< sizeof(struct SDIHeader
); i
++)
160 checksum
+= header
[i
];
164 int main(int argc
, char *argv
[])
169 openconsole(&dev_null_r
, &dev_stdcon_w
);
172 error("Usage: sdi.c32 sdi_file\n");
176 fputs("Loading ", stdout
);
177 fputs(argv
[1], stdout
);
178 fputs("... ", stdout
);
179 if (zloadfile(argv
[1], &data
, &data_len
)) {
183 fputs("ok\n", stdout
);
185 if (!has_valid_header(data
)) {
186 error("SDI header is corrupted\n");
190 boot_sdi(data
, data_len
);
191 error("Invalid SDI file or insufficient memory\n");