#include <syslinux/config.h>
struct segoff16 {
- uint16_t offs, seg;
+ uint16_t offs, seg;
};
struct s_PXENV_FILE_CHECK_API {
- uint16_t Status;
- uint16_t Size;
- uint32_t Magic;
- uint32_t Provider;
- uint32_t APIMask;
- uint32_t Flags;
+ uint16_t Status;
+ uint16_t Size;
+ uint32_t Magic;
+ uint32_t Provider;
+ uint32_t APIMask;
+ uint32_t Flags;
};
static bool is_gpxe(void)
{
- const struct syslinux_version *sv;
- com32sys_t reg;
- struct s_PXENV_FILE_CHECK_API *fca;
+ const struct syslinux_version *sv;
+ com32sys_t reg;
+ struct s_PXENV_FILE_CHECK_API *fca;
- sv = syslinux_version();
- if (sv->filesystem != SYSLINUX_FS_PXELINUX)
- return false; /* Not PXELINUX */
+ sv = syslinux_version();
+ if (sv->filesystem != SYSLINUX_FS_PXELINUX)
+ return false; /* Not PXELINUX */
- fca = __com32.cs_bounce;
- memset(fca, 0, sizeof *fca);
- fca->Size = sizeof *fca;
- fca->Magic = 0x91d447b2;
+ fca = __com32.cs_bounce;
+ memset(fca, 0, sizeof *fca);
+ fca->Size = sizeof *fca;
+ fca->Magic = 0x91d447b2;
- memset(®, 0, sizeof reg);
- reg.eax.w[0] = 0x0009;
- reg.ebx.w[0] = 0x00e6; /* PXENV_FILE_API_CHECK */
- reg.edi.w[0] = OFFS(fca);
- reg.es = SEG(fca);
+ memset(®, 0, sizeof reg);
+ reg.eax.w[0] = 0x0009;
+ reg.ebx.w[0] = 0x00e6; /* PXENV_FILE_API_CHECK */
+ reg.edi.w[0] = OFFS(fca);
+ reg.es = SEG(fca);
- __intcall(0x22, ®, ®);
+ __intcall(0x22, ®, ®);
- if (reg.eflags.l & EFLAGS_CF)
- return false; /* Cannot invoke PXE stack */
+ if (reg.eflags.l & EFLAGS_CF)
+ return false; /* Cannot invoke PXE stack */
- if (reg.eax.w[0] || fca->Status)
- return false; /* PXE failure */
+ if (reg.eax.w[0] || fca->Status)
+ return false; /* PXE failure */
- if (fca->Magic != 0xe9c17b20)
- return false; /* Incorrect magic */
+ if (fca->Magic != 0xe9c17b20)
+ return false; /* Incorrect magic */
- if (fca->Size < sizeof *fca)
- return false; /* Short return */
+ if (fca->Size < sizeof *fca)
+ return false; /* Short return */
- if (!(fca->APIMask & (1 << 5)))
- return false; /* No FILE EXEC */
+ if (!(fca->APIMask & (1 << 5)))
+ return false; /* No FILE EXEC */
- return true;
+ return true;
}
struct s_PXENV_FILE_EXEC {
- uint16_t Status;
- struct segoff16 Command;
+ uint16_t Status;
+ struct segoff16 Command;
};
static void sanboot(const char **args)
{
- char *q;
- struct s_PXENV_FILE_EXEC *fx;
- com32sys_t reg;
+ char *q;
+ struct s_PXENV_FILE_EXEC *fx;
+ com32sys_t reg;
- memset(®, 0, sizeof reg);
+ memset(®, 0, sizeof reg);
- fx = __com32.cs_bounce;
- q = (char *)(fx+1);
+ fx = __com32.cs_bounce;
+ q = (char *)(fx + 1);
- fx->Status = 1;
- fx->Command.offs = OFFS(q);
- fx->Command.seg = SEG(q);
+ fx->Status = 1;
+ fx->Command.offs = OFFS(q);
+ fx->Command.seg = SEG(q);
- q = stpcpy(q, "sanboot");
+ q = stpcpy(q, "sanboot");
- while (*args) {
- *q++ = ' ';
- q = stpcpy(q, *args);
- args++;
- }
+ while (*args) {
+ *q++ = ' ';
+ q = stpcpy(q, *args);
+ args++;
+ }
- memset(®, 0, sizeof reg);
- reg.eax.w[0] = 0x0009;
- reg.ebx.w[0] = 0x00e5; /* PXENV_FILE_EXEC */
- reg.edi.w[0] = OFFS(fx);
- reg.es = SEG(fx);
+ memset(®, 0, sizeof reg);
+ reg.eax.w[0] = 0x0009;
+ reg.ebx.w[0] = 0x00e5; /* PXENV_FILE_EXEC */
+ reg.edi.w[0] = OFFS(fx);
+ reg.es = SEG(fx);
- __intcall(0x22, ®, ®);
+ __intcall(0x22, ®, ®);
- /* This should not return... */
+ /* This should not return... */
}
int main(int argc, const char *argv[])
{
- openconsole(&dev_null_r, &dev_stdcon_w);
+ openconsole(&dev_null_r, &dev_stdcon_w);
- if (argc < 2) {
- printf("Usage: sanboot rootpath\n");
- return 1;
- }
+ if (argc < 2) {
+ printf("Usage: sanboot rootpath\n");
+ return 1;
+ }
- if (!is_gpxe()) {
- printf("sanboot: gPXE API not detected\n");
- return 1;
- }
+ if (!is_gpxe()) {
+ printf("sanboot: gPXE API not detected\n");
+ return 1;
+ }
- sanboot(argv+1);
+ sanboot(argv + 1);
- /* sanboot() should not return... */
- printf("SAN boot failed.\n");
- return 1;
+ /* sanboot() should not return... */
+ printf("SAN boot failed.\n");
+ return 1;
}