summaryrefslogtreecommitdiffstats
path: root/contrib/syslinux-4.02/com32/lib/syslinux
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/syslinux-4.02/com32/lib/syslinux')
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/addlist.c45
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/adv.c49
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/advwrite.c45
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/cleanup.c40
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/config.c41
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/dsinfo.c45
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/dump_mmap.c47
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/dump_movelist.c46
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/features.c51
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/floadfile.c108
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/freelist.c46
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/getadv.c68
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/idle.c47
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/initramfs.c76
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/initramfs_archive.c47
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/initramfs_file.c161
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/initramfs_loadfile.c48
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/ipappend.c58
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/keyboard.c44
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/load_linux.c511
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/loadfile.c63
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/localboot.c42
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/memmap.c65
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/memscan.c158
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/movebits.c710
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/pxe_dns.c75
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/pxe_get_cached.c96
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/pxe_get_nic.c67
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/reboot.c47
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/run_command.c50
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/run_default.c41
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/runimage.c70
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/serial.c52
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/setadv.c116
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/shuffle.c275
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/shuffle_pm.c77
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/shuffle_rm.c171
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/version.c46
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/video/fontquery.c54
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/video/forcetext.c42
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/video/reportmode.c45
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/zloadfile.c59
-rw-r--r--contrib/syslinux-4.02/com32/lib/syslinux/zonelist.c301
43 files changed, 4345 insertions, 0 deletions
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/addlist.c b/contrib/syslinux-4.02/com32/lib/syslinux/addlist.c
new file mode 100644
index 0000000..265cf4a
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/addlist.c
@@ -0,0 +1,45 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <syslinux/movebits.h>
+
+int syslinux_add_movelist(struct syslinux_movelist **list,
+ addr_t dst, addr_t src, addr_t len)
+{
+ struct syslinux_movelist *ml = malloc(sizeof(struct syslinux_movelist));
+ if (!ml)
+ return -1;
+
+ ml->dst = dst;
+ ml->src = src;
+ ml->len = len;
+ ml->next = *list;
+
+ *list = ml;
+ return 0;
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/adv.c b/contrib/syslinux-4.02/com32/lib/syslinux/adv.c
new file mode 100644
index 0000000..be38e89
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/adv.c
@@ -0,0 +1,49 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/adv.c
+ *
+ * Access the syslinux auxilliary data vector
+ */
+
+#include <syslinux/adv.h>
+#include <klibc/compiler.h>
+#include <com32.h>
+
+void *__syslinux_adv_ptr;
+size_t __syslinux_adv_size;
+
+void __constructor __syslinux_get_adv(void)
+{
+ static com32sys_t reg;
+
+ reg.eax.w[0] = 0x001c;
+ __intcall(0x22, &reg, &reg);
+ __syslinux_adv_ptr = MK_PTR(reg.es, reg.ebx.w[0]);
+ __syslinux_adv_size = reg.ecx.w[0];
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/advwrite.c b/contrib/syslinux-4.02/com32/lib/syslinux/advwrite.c
new file mode 100644
index 0000000..4152eea
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/advwrite.c
@@ -0,0 +1,45 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/advwrite.c
+ *
+ * Write back the ADV
+ */
+
+#include <syslinux/adv.h>
+#include <klibc/compiler.h>
+#include <com32.h>
+
+int syslinux_adv_write(void)
+{
+ static com32sys_t reg;
+
+ reg.eax.w[0] = 0x001d;
+ __intcall(0x22, &reg, &reg);
+ return (reg.eflags.l & EFLAGS_CF) ? -1 : 0;
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/cleanup.c b/contrib/syslinux-4.02/com32/lib/syslinux/cleanup.c
new file mode 100644
index 0000000..12140e5
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/cleanup.c
@@ -0,0 +1,40 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <syslinux/boot.h>
+#include <stddef.h>
+#include <com32.h>
+
+void syslinux_final_cleanup(uint16_t flags)
+{
+ static com32sys_t ireg;
+
+ ireg.eax.w[0] = 0x000c;
+ ireg.edx.w[0] = flags;
+
+ __intcall(0x22, &ireg, NULL);
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/config.c b/contrib/syslinux-4.02/com32/lib/syslinux/config.c
new file mode 100644
index 0000000..b27aa82
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/config.c
@@ -0,0 +1,41 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <syslinux/config.h>
+#include <klibc/compiler.h>
+#include <com32.h>
+
+const char *__syslinux_config_file;
+
+void __constructor __syslinux_get_config_file_name(void)
+{
+ static com32sys_t reg;
+
+ reg.eax.w[0] = 0x000e;
+ __intcall(0x22, &reg, &reg);
+ __syslinux_config_file = MK_PTR(reg.es, reg.ebx.w[0]);
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/dsinfo.c b/contrib/syslinux-4.02/com32/lib/syslinux/dsinfo.c
new file mode 100644
index 0000000..c1f02a5
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/dsinfo.c
@@ -0,0 +1,45 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2008-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <syslinux/config.h>
+#include <klibc/compiler.h>
+#include <com32.h>
+
+union syslinux_derivative_info __syslinux_derivative_info;
+
+void __constructor __syslinux_get_derivative_info(void)
+{
+ com32sys_t *const r = &__syslinux_derivative_info.rr.r;
+
+ r->eax.w[0] = 0x000A;
+ __intcall(0x22, r, r);
+
+ __syslinux_derivative_info.r.esbx = MK_PTR(r->es, r->ebx.w[0]);
+ __syslinux_derivative_info.r.fssi = MK_PTR(r->fs, r->esi.w[0]);
+ __syslinux_derivative_info.r.gsdi = MK_PTR(r->gs, r->edi.w[0]);
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/dump_mmap.c b/contrib/syslinux-4.02/com32/lib/syslinux/dump_mmap.c
new file mode 100644
index 0000000..3f1e340
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/dump_mmap.c
@@ -0,0 +1,47 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * dump_mmap.c
+ *
+ * Writes a syslinux_memmap out to a specified file. This is
+ * intended for debugging.
+ */
+
+#include <stdio.h>
+#include <syslinux/movebits.h>
+
+void syslinux_dump_memmap(FILE * file, struct syslinux_memmap *memmap)
+{
+ fprintf(file, "%10s %10s %10s\n"
+ "--------------------------------\n", "Start", "Length", "Type");
+ while (memmap->next) {
+ fprintf(file, "0x%08x 0x%08x %10d\n", memmap->start,
+ memmap->next->start - memmap->start, memmap->type);
+ memmap = memmap->next;
+ }
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/dump_movelist.c b/contrib/syslinux-4.02/com32/lib/syslinux/dump_movelist.c
new file mode 100644
index 0000000..282d006
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/dump_movelist.c
@@ -0,0 +1,46 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * dump_movelist.c
+ *
+ * Writes a syslinux_movelist out to a specified file. This is
+ * intended for debugging.
+ */
+
+#include <stdio.h>
+#include <syslinux/movebits.h>
+
+void syslinux_dump_movelist(FILE * file, struct syslinux_movelist *ml)
+{
+ fprintf(file, "%10s %10s %10s\n"
+ "--------------------------------\n", "Dest", "Src", "Length");
+ while (ml) {
+ fprintf(file, "0x%08x 0x%08x 0x%08x\n", ml->dst, ml->src, ml->len);
+ ml = ml->next;
+ }
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/features.c b/contrib/syslinux-4.02/com32/lib/syslinux/features.c
new file mode 100644
index 0000000..c88aef3
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/features.c
@@ -0,0 +1,51 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/features.c
+ *
+ * SYSLINUX feature flag query
+ */
+
+#include <klibc/compiler.h>
+#include <syslinux/features.h>
+#include <string.h>
+#include <com32.h>
+
+struct __syslinux_feature_flags __syslinux_feature_flags;
+
+void __constructor __syslinux_detect_features(void)
+{
+ static com32sys_t reg;
+
+ memset(&reg, 0, sizeof reg);
+ reg.eax.w[0] = 0x0015;
+ __intcall(0x22, &reg, &reg);
+
+ __syslinux_feature_flags.len = reg.ecx.w[0];
+ __syslinux_feature_flags.ptr = MK_PTR(reg.es, reg.ebx.w[0]);
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/floadfile.c b/contrib/syslinux-4.02/com32/lib/syslinux/floadfile.c
new file mode 100644
index 0000000..ece460d
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/floadfile.c
@@ -0,0 +1,108 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2005-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * floadfile.c
+ *
+ * Read the contents of a data file into a malloc'd buffer
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include <syslinux/loadfile.h>
+
+#define INCREMENTAL_CHUNK 1024*1024
+
+int floadfile(FILE * f, void **ptr, size_t * len, const void *prefix,
+ size_t prefix_len)
+{
+ struct stat st;
+ void *data, *dp;
+ size_t alen, clen, rlen, xlen;
+
+ clen = alen = 0;
+ data = NULL;
+
+ if (fstat(fileno(f), &st))
+ goto err;
+
+ if (!S_ISREG(st.st_mode)) {
+ /* Not a regular file, we can't assume we know the file size */
+ if (prefix_len) {
+ clen = alen = prefix_len;
+ data = malloc(prefix_len);
+ if (!data)
+ goto err;
+
+ memcpy(data, prefix, prefix_len);
+ }
+
+ do {
+ alen += INCREMENTAL_CHUNK;
+ dp = realloc(data, alen);
+ if (!dp)
+ goto err;
+ data = dp;
+
+ rlen = fread((char *)data + clen, 1, alen - clen, f);
+ clen += rlen;
+ } while (clen == alen);
+
+ *len = clen;
+ xlen = (clen + LOADFILE_ZERO_PAD - 1) & ~(LOADFILE_ZERO_PAD - 1);
+ dp = realloc(data, xlen);
+ if (dp)
+ data = dp;
+ *ptr = data;
+ } else {
+ *len = clen = st.st_size + prefix_len - ftell(f);
+ xlen = (clen + LOADFILE_ZERO_PAD - 1) & ~(LOADFILE_ZERO_PAD - 1);
+
+ *ptr = data = malloc(xlen);
+ if (!data)
+ return -1;
+
+ memcpy(data, prefix, prefix_len);
+
+ if ((off_t) fread((char *)data + prefix_len, 1, clen - prefix_len, f)
+ != clen - prefix_len)
+ goto err;
+ }
+
+ memset((char *)data + clen, 0, xlen - clen);
+ return 0;
+
+err:
+ if (data)
+ free(data);
+ return -1;
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/freelist.c b/contrib/syslinux-4.02/com32/lib/syslinux/freelist.c
new file mode 100644
index 0000000..f73a69c
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/freelist.c
@@ -0,0 +1,46 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * freelist.c
+ *
+ * Frees a syslinux_movelist
+ */
+
+#include <stdlib.h>
+#include <syslinux/movebits.h>
+
+void syslinux_free_movelist(struct syslinux_movelist *list)
+{
+ struct syslinux_movelist *m;
+
+ while (list) {
+ m = list;
+ list = list->next;
+ free(m);
+ }
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/getadv.c b/contrib/syslinux-4.02/com32/lib/syslinux/getadv.c
new file mode 100644
index 0000000..5578313
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/getadv.c
@@ -0,0 +1,68 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/getadv.c
+ *
+ * Get a data item from the auxilliary data vector. Returns a pointer
+ * and sets *size on success; NULL on failure.
+ */
+
+#include <syslinux/adv.h>
+#include <klibc/compiler.h>
+#include <inttypes.h>
+
+const void *syslinux_getadv(int tag, size_t * size)
+{
+ const uint8_t *p;
+ size_t left;
+
+ p = syslinux_adv_ptr();
+ left = syslinux_adv_size();
+
+ while (left >= 2) {
+ uint8_t ptag = *p++;
+ size_t plen = *p++;
+ left -= 2;
+
+ if (ptag == ADV_END)
+ return NULL; /* Not found */
+
+ if (left < plen)
+ return NULL; /* Item overrun */
+
+ if (ptag == tag) {
+ *size = plen;
+ return p;
+ }
+
+ p += plen;
+ left -= plen;
+ }
+
+ return NULL;
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/idle.c b/contrib/syslinux-4.02/com32/lib/syslinux/idle.c
new file mode 100644
index 0000000..ddaa7fc
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/idle.c
@@ -0,0 +1,47 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2005-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * idle.c
+ *
+ * What to do in a busy loop...
+ */
+
+#include <stddef.h>
+#include <com32.h>
+#include <syslinux/pmapi.h>
+#include <syslinux/idle.h>
+
+void syslinux_reset_idle(void)
+{
+ __com32.cs_pm->reset_idle();
+}
+
+void syslinux_idle(void)
+{
+ __com32.cs_pm->idle();
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/initramfs.c b/contrib/syslinux-4.02/com32/lib/syslinux/initramfs.c
new file mode 100644
index 0000000..220e162
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/initramfs.c
@@ -0,0 +1,76 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * initramfs.c
+ *
+ * Utility functions for initramfs manipulation
+ */
+
+#include <stdlib.h>
+#include <syslinux/linux.h>
+
+struct initramfs *initramfs_init(void)
+{
+ struct initramfs *ir;
+
+ ir = calloc(sizeof(*ir), 1);
+ if (!ir)
+ return NULL;
+
+ ir->prev = ir->next = ir;
+ return ir;
+}
+
+int initramfs_add_data(struct initramfs *ihead, const void *data,
+ size_t data_len, size_t len, size_t align)
+{
+ struct initramfs *in;
+
+ if (!len)
+ return 0; /* Nothing to add... */
+
+ /* Alignment must be a power of 2, and <= INITRAMFS_MAX_ALIGN */
+ if (!align || (align & (align - 1)) || align > INITRAMFS_MAX_ALIGN)
+ return -1;
+
+ in = malloc(sizeof(*in));
+ if (!in)
+ return -1;
+
+ in->len = len;
+ in->data = data;
+ in->data_len = data_len;
+ in->align = align;
+
+ in->next = ihead;
+ in->prev = ihead->prev;
+ ihead->prev->next = in;
+ ihead->prev = in;
+
+ return 0;
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/initramfs_archive.c b/contrib/syslinux-4.02/com32/lib/syslinux/initramfs_archive.c
new file mode 100644
index 0000000..495b78e
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/initramfs_archive.c
@@ -0,0 +1,47 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * initramfs_archive.c
+ *
+ * Utility function to load an initramfs archive.
+ */
+
+#include <stdlib.h>
+#include <syslinux/loadfile.h>
+#include <syslinux/linux.h>
+
+int initramfs_load_archive(struct initramfs *ihead, const char *filename)
+{
+ void *data;
+ size_t len;
+
+ if (loadfile(filename, &data, &len))
+ return -1;
+
+ return initramfs_add_data(ihead, data, len, len, 4);
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/initramfs_file.c b/contrib/syslinux-4.02/com32/lib/syslinux/initramfs_file.c
new file mode 100644
index 0000000..763eff2
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/initramfs_file.c
@@ -0,0 +1,161 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * initramfs_file.c
+ *
+ * Utility functions to add arbitrary files including cpio header
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <syslinux/linux.h>
+
+#define CPIO_MAGIC "070701"
+struct cpio_header {
+ char c_magic[6]; /* 070701 */
+ char c_ino[8]; /* Inode number */
+ char c_mode[8]; /* File mode and permissions */
+ char c_uid[8]; /* uid */
+ char c_gid[8]; /* gid */
+ char c_nlink[8]; /* Number of links */
+ char c_mtime[8]; /* Modification time */
+ char c_filesize[8]; /* Size of data field */
+ char c_maj[8]; /* File device major number */
+ char c_min[8]; /* File device minor number */
+ char c_rmaj[8]; /* Device node reference major number */
+ char c_rmin[8]; /* Device node reference minor number */
+ char c_namesize[8]; /* Length of filename including final \0 */
+ char c_chksum[8]; /* Checksum if c_magic ends in 2 */
+};
+
+static uint32_t next_ino = 1;
+
+/* Create cpio headers for the directory entries leading up to a file.
+ Returns the number of bytes; doesn't touch the buffer if too small. */
+static size_t initramfs_mkdirs(const char *filename, void *buffer,
+ size_t buflen)
+{
+ const char *p = filename;
+ char *bp = buffer;
+ int len;
+ size_t bytes = 0;
+ int pad;
+
+ while ((p = strchr(p, '/'))) {
+ if (p != filename && p[-1] != '/') {
+ len = p - filename;
+ bytes += ((sizeof(struct cpio_header) + len + 1) + 3) & ~3;
+ }
+ p++;
+ }
+
+ if (buflen >= bytes) {
+ p = filename;
+ while ((p = strchr(p, '/'))) {
+ if (p != filename && p[-1] != '/') {
+ len = p - filename;
+ bp += sprintf(bp, "070701%08x%08x%08x%08x%08x%08x%08x%08x%08x"
+ "%08x%08x%08x%08x", next_ino++, S_IFDIR | 0755,
+ 0, 0, 1, 0, 0, 0, 1, 0, 1, len + 1, 0);
+ memcpy(bp, filename, len);
+ bp += len;
+ pad = (-(sizeof(struct cpio_header) + len) & 3) + 1;
+ memset(bp, 0, pad);
+ bp += pad;
+ }
+ }
+ }
+
+ return bytes;
+}
+
+/*
+ * Create a file header (with optional parent directory entries)
+ * and add it to an initramfs chain
+ */
+int initramfs_mknod(struct initramfs *ihead, const char *filename,
+ int do_mkdir,
+ uint16_t mode, size_t len, uint32_t major, uint32_t minor)
+{
+ size_t bytes;
+ int namelen = strlen(filename);
+ int pad;
+ char *buffer, *bp;
+
+ if (do_mkdir)
+ bytes = initramfs_mkdirs(filename, NULL, 0);
+ else
+ bytes = 0;
+
+ bytes += ((sizeof(struct cpio_header) + namelen + 1) + 3) & ~3;
+
+ bp = buffer = malloc(bytes);
+ if (!buffer)
+ return -1;
+
+ if (do_mkdir)
+ bp += initramfs_mkdirs(filename, bp, bytes);
+
+ bp += sprintf(bp, "070701%08x%08x%08x%08x%08x%08x%08x%08x%08x"
+ "%08x%08x%08x%08x", next_ino++, mode,
+ 0, 0, 1, 0, len, 0, 1, major, minor, namelen + 1, 0);
+ memcpy(bp, filename, namelen);
+ bp += len;
+ pad = (-(sizeof(struct cpio_header) + namelen) & 3) + 1;
+ memset(bp, 0, pad);
+
+ if (initramfs_add_data(ihead, buffer, bytes, bytes, 4)) {
+ free(buffer);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Add a file given data in memory to an initramfs chain. This
+ * can be used to create nonfiles like symlinks by specifying an
+ * appropriate mode.
+ */
+int initramfs_add_file(struct initramfs *ihead, const void *data,
+ size_t data_len, size_t len,
+ const char *filename, int do_mkdir, uint32_t mode)
+{
+ if (initramfs_mknod(ihead, filename, do_mkdir,
+ (mode & S_IFMT) ? mode : mode | S_IFREG, len, 0, 1))
+ return -1;
+
+ return initramfs_add_data(ihead, data, data_len, len, 4);
+}
+
+int initramfs_add_trailer(struct initramfs *ihead)
+{
+ return initramfs_mknod(ihead, "TRAILER!!!", 0, 0, 0, 0, 0);
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/initramfs_loadfile.c b/contrib/syslinux-4.02/com32/lib/syslinux/initramfs_loadfile.c
new file mode 100644
index 0000000..1338aad
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/initramfs_loadfile.c
@@ -0,0 +1,48 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * initramfs_loadfile.c
+ *
+ * Load a single file into an initramfs image.
+ */
+
+#include <syslinux/linux.h>
+#include <syslinux/loadfile.h>
+
+int initramfs_load_file(struct initramfs *ihead, const char *src_filename,
+ const char *dst_filename, int do_mkdir, uint32_t mode)
+{
+ void *data;
+ size_t len;
+
+ if (loadfile(src_filename, &data, &len))
+ return -1;
+
+ return initramfs_add_file(ihead, data, len, len, dst_filename,
+ do_mkdir, mode);
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/ipappend.c b/contrib/syslinux-4.02/com32/lib/syslinux/ipappend.c
new file mode 100644
index 0000000..bd00092
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/ipappend.c
@@ -0,0 +1,58 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/ipappend.c
+ *
+ * Get ipappend strings
+ */
+
+#include <syslinux/config.h>
+#include <klibc/compiler.h>
+#include <com32.h>
+
+struct syslinux_ipappend_strings __syslinux_ipappend_strings;
+static const char *syslinux_ipappend_string_list[32];
+
+void __constructor __syslinux_get_ipappend_strings(void)
+{
+ static com32sys_t reg;
+ int i;
+
+ reg.eax.w[0] = 0x000f;
+ __intcall(0x22, &reg, &reg);
+
+ if (!(reg.eflags.l & EFLAGS_CF)) {
+ __syslinux_ipappend_strings.count = reg.ecx.w[0];
+ __syslinux_ipappend_strings.ptr = syslinux_ipappend_string_list;
+ for (i = 0; i < reg.ecx.w[0]; i++) {
+ syslinux_ipappend_string_list[i] =
+ MK_PTR(reg.es,
+ *(uint16_t *) MK_PTR(reg.es, reg.ebx.w[0] + i * 2));
+ }
+ }
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/keyboard.c b/contrib/syslinux-4.02/com32/lib/syslinux/keyboard.c
new file mode 100644
index 0000000..feafde0
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/keyboard.c
@@ -0,0 +1,44 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <syslinux/keyboard.h>
+#include <com32.h>
+
+struct syslinux_keyboard_map __syslinux_keyboard_map;
+
+void __constructor __syslinux_get_keyboard_map(void)
+{
+ static com32sys_t reg;
+
+ reg.eax.w[0] = 0x001e;
+ __intcall(0x22, &reg, &reg);
+ if (!(reg.eflags.l & EFLAGS_CF)) {
+ __syslinux_keyboard_map.version = reg.eax.w[0];
+ __syslinux_keyboard_map.length = reg.ecx.w[0];
+ __syslinux_keyboard_map.map = MK_PTR(reg.es, reg.ebx.w[0]);
+ }
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/load_linux.c b/contrib/syslinux-4.02/com32/lib/syslinux/load_linux.c
new file mode 100644
index 0000000..df79362
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/load_linux.c
@@ -0,0 +1,511 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * load_linux.c
+ *
+ * Load a Linux kernel (Image/zImage/bzImage).
+ */
+
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <string.h>
+#include <minmax.h>
+#include <syslinux/align.h>
+#include <syslinux/linux.h>
+#include <syslinux/bootrm.h>
+#include <syslinux/movebits.h>
+
+#ifndef DEBUG
+# define DEBUG 0
+#endif
+#if DEBUG
+# include <stdio.h>
+# define dprintf printf
+#else
+# define dprintf(f, ...) ((void)0)
+#endif
+
+struct linux_header {
+ uint8_t boot_sector_1[0x0020];
+ uint16_t old_cmd_line_magic;
+ uint16_t old_cmd_line_offset;
+ uint8_t boot_sector_2[0x01f1 - 0x0024];
+ uint8_t setup_sects;
+ uint16_t root_flags;
+ uint32_t syssize;
+ uint16_t ram_size;
+ uint16_t vid_mode;
+ uint16_t root_dev;
+ uint16_t boot_flag;
+ uint16_t jump;
+ uint32_t header;
+ uint16_t version;
+ uint32_t realmode_swtch;
+ uint16_t start_sys;
+ uint16_t kernel_version;
+ uint8_t type_of_loader;
+ uint8_t loadflags;
+ uint16_t setup_move_size;
+ uint32_t code32_start;
+ uint32_t ramdisk_image;
+ uint32_t ramdisk_size;
+ uint32_t bootsect_kludge;
+ uint16_t heap_end_ptr;
+ uint16_t pad1;
+ uint32_t cmd_line_ptr;
+ uint32_t initrd_addr_max;
+ uint32_t kernel_alignment;
+ uint8_t relocatable_kernel;
+ uint8_t pad2[3];
+ uint32_t cmdline_max_len;
+} __packed;
+
+#define BOOT_MAGIC 0xAA55
+#define LINUX_MAGIC ('H' + ('d' << 8) + ('r' << 16) + ('S' << 24))
+#define OLD_CMDLINE_MAGIC 0xA33F
+
+/* loadflags */
+#define LOAD_HIGH 0x01
+#define CAN_USE_HEAP 0x80
+
+/* Get a value with a potential suffix (k/m/g/t/p/e) */
+static unsigned long long suffix_number(const char *str)
+{
+ char *ep;
+ unsigned long long v;
+ int shift;
+
+ v = strtoull(str, &ep, 0);
+ switch (*ep | 0x20) {
+ case 'k':
+ shift = 10;
+ break;
+ case 'm':
+ shift = 20;
+ break;
+ case 'g':
+ shift = 30;
+ break;
+ case 't':
+ shift = 40;
+ break;
+ case 'p':
+ shift = 50;
+ break;
+ case 'e':
+ shift = 60;
+ break;
+ default:
+ shift = 0;
+ break;
+ }
+ v <<= shift;
+
+ return v;
+}
+
+/*
+ * Find the last instance of a particular command line argument
+ * (which should include the final =; do not use for boolean arguments)
+ * Note: the resulting string is typically not null-terminated.
+ */
+static const char *find_argument(const char *cmdline, const char *argument)
+{
+ const char *found = NULL;
+ const char *p = cmdline;
+ bool was_space = true;
+ size_t la = strlen(argument);
+
+ while (*p) {
+ if (isspace(*p)) {
+ was_space = true;
+ } else if (was_space) {
+ if (!memcmp(p, argument, la))
+ found = p + la;
+ was_space = false;
+ }
+ p++;
+ }
+
+ return found;
+}
+
+/* Truncate to 32 bits, with saturate */
+static inline uint32_t saturate32(unsigned long long v)
+{
+ return (v > 0xffffffff) ? 0xffffffff : (uint32_t) v;
+}
+
+/* Get the combined size of the initramfs */
+static addr_t initramfs_size(struct initramfs *initramfs)
+{
+ struct initramfs *ip;
+ addr_t size = 0;
+
+ if (!initramfs)
+ return 0;
+
+ for (ip = initramfs->next; ip->len; ip = ip->next) {
+ size = (size + ip->align - 1) & ~(ip->align - 1); /* Alignment */
+ size += ip->len;
+ }
+
+ return size;
+}
+
+/* Create the appropriate mappings for the initramfs */
+static int map_initramfs(struct syslinux_movelist **fraglist,
+ struct syslinux_memmap **mmap,
+ struct initramfs *initramfs, addr_t addr)
+{
+ struct initramfs *ip;
+ addr_t next_addr, len, pad;
+
+ for (ip = initramfs->next; ip->len; ip = ip->next) {
+ len = ip->len;
+ next_addr = addr + len;
+
+ /* If this isn't the last entry, extend the zero-pad region
+ to enforce the alignment of the next chunk. */
+ if (ip->next->len) {
+ pad = -next_addr & (ip->next->align - 1);
+ len += pad;
+ next_addr += pad;
+ }
+
+ if (ip->data_len) {
+ if (syslinux_add_movelist(fraglist, addr, (addr_t) ip->data, len))
+ return -1;
+ }
+ if (len > ip->data_len) {
+ if (syslinux_add_memmap(mmap, addr + ip->data_len,
+ len - ip->data_len, SMT_ZERO))
+ return -1;
+ }
+ addr = next_addr;
+ }
+
+ return 0;
+}
+
+int syslinux_boot_linux(void *kernel_buf, size_t kernel_size,
+ struct initramfs *initramfs, char *cmdline)
+{
+ struct linux_header hdr, *whdr;
+ size_t real_mode_size, prot_mode_size;
+ addr_t real_mode_base, prot_mode_base;
+ addr_t irf_size;
+ size_t cmdline_size, cmdline_offset;
+ struct syslinux_rm_regs regs;
+ struct syslinux_movelist *fraglist = NULL;
+ struct syslinux_memmap *mmap = NULL;
+ struct syslinux_memmap *amap = NULL;
+ bool ok;
+ uint32_t memlimit = 0;
+ uint16_t video_mode = 0;
+ const char *arg;
+
+ cmdline_size = strlen(cmdline) + 1;
+
+ if (kernel_size < 2 * 512)
+ goto bail;
+
+ /* Look for specific command-line arguments we care about */
+ if ((arg = find_argument(cmdline, "mem=")))
+ memlimit = saturate32(suffix_number(arg));
+
+ if ((arg = find_argument(cmdline, "vga="))) {
+ switch (arg[0] | 0x20) {
+ case 'a': /* "ask" */
+ video_mode = 0xfffd;
+ break;
+ case 'e': /* "ext" */
+ video_mode = 0xfffe;
+ break;
+ case 'n': /* "normal" */
+ video_mode = 0xffff;
+ break;
+ case 'c': /* "current" */
+ video_mode = 0x0f04;
+ break;
+ default:
+ video_mode = strtoul(arg, NULL, 0);
+ break;
+ }
+ }
+
+ /* Copy the header into private storage */
+ /* Use whdr to modify the actual kernel header */
+ memcpy(&hdr, kernel_buf, sizeof hdr);
+ whdr = (struct linux_header *)kernel_buf;
+
+ if (hdr.boot_flag != BOOT_MAGIC)
+ goto bail;
+
+ if (hdr.header != LINUX_MAGIC) {
+ hdr.version = 0x0100; /* Very old kernel */
+ hdr.loadflags = 0;
+ }
+
+ whdr->vid_mode = video_mode;
+
+ if (!hdr.setup_sects)
+ hdr.setup_sects = 4;
+
+ if (hdr.version < 0x0203)
+ hdr.initrd_addr_max = 0x37ffffff;
+
+ if (!memlimit && memlimit - 1 > hdr.initrd_addr_max)
+ memlimit = hdr.initrd_addr_max + 1; /* Zero for no limit */
+
+ if (hdr.version < 0x0205 || !(hdr.loadflags & LOAD_HIGH))
+ hdr.relocatable_kernel = 0;
+
+ if (hdr.version < 0x0206)
+ hdr.cmdline_max_len = 256;
+
+ if (cmdline_size > hdr.cmdline_max_len) {
+ cmdline_size = hdr.cmdline_max_len;
+ cmdline[cmdline_size - 1] = '\0';
+ }
+
+ if (hdr.version < 0x0202 || !(hdr.loadflags & 0x01))
+ cmdline_offset = (0x9ff0 - cmdline_size) & ~15;
+ else
+ cmdline_offset = 0x10000;
+
+ real_mode_size = (hdr.setup_sects + 1) << 9;
+ real_mode_base = (hdr.loadflags & LOAD_HIGH) ? 0x10000 : 0x90000;
+ prot_mode_base = (hdr.loadflags & LOAD_HIGH) ? 0x100000 : 0x10000;
+ prot_mode_size = kernel_size - real_mode_size;
+
+ if (!(hdr.loadflags & LOAD_HIGH) && prot_mode_size > 512 * 1024)
+ goto bail; /* Kernel cannot be loaded low */
+
+ if (initramfs && hdr.version < 0x0200)
+ goto bail; /* initrd/initramfs not supported */
+
+ if (hdr.version >= 0x0200) {
+ whdr->type_of_loader = 0x30; /* SYSLINUX unknown module */
+ if (hdr.version >= 0x0201) {
+ whdr->heap_end_ptr = cmdline_offset - 0x0200;
+ whdr->loadflags |= CAN_USE_HEAP;
+ }
+ if (hdr.version >= 0x0202) {
+ whdr->cmd_line_ptr = real_mode_base + cmdline_offset;
+ } else {
+ whdr->old_cmd_line_magic = OLD_CMDLINE_MAGIC;
+ whdr->old_cmd_line_offset = cmdline_offset;
+ /* Be paranoid and round up to a multiple of 16 */
+ whdr->setup_move_size = (cmdline_offset + cmdline_size + 15) & ~15;
+ }
+ }
+
+ /* Get the memory map */
+ mmap = syslinux_memory_map(); /* Memory map for shuffle_boot */
+ amap = syslinux_dup_memmap(mmap); /* Keep track of available memory */
+ if (!mmap || !amap)
+ goto bail;
+
+#if DEBUG
+ dprintf("Initial memory map:\n");
+ syslinux_dump_memmap(stdout, mmap);
+#endif
+
+ /* If the user has specified a memory limit, mark that as unavailable.
+ Question: should we mark this off-limit in the mmap as well (meaning
+ it's unavailable to the boot loader, which probably has already touched
+ some of it), or just in the amap? */
+ if (memlimit)
+ if (syslinux_add_memmap(&amap, memlimit, -memlimit, SMT_RESERVED))
+ goto bail;
+
+ /* Place the kernel in memory */
+
+ /* First, find a suitable place for the protected-mode code */
+ if (syslinux_memmap_type(amap, prot_mode_base, prot_mode_size)
+ != SMT_FREE) {
+ const struct syslinux_memmap *mp;
+ if (!hdr.relocatable_kernel)
+ goto bail; /* Can't relocate - no hope */
+
+ ok = false;
+ for (mp = amap; mp; mp = mp->next) {
+ addr_t start, end;
+ start = mp->start;
+ end = mp->next->start;
+
+ if (mp->type != SMT_FREE)
+ continue;
+
+ if (end <= prot_mode_base)
+ continue; /* Only relocate upwards */
+
+ if (start <= prot_mode_base)
+ start = prot_mode_base;
+
+ start = ALIGN_UP(start, hdr.kernel_alignment);
+ if (start >= end)
+ continue;
+
+ /* The 3* here is a total fudge factor... it's supposed to
+ account for the fact that the kernel needs to be decompressed,
+ and then followed by the BSS and BRK regions. This doesn't,
+ however, account for the fact that the kernel is decompressed
+ into a whole other place, either. */
+ if (end - start >= 3 * prot_mode_size) {
+ whdr->code32_start += start - prot_mode_base;
+ prot_mode_base = start;
+ ok = true;
+ break;
+ }
+ }
+
+ if (!ok)
+ goto bail;
+ }
+
+ /* Real mode code */
+ if (syslinux_memmap_type(amap, real_mode_base,
+ cmdline_offset + cmdline_size) != SMT_FREE) {
+ const struct syslinux_memmap *mp;
+
+ ok = false;
+ for (mp = amap; mp; mp = mp->next) {
+ addr_t start, end;
+ start = mp->start;
+ end = mp->next->start;
+
+ if (mp->type != SMT_FREE)
+ continue;
+
+ if (start < real_mode_base)
+ start = real_mode_base; /* Lowest address we'll use */
+ if (end > 640 * 1024)
+ end = 640 * 1024;
+
+ start = ALIGN_UP(start, 16);
+ if (start > 0x90000 || start >= end)
+ continue;
+
+ if (end - start >= cmdline_offset + cmdline_size) {
+ real_mode_base = start;
+ ok = true;
+ break;
+ }
+ }
+ }
+
+ if (syslinux_add_movelist(&fraglist, real_mode_base, (addr_t) kernel_buf,
+ real_mode_size))
+ goto bail;
+ if (syslinux_add_memmap
+ (&amap, real_mode_base, cmdline_offset + cmdline_size, SMT_ALLOC))
+ goto bail;
+
+ /* Zero region between real mode code and cmdline */
+ if (syslinux_add_memmap(&mmap, real_mode_base + real_mode_size,
+ cmdline_offset - real_mode_size, SMT_ZERO))
+ goto bail;
+
+ /* Command line */
+ if (syslinux_add_movelist(&fraglist, real_mode_base + cmdline_offset,
+ (addr_t) cmdline, cmdline_size))
+ goto bail;
+
+ /* Protected-mode code */
+ if (syslinux_add_movelist(&fraglist, prot_mode_base,
+ (addr_t) kernel_buf + real_mode_size,
+ prot_mode_size))
+ goto bail;
+ if (syslinux_add_memmap(&amap, prot_mode_base, prot_mode_size, SMT_ALLOC))
+ goto bail;
+
+ /* Figure out the size of the initramfs, and where to put it.
+ We should put it at the highest possible address which is
+ <= hdr.initrd_addr_max, which fits the entire initramfs. */
+
+ irf_size = initramfs_size(initramfs); /* Handles initramfs == NULL */
+
+ if (irf_size) {
+ addr_t best_addr = 0;
+ struct syslinux_memmap *ml;
+ const addr_t align_mask = INITRAMFS_MAX_ALIGN - 1;
+
+ if (irf_size) {
+ for (ml = amap; ml->type != SMT_END; ml = ml->next) {
+ addr_t adj_start = (ml->start + align_mask) & ~align_mask;
+ addr_t adj_end = ml->next->start & ~align_mask;
+ if (ml->type == SMT_FREE && adj_end - adj_start >= irf_size)
+ best_addr = (adj_end - irf_size) & ~align_mask;
+ }
+
+ if (!best_addr)
+ goto bail; /* Insufficient memory for initramfs */
+
+ whdr->ramdisk_image = best_addr;
+ whdr->ramdisk_size = irf_size;
+
+ if (syslinux_add_memmap(&amap, best_addr, irf_size, SMT_ALLOC))
+ goto bail;
+
+ if (map_initramfs(&fraglist, &mmap, initramfs, best_addr))
+ goto bail;
+ }
+ }
+
+ /* Set up the registers on entry */
+ memset(&regs, 0, sizeof regs);
+ regs.es = regs.ds = regs.ss = regs.fs = regs.gs = real_mode_base >> 4;
+ regs.cs = (real_mode_base >> 4) + 0x20;
+ /* regs.ip = 0; */
+ /* Linux is OK with sp = 0 = 64K, but perhaps other things aren't... */
+ regs.esp.w[0] = min(cmdline_offset, (size_t) 0xfff0);
+
+#if DEBUG
+ dprintf("Final memory map:\n");
+ syslinux_dump_memmap(stdout, mmap);
+
+ dprintf("Final available map:\n");
+ syslinux_dump_memmap(stdout, amap);
+
+ dprintf("Initial movelist:\n");
+ syslinux_dump_movelist(stdout, fraglist);
+#endif
+
+ syslinux_shuffle_boot_rm(fraglist, mmap, 0, &regs);
+
+bail:
+ syslinux_free_movelist(fraglist);
+ syslinux_free_memmap(mmap);
+ syslinux_free_memmap(amap);
+ return -1;
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/loadfile.c b/contrib/syslinux-4.02/com32/lib/syslinux/loadfile.c
new file mode 100644
index 0000000..fa96c65
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/loadfile.c
@@ -0,0 +1,63 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2005-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * loadfile.c
+ *
+ * Read the contents of a data file into a malloc'd buffer
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include <syslinux/loadfile.h>
+
+#define INCREMENTAL_CHUNK 1024*1024
+
+int loadfile(const char *filename, void **ptr, size_t * len)
+{
+ FILE *f;
+ int rv, e;
+
+ f = fopen(filename, "r");
+ if (!f)
+ return -1;
+
+ rv = floadfile(f, ptr, len, NULL, 0);
+ e = errno;
+
+ fclose(f);
+
+ if (rv)
+ errno = e;
+ return rv;
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/localboot.c b/contrib/syslinux-4.02/com32/lib/syslinux/localboot.c
new file mode 100644
index 0000000..3b480c7
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/localboot.c
@@ -0,0 +1,42 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <syslinux/boot.h>
+#include <stddef.h>
+#include <com32.h>
+
+/* This returns only on failure */
+
+void syslinux_local_boot(uint16_t flags)
+{
+ static com32sys_t ireg;
+
+ ireg.eax.w[0] = 0x0014;
+ ireg.edx.w[0] = flags;
+
+ __intcall(0x22, &ireg, NULL);
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/memmap.c b/contrib/syslinux-4.02/com32/lib/syslinux/memmap.c
new file mode 100644
index 0000000..12baa33
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/memmap.c
@@ -0,0 +1,65 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * memmap.c
+ *
+ * Create initial memory map for "shuffle and boot" operation
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <inttypes.h>
+
+#include <syslinux/memscan.h>
+#include <syslinux/movebits.h>
+
+static int syslinux_memory_map_callback(void *map, addr_t start,
+ addr_t len, bool valid)
+{
+ struct syslinux_memmap **mmap = map;
+ return syslinux_add_memmap(mmap, start, len,
+ valid ? SMT_FREE : SMT_RESERVED);
+}
+
+struct syslinux_memmap *syslinux_memory_map(void)
+{
+ struct syslinux_memmap *mmap;
+
+ mmap = syslinux_init_memmap();
+ if (!mmap)
+ return NULL;
+
+ if (syslinux_scan_memory(syslinux_memory_map_callback, &mmap)) {
+ syslinux_free_memmap(mmap);
+ return NULL;
+ }
+
+ return mmap;
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/memscan.c b/contrib/syslinux-4.02/com32/lib/syslinux/memscan.c
new file mode 100644
index 0000000..fc676cb
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/memscan.c
@@ -0,0 +1,158 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * memscan.c
+ *
+ * Query the system for free memory
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <com32.h>
+
+#include <syslinux/memscan.h>
+
+struct e820_entry {
+ uint64_t start;
+ uint64_t len;
+ uint32_t type;
+};
+
+int syslinux_scan_memory(scan_memory_callback_t callback, void *data)
+{
+ static com32sys_t ireg;
+ com32sys_t oreg;
+ struct e820_entry *e820buf;
+ uint64_t start, len, maxlen;
+ int memfound = 0;
+ int rv;
+ addr_t dosmem;
+ const addr_t bios_data = 0x510; /* Amount to reserve for BIOS data */
+
+ /* Use INT 12h to get DOS memory */
+ __intcall(0x12, &__com32_zero_regs, &oreg);
+ dosmem = oreg.eax.w[0] << 10;
+ if (dosmem < 32 * 1024 || dosmem > 640 * 1024) {
+ /* INT 12h reports nonsense... now what? */
+ uint16_t ebda_seg = *(uint16_t *) 0x40e;
+ if (ebda_seg >= 0x8000 && ebda_seg < 0xa000)
+ dosmem = ebda_seg << 4;
+ else
+ dosmem = 640 * 1024; /* Hope for the best... */
+ }
+ rv = callback(data, bios_data, dosmem - bios_data, true);
+ if (rv)
+ return rv;
+
+ /* First try INT 15h AX=E820h */
+ e820buf = lzalloc(sizeof *e820buf);
+ if (!e820buf)
+ return -1;
+
+ ireg.eax.l = 0xe820;
+ ireg.edx.l = 0x534d4150;
+ ireg.ebx.l = 0;
+ ireg.ecx.l = sizeof(*e820buf);
+ ireg.es = SEG(e820buf);
+ ireg.edi.w[0] = OFFS(e820buf);
+
+ do {
+ __intcall(0x15, &ireg, &oreg);
+
+ if ((oreg.eflags.l & EFLAGS_CF) ||
+ (oreg.eax.l != 0x534d4150) || (oreg.ecx.l < 20))
+ break;
+
+ start = e820buf->start;
+ len = e820buf->len;
+
+ if (start < 0x100000000ULL) {
+ /* Don't rely on E820 being valid for low memory. Doing so
+ could mean stuff like overwriting the PXE stack even when
+ using "keeppxe", etc. */
+ if (start < 0x100000ULL) {
+ if (len > 0x100000ULL - start)
+ len -= 0x100000ULL - start;
+ else
+ len = 0;
+ start = 0x100000ULL;
+ }
+
+ maxlen = 0x100000000ULL - start;
+ if (len > maxlen)
+ len = maxlen;
+
+ if (len) {
+ rv = callback(data, (addr_t) start, (addr_t) len,
+ e820buf->type == 1);
+ if (rv)
+ return rv;
+ memfound = 1;
+ }
+ }
+
+ ireg.ebx.l = oreg.ebx.l;
+ } while (oreg.ebx.l);
+
+ lfree(e820buf);
+
+ if (memfound)
+ return 0;
+
+ /* Next try INT 15h AX=E801h */
+ ireg.eax.w[0] = 0xe801;
+ __intcall(0x15, &ireg, &oreg);
+
+ if (!(oreg.eflags.l & EFLAGS_CF) && oreg.ecx.w[0]) {
+ rv = callback(data, (addr_t) 1 << 20, oreg.ecx.w[0] << 10, true);
+ if (rv)
+ return rv;
+
+ if (oreg.edx.w[0]) {
+ rv = callback(data, (addr_t) 16 << 20, oreg.edx.w[0] << 16, true);
+ if (rv)
+ return rv;
+ }
+
+ return 0;
+ }
+
+ /* Finally try INT 15h AH=88h */
+ ireg.eax.w[0] = 0x8800;
+ if (!(oreg.eflags.l & EFLAGS_CF) && oreg.eax.w[0]) {
+ rv = callback(data, (addr_t) 1 << 20, oreg.ecx.w[0] << 10, true);
+ if (rv)
+ return rv;
+ }
+
+ return 0;
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/movebits.c b/contrib/syslinux-4.02/com32/lib/syslinux/movebits.c
new file mode 100644
index 0000000..bd5ce0e
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/movebits.c
@@ -0,0 +1,710 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * movebits.c
+ *
+ * Utility function to take a list of memory areas to shuffle and
+ * convert it to a set of shuffle operations.
+ *
+ * Note: a lot of the functions in this file deal with "parent pointers",
+ * which are pointers to a pointer to a list, or part of the list.
+ * They can be pointers to a variable holding the list root pointer,
+ * or pointers to a next field of a previous entry.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <setjmp.h>
+#include <minmax.h>
+#include <stdbool.h>
+
+#include <syslinux/movebits.h>
+
+#ifndef DEBUG
+# ifdef TEST
+# define DEBUG 1
+# else
+# define DEBUG 0
+# endif
+#endif
+
+#if DEBUG
+# include <stdio.h>
+# define dprintf printf
+#else
+# define dprintf(...) ((void)0)
+#endif
+
+static jmp_buf new_movelist_bail;
+
+static struct syslinux_movelist *new_movelist(addr_t dst, addr_t src,
+ addr_t len)
+{
+ struct syslinux_movelist *ml = malloc(sizeof(struct syslinux_movelist));
+
+ if (!ml)
+ longjmp(new_movelist_bail, 1);
+
+ ml->dst = dst;
+ ml->src = src;
+ ml->len = len;
+ ml->next = NULL;
+
+ return ml;
+}
+
+static struct syslinux_movelist *dup_movelist(struct syslinux_movelist *src)
+{
+ struct syslinux_movelist *dst = NULL, **dstp = &dst, *ml;
+
+ while (src) {
+ ml = new_movelist(src->dst, src->src, src->len);
+ *dstp = ml;
+ dstp = &ml->next;
+ src = src->next;
+ }
+
+ return dst;
+}
+
+static void
+add_freelist(struct syslinux_memmap **mmap, addr_t start,
+ addr_t len, enum syslinux_memmap_types type)
+{
+ if (syslinux_add_memmap(mmap, start, len, type))
+ longjmp(new_movelist_bail, 1);
+}
+
+/*
+ * Take a chunk, entirely confined in **parentptr, and split it off so that
+ * it has its own structure.
+ */
+static struct syslinux_movelist **split_movelist(addr_t start, addr_t len,
+ struct syslinux_movelist
+ **parentptr)
+{
+ struct syslinux_movelist *m, *ml = *parentptr;
+
+ assert(start >= ml->src);
+ assert(start < ml->src + ml->len);
+
+ /* Split off the beginning */
+ if (start > ml->src) {
+ addr_t l = start - ml->src;
+
+ m = new_movelist(ml->dst + l, start, ml->len - l);
+ m->next = ml->next;
+ ml->len = l;
+ ml->next = m;
+
+ parentptr = &ml->next;
+ ml = m; /* Continue processing the new node */
+ }
+
+ /* Split off the end */
+ if (ml->len > len) {
+ addr_t l = ml->len - len;
+
+ m = new_movelist(ml->dst + len, ml->src + len, l);
+ m->next = ml->next;
+ ml->len = len;
+ ml->next = m;
+ }
+
+ return parentptr;
+}
+
+static void delete_movelist(struct syslinux_movelist **parentptr)
+{
+ struct syslinux_movelist *o = *parentptr;
+ *parentptr = o->next;
+ free(o);
+}
+
+static void free_movelist(struct syslinux_movelist **parentptr)
+{
+ while (*parentptr)
+ delete_movelist(parentptr);
+}
+
+/*
+ * Scan the freelist looking for a particular chunk of memory
+ */
+static const struct syslinux_memmap *is_free_zone(const struct syslinux_memmap
+ *list, addr_t start,
+ addr_t len)
+{
+ dprintf("f: 0x%08x bytes at 0x%08x\n", len, start);
+
+ addr_t last, llast;
+
+ last = start + len - 1;
+
+ while (list->type != SMT_END) {
+ llast = list->next->start - 1;
+ if (list->start <= start) {
+ if (llast >= last) {
+ /* Chunk has a single, well-defined type */
+ if (list->type == SMT_FREE) {
+ dprintf("F: 0x%08x bytes at 0x%08x\n",
+ list->next->start, list->start);
+ return list; /* It's free */
+ }
+ return NULL; /* Not free */
+ } else if (llast >= start) {
+ return NULL; /* Crosses region boundary */
+ }
+ }
+ list = list->next;
+ }
+
+ return NULL; /* Internal error? */
+}
+
+/*
+ * Scan the freelist looking for the smallest chunk of memory which
+ * can fit X bytes; returns the length of the block on success.
+ */
+static addr_t free_area(const struct syslinux_memmap *mmap,
+ addr_t len, addr_t * start)
+{
+ const struct syslinux_memmap *best = NULL;
+ const struct syslinux_memmap *s;
+ addr_t slen, best_len = -1;
+
+ for (s = mmap; s->type != SMT_END; s = s->next) {
+ if (s->type != SMT_FREE)
+ continue;
+ slen = s->next->start - s->start;
+ if (slen >= len) {
+ if (!best || best_len > slen) {
+ best = s;
+ best_len = slen;
+ }
+ }
+ }
+
+ if (best) {
+ *start = best->start;
+ return best_len;
+ } else {
+ return 0;
+ }
+}
+
+/*
+ * Remove a chunk from the freelist
+ */
+static void
+allocate_from(struct syslinux_memmap **mmap, addr_t start, addr_t len)
+{
+ syslinux_add_memmap(mmap, start, len, SMT_ALLOC);
+}
+
+/*
+ * Find chunks of a movelist which are one-to-many (one source, multiple
+ * destinations.) Those chunks can get turned into post-shuffle copies,
+ * to avoid confusing the shuffler.
+ */
+static void shuffle_dealias(struct syslinux_movelist **fraglist,
+ struct syslinux_movelist **postcopy)
+{
+ struct syslinux_movelist *mp, **mpp, *mx, *np;
+ addr_t ps, pe, xs, xe, delta;
+ bool advance;
+
+#if DEBUG
+ dprintf("Before alias resolution:\n");
+ syslinux_dump_movelist(stdout, *fraglist);
+#endif
+
+ *postcopy = NULL;
+
+ /*
+ * Note: as written, this is an O(n^2) algorithm; by producing a list
+ * sorted by destination address we could reduce it to O(n log n).
+ */
+ mpp = fraglist;
+ while ((mp = *mpp)) {
+ dprintf("mp -> (%#x,%#x,%#x)\n", mp->dst, mp->src, mp->len);
+ ps = mp->src;
+ pe = mp->src + mp->len - 1;
+ for (mx = *fraglist; mx != mp; mx = mx->next) {
+ dprintf("mx -> (%#x,%#x,%#x)\n", mx->dst, mx->src, mx->len);
+ /*
+ * If there is any overlap between mx and mp, mp should be
+ * modified and possibly split.
+ */
+ xs = mx->src;
+ xe = mx->src + mx->len - 1;
+
+ dprintf("?: %#x..%#x (inside %#x..%#x)\n", ps, pe, xs, xe);
+
+ if (pe <= xs || ps >= xe)
+ continue; /* No overlap */
+
+ advance = false;
+ *mpp = mp->next; /* Remove from list */
+
+ if (pe > xe) {
+ delta = pe - xe;
+ np = new_movelist(mp->dst + mp->len - delta,
+ mp->src + mp->len - delta, delta);
+ mp->len -= delta;
+ pe = xe;
+ np->next = *mpp;
+ *mpp = np;
+ advance = true;
+ }
+ if (ps < xs) {
+ delta = xs - ps;
+ np = new_movelist(mp->dst, ps, delta);
+ mp->src += delta;
+ ps = mp->src;
+ mp->dst += delta;
+ mp->len -= delta;
+ np->next = *mpp;
+ *mpp = np;
+ advance = true;
+ }
+
+ assert(ps >= xs && pe <= xe);
+
+ dprintf("Overlap: %#x..%#x (inside %#x..%#x)\n", ps, pe, xs, xe);
+
+ mp->src = mx->dst + (ps - xs);
+ mp->next = *postcopy;
+ *postcopy = mp;
+
+ mp = *mpp;
+
+ if (!advance)
+ goto restart;
+ }
+
+ mpp = &mp->next;
+restart:
+ ;
+ }
+
+#if DEBUG
+ dprintf("After alias resolution:\n");
+ syslinux_dump_movelist(stdout, *fraglist);
+ dprintf("Post-shuffle copies:\n");
+ syslinux_dump_movelist(stdout, *postcopy);
+#endif
+}
+
+/*
+ * The code to actually emit moving of a chunk into its final place.
+ */
+static void
+move_chunk(struct syslinux_movelist ***moves,
+ struct syslinux_memmap **mmap,
+ struct syslinux_movelist **fp, addr_t copylen)
+{
+ addr_t copydst, copysrc;
+ addr_t freebase, freelen;
+ addr_t needlen;
+ int reverse;
+ struct syslinux_movelist *f = *fp, *mv;
+
+ if (f->src < f->dst && (f->dst - f->src) < f->len) {
+ /* "Shift up" type overlap */
+ needlen = f->dst - f->src;
+ reverse = 1;
+ } else if (f->src > f->dst && (f->src - f->dst) < f->len) {
+ /* "Shift down" type overlap */
+ needlen = f->src - f->dst;
+ reverse = 0;
+ } else {
+ needlen = f->len;
+ reverse = 0;
+ }
+
+ copydst = f->dst;
+ copysrc = f->src;
+
+ dprintf("Q: copylen = 0x%08x, needlen = 0x%08x\n", copylen, needlen);
+
+ if (copylen < needlen) {
+ if (reverse) {
+ copydst += (f->len - copylen);
+ copysrc += (f->len - copylen);
+ }
+
+ dprintf("X: 0x%08x bytes at 0x%08x -> 0x%08x\n",
+ copylen, copysrc, copydst);
+
+ /* Didn't get all we wanted, so we have to split the chunk */
+ fp = split_movelist(copysrc, copylen, fp); /* Is this right? */
+ f = *fp;
+ }
+
+ mv = new_movelist(f->dst, f->src, f->len);
+ dprintf("A: 0x%08x bytes at 0x%08x -> 0x%08x\n", mv->len, mv->src, mv->dst);
+ **moves = mv;
+ *moves = &mv->next;
+
+ /* Figure out what memory we just freed up */
+ if (f->dst > f->src) {
+ freebase = f->src;
+ freelen = min(f->len, f->dst - f->src);
+ } else if (f->src >= f->dst + f->len) {
+ freebase = f->src;
+ freelen = f->len;
+ } else {
+ freelen = f->src - f->dst;
+ freebase = f->dst + f->len;
+ }
+
+ dprintf("F: 0x%08x bytes at 0x%08x\n", freelen, freebase);
+
+ add_freelist(mmap, freebase, freelen, SMT_FREE);
+
+ delete_movelist(fp);
+}
+
+/*
+ * moves is computed from "frags" and "freemem". "space" lists
+ * free memory areas at our disposal, and is (src, cnt) only.
+ */
+int
+syslinux_compute_movelist(struct syslinux_movelist **moves,
+ struct syslinux_movelist *ifrags,
+ struct syslinux_memmap *memmap)
+{
+ struct syslinux_memmap *mmap = NULL;
+ const struct syslinux_memmap *mm, *ep;
+ struct syslinux_movelist *frags = NULL;
+ struct syslinux_movelist *postcopy = NULL;
+ struct syslinux_movelist *mv;
+ struct syslinux_movelist *f, **fp;
+ struct syslinux_movelist *o, **op;
+ addr_t needbase, needlen, copysrc, copydst, copylen;
+ addr_t avail;
+ addr_t fstart, flen;
+ addr_t cbyte;
+ addr_t ep_len;
+ int rv = -1;
+ int reverse;
+
+ dprintf("entering syslinux_compute_movelist()...\n");
+
+ if (setjmp(new_movelist_bail)) {
+nomem:
+ dprintf("Out of working memory!\n");
+ goto bail;
+ }
+
+ *moves = NULL;
+
+ /* Create our memory map. Anything that is SMT_FREE or SMT_ZERO is
+ fair game, but mark anything used by source material as SMT_ALLOC. */
+ mmap = syslinux_init_memmap();
+ if (!mmap)
+ goto nomem;
+
+ frags = dup_movelist(ifrags);
+
+ /* Process one-to-many conditions */
+ shuffle_dealias(&frags, &postcopy);
+
+ for (mm = memmap; mm->type != SMT_END; mm = mm->next)
+ add_freelist(&mmap, mm->start, mm->next->start - mm->start,
+ mm->type == SMT_ZERO ? SMT_FREE : mm->type);
+
+ for (f = frags; f; f = f->next)
+ add_freelist(&mmap, f->src, f->len, SMT_ALLOC);
+
+ /* As long as there are unprocessed fragments in the chain... */
+ while ((fp = &frags, f = *fp)) {
+
+#if DEBUG
+ dprintf("Current free list:\n");
+ syslinux_dump_memmap(stdout, mmap);
+ dprintf("Current frag list:\n");
+ syslinux_dump_movelist(stdout, frags);
+#endif
+
+ /* Scan for fragments which can be discarded without action. */
+ if (f->src == f->dst) {
+ delete_movelist(fp);
+ continue;
+ }
+ op = &f->next;
+ while ((o = *op)) {
+ if (o->src == o->dst)
+ delete_movelist(op);
+ else
+ op = &o->next;
+ }
+
+ /* Scan for fragments which can be immediately moved
+ to their final destination, if so handle them now */
+ for (op = fp; (o = *op); op = &o->next) {
+ if (o->src < o->dst && (o->dst - o->src) < o->len) {
+ /* "Shift up" type overlap */
+ needlen = o->dst - o->src;
+ needbase = o->dst + (o->len - needlen);
+ reverse = 1;
+ cbyte = o->dst + o->len - 1;
+ } else if (o->src > o->dst && (o->src - o->dst) < o->len) {
+ /* "Shift down" type overlap */
+ needlen = o->src - o->dst;
+ needbase = o->dst;
+ reverse = 0;
+ cbyte = o->dst; /* "Critical byte" */
+ } else {
+ needlen = o->len;
+ needbase = o->dst;
+ reverse = 0;
+ cbyte = o->dst; /* "Critical byte" */
+ }
+
+ if (is_free_zone(mmap, needbase, needlen)) {
+ fp = op, f = o;
+ dprintf("!: 0x%08x bytes at 0x%08x -> 0x%08x\n",
+ f->len, f->src, f->dst);
+ copysrc = f->src;
+ copylen = needlen;
+ allocate_from(&mmap, needbase, copylen);
+ goto move_chunk;
+ }
+ }
+
+ /* Ok, bother. Need to do real work at least with one chunk. */
+
+ dprintf("@: 0x%08x bytes at 0x%08x -> 0x%08x\n",
+ f->len, f->src, f->dst);
+
+ /* See if we can move this chunk into place by claiming
+ the destination, or in the case of partial overlap, the
+ missing portion. */
+
+ if (f->src < f->dst && (f->dst - f->src) < f->len) {
+ /* "Shift up" type overlap */
+ needlen = f->dst - f->src;
+ needbase = f->dst + (f->len - needlen);
+ reverse = 1;
+ cbyte = f->dst + f->len - 1;
+ } else if (f->src > f->dst && (f->src - f->dst) < f->len) {
+ /* "Shift down" type overlap */
+ needlen = f->src - f->dst;
+ needbase = f->dst;
+ reverse = 0;
+ cbyte = f->dst; /* "Critical byte" */
+ } else {
+ needlen = f->len;
+ needbase = f->dst;
+ reverse = 0;
+ cbyte = f->dst;
+ }
+
+ dprintf("need: base = 0x%08x, len = 0x%08x, "
+ "reverse = %d, cbyte = 0x%08x\n",
+ needbase, needlen, reverse, cbyte);
+
+ ep = is_free_zone(mmap, cbyte, 1);
+ if (ep) {
+ ep_len = ep->next->start - ep->start;
+ if (reverse)
+ avail = needbase + needlen - ep->start;
+ else
+ avail = ep_len - (needbase - ep->start);
+ } else {
+ avail = 0;
+ }
+
+ if (avail) {
+ /* We can move at least part of this chunk into place without
+ further ado */
+ dprintf("space: start 0x%08x, len 0x%08x, free 0x%08x\n",
+ ep->start, ep_len, avail);
+ copylen = min(needlen, avail);
+
+ if (reverse)
+ allocate_from(&mmap, needbase + needlen - copylen, copylen);
+ else
+ allocate_from(&mmap, needbase, copylen);
+
+ goto move_chunk;
+ }
+
+ /* At this point, we need to evict something out of our space.
+ Find the object occupying the critical byte of our target space,
+ and move it out (the whole object if we can, otherwise a subset.)
+ Then move a chunk of ourselves into place. */
+ for (op = &f->next, o = *op; o; op = &o->next, o = *op) {
+
+ dprintf("O: 0x%08x bytes at 0x%08x -> 0x%08x\n",
+ o->len, o->src, o->dst);
+
+ if (!(o->src <= cbyte && o->src + o->len > cbyte))
+ continue; /* Not what we're looking for... */
+
+ /* Find somewhere to put it... */
+
+ if (is_free_zone(mmap, o->dst, o->len)) {
+ /* Score! We can move it into place directly... */
+ copydst = o->dst;
+ copysrc = o->src;
+ copylen = o->len;
+ } else if (free_area(mmap, o->len, &fstart)) {
+ /* We can move the whole chunk */
+ copydst = fstart;
+ copysrc = o->src;
+ copylen = o->len;
+ } else {
+ /* Well, copy as much as we can... */
+ if (syslinux_memmap_largest(mmap, SMT_FREE, &fstart, &flen)) {
+ dprintf("No free memory at all!\n");
+ goto bail; /* Stuck! */
+ }
+
+ /* Make sure we include the critical byte */
+ copydst = fstart;
+ if (reverse) {
+ copysrc = max(o->src, cbyte + 1 - flen);
+ copylen = cbyte + 1 - copysrc;
+ } else {
+ copysrc = cbyte;
+ copylen = min(flen, o->len - (cbyte - o->src));
+ }
+ }
+ allocate_from(&mmap, copydst, copylen);
+
+ if (copylen < o->len) {
+ op = split_movelist(copysrc, copylen, op);
+ o = *op;
+ }
+
+ mv = new_movelist(copydst, copysrc, copylen);
+ dprintf("C: 0x%08x bytes at 0x%08x -> 0x%08x\n",
+ mv->len, mv->src, mv->dst);
+ *moves = mv;
+ moves = &mv->next;
+
+ o->src = copydst;
+
+ if (copylen > needlen) {
+ /* We don't need all the memory we freed up. Mark it free. */
+ if (copysrc < needbase) {
+ add_freelist(&mmap, copysrc, needbase - copysrc, SMT_FREE);
+ copylen -= (needbase - copysrc);
+ }
+ if (copylen > needlen) {
+ add_freelist(&mmap, copysrc + needlen, copylen - needlen,
+ SMT_FREE);
+ copylen = needlen;
+ }
+ }
+ reverse = 0;
+ goto move_chunk;
+ }
+ dprintf("Cannot find the chunk containing the critical byte\n");
+ goto bail; /* Stuck! */
+
+move_chunk:
+ move_chunk(&moves, &mmap, fp, copylen);
+ }
+
+ /* Finally, append the postcopy chain to the end of the moves list */
+ for (op = moves; (o = *op); op = &o->next) ; /* Locate the end of the list */
+ *op = postcopy;
+ postcopy = NULL;
+
+ rv = 0;
+bail:
+ if (mmap)
+ syslinux_free_memmap(mmap);
+ if (frags)
+ free_movelist(&frags);
+ if (postcopy)
+ free_movelist(&postcopy);
+ return rv;
+}
+
+#ifdef TEST
+
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+ FILE *f;
+ unsigned long d, s, l;
+ struct syslinux_movelist *frags;
+ struct syslinux_movelist **fep = &frags;
+ struct syslinux_movelist *mv, *moves;
+ struct syslinux_memmap *memmap;
+ char line[BUFSIZ];
+
+ (void)argc;
+
+ memmap = syslinux_init_memmap();
+
+ f = fopen(argv[1], "r");
+ while (fgets(line, sizeof line, f) != NULL) {
+ if (sscanf(line, "%lx %lx %lx", &s, &d, &l) == 3) {
+ if (d) {
+ if (s == -1UL) {
+ syslinux_add_memmap(&memmap, d, l, SMT_ZERO);
+ } else {
+ mv = new_movelist(d, s, l);
+ *fep = mv;
+ fep = &mv->next;
+ }
+ } else {
+ syslinux_add_memmap(&memmap, s, l, SMT_FREE);
+ }
+ }
+ }
+ fclose(f);
+
+ *fep = NULL;
+
+ printf("Input move list:\n");
+ syslinux_dump_movelist(stdout, frags);
+ printf("Input free list:\n");
+ syslinux_dump_memmap(stdout, memmap);
+
+ if (syslinux_compute_movelist(&moves, frags, memmap)) {
+ printf("Failed to compute a move sequence\n");
+ return 1;
+ } else {
+ printf("Final move list:\n");
+ syslinux_dump_movelist(stdout, moves);
+ return 0;
+ }
+}
+
+#endif /* TEST */
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/pxe_dns.c b/contrib/syslinux-4.02/com32/lib/syslinux/pxe_dns.c
new file mode 100644
index 0000000..6620396
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/pxe_dns.c
@@ -0,0 +1,75 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2010 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * pxe_dns.c
+ *
+ * Resolve a hostname via DNS
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <com32.h>
+
+#include <syslinux/pxe.h>
+
+/* Returns the status code from PXE (0 on success),
+ or -1 on invocation failure */
+uint32_t pxe_dns(const char *hostname)
+{
+ com32sys_t regs;
+ union {
+ unsigned char b[4];
+ uint32_t ip;
+ } q;
+ char *lm_hostname;
+
+ /* Is this a dot-quad? */
+ if (sscanf(hostname, "%hhu.%hhu.%hhu.%hhu",
+ &q.b[0], &q.b[1], &q.b[2], &q.b[3]) == 4)
+ return q.ip;
+
+ lm_hostname = lstrdup(hostname);
+ if (!lm_hostname)
+ return 0;
+
+ memset(&regs, 0, sizeof regs);
+ regs.eax.w[0] = 0x0010;
+ regs.es = SEG(lm_hostname);
+ /* regs.ebx.w[0] = OFFS(lm_hostname); */
+
+ __intcall(0x22, &regs, &regs);
+
+ lfree(lm_hostname);
+
+ if (regs.eflags.l & EFLAGS_CF)
+ return 0;
+
+ return regs.eax.l;
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/pxe_get_cached.c b/contrib/syslinux-4.02/com32/lib/syslinux/pxe_get_cached.c
new file mode 100644
index 0000000..4704037
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/pxe_get_cached.c
@@ -0,0 +1,96 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * pxe_get_cached.c
+ *
+ * PXE call "get cached info"
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <com32.h>
+
+#include <syslinux/pxe.h>
+
+/* Returns the status code from PXE (0 on success),
+ or -1 on invocation failure */
+int pxe_get_cached_info(int level, void **buf, size_t * len)
+{
+ const int max_dhcp_packet = 2048;
+ com32sys_t regs;
+ t_PXENV_GET_CACHED_INFO *gci;
+ void *bbuf, *nbuf;
+ int err;
+
+ gci = lmalloc(sizeof *gci + max_dhcp_packet);
+ if (!gci)
+ return -1;
+
+ memset(&regs, 0, sizeof regs);
+ regs.eax.w[0] = 0x0009;
+ regs.ebx.w[0] = PXENV_GET_CACHED_INFO;
+ regs.es = SEG(gci);
+ /* regs.edi.w[0] = OFFS(gci); */
+
+ bbuf = &gci[1];
+
+ gci->Status = PXENV_STATUS_FAILURE;
+ gci->PacketType = level;
+ gci->BufferSize = gci->BufferLimit = max_dhcp_packet;
+ gci->Buffer.seg = SEG(bbuf);
+ gci->Buffer.offs = OFFS(bbuf);
+
+ __intcall(0x22, &regs, &regs);
+
+ if (regs.eflags.l & EFLAGS_CF) {
+ err = -1;
+ goto exit;
+ }
+
+ if (gci->Status) {
+ err = gci->Status;
+ goto exit;
+ }
+
+ nbuf = malloc(gci->BufferSize);
+ if (!nbuf) {
+ err = -1;
+ goto exit;
+ }
+
+ memcpy(nbuf, bbuf, gci->BufferSize);
+
+ *buf = nbuf;
+ *len = gci->BufferSize;
+ err = 0;
+
+exit:
+ lfree(gci);
+ return err;
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/pxe_get_nic.c b/contrib/syslinux-4.02/com32/lib/syslinux/pxe_get_nic.c
new file mode 100644
index 0000000..b301a75
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/pxe_get_nic.c
@@ -0,0 +1,67 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * pxe_get_cached.c
+ *
+ * PXE call "get cached info"
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <com32.h>
+
+#include <syslinux/pxe.h>
+
+/* Returns the status code from PXE (0 on success),
+ or -1 on invocation failure */
+int pxe_get_nic_type(t_PXENV_UNDI_GET_NIC_TYPE *gnt)
+{
+ com32sys_t regs;
+ t_PXENV_UNDI_GET_NIC_TYPE *lgnt;
+
+ lgnt = lzalloc(sizeof *lgnt);
+ if (!lgnt)
+ return -1;
+
+ memset(&regs, 0, sizeof regs);
+ regs.eax.w[0] = 0x0009;
+ regs.ebx.w[0] = PXENV_UNDI_GET_NIC_TYPE;
+ regs.es = SEG(lgnt);
+ /* regs.edi.w[0] = OFFS(lgnt); */
+
+ __intcall(0x22, &regs, &regs);
+
+ memcpy(gnt, lgnt, sizeof(t_PXENV_UNDI_GET_NIC_TYPE));
+ lfree(lgnt);
+
+ if (regs.eflags.l & EFLAGS_CF)
+ return -1;
+
+ return gnt->Status;
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/reboot.c b/contrib/syslinux-4.02/com32/lib/syslinux/reboot.c
new file mode 100644
index 0000000..2e3eb2b
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/reboot.c
@@ -0,0 +1,47 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * reboot.c
+ *
+ * Provoke a system reboot
+ */
+
+#include <stddef.h>
+#include <com32.h>
+#include <syslinux/reboot.h>
+
+__noreturn syslinux_reboot(int warm)
+{
+ uint16_t *const reboot_flag = (uint16_t *) 0x472;
+
+ *reboot_flag = warm ? 0x1234 : 0;
+ __farcall(0xf000, 0xfff0, &__com32_zero_regs, NULL);
+
+ while (1)
+ asm volatile ("hlt");
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/run_command.c b/contrib/syslinux-4.02/com32/lib/syslinux/run_command.c
new file mode 100644
index 0000000..a0ac9a0
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/run_command.c
@@ -0,0 +1,50 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <syslinux/boot.h>
+#include <stddef.h>
+#include <string.h>
+#include <com32.h>
+
+int syslinux_run_command(const char *command)
+{
+ static com32sys_t ireg;
+ char *lm_command = lstrdup(command);
+
+ if (!lm_command)
+ return -1;
+
+ ireg.eax.w[0] = 0x0003;
+ ireg.es = SEG(lm_command);
+ /* ireg.ebx.w[0] = OFFS(lm_command); */
+
+ __intcall(0x22, &ireg, NULL);
+
+ /* Should not return even on failure, but in case... */
+ lfree(lm_command);
+ return -1;
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/run_default.c b/contrib/syslinux-4.02/com32/lib/syslinux/run_default.c
new file mode 100644
index 0000000..8dc9fbe
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/run_default.c
@@ -0,0 +1,41 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <syslinux/boot.h>
+#include <stddef.h>
+#include <com32.h>
+
+__noreturn syslinux_run_default(void)
+{
+ static com32sys_t ireg;
+
+ ireg.eax.w[0] = 0x0004;
+ __intcall(0x22, &ireg, NULL);
+
+ /* Should not return even on failure */
+ for (;;) ;
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/runimage.c b/contrib/syslinux-4.02/com32/lib/syslinux/runimage.c
new file mode 100644
index 0000000..d5cdbc6
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/runimage.c
@@ -0,0 +1,70 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * runimage.c
+ *
+ * Load and run a syslinux image.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <syslinux/boot.h>
+#include <com32.h>
+
+void syslinux_run_kernel_image(const char *filename, const char *cmdline,
+ uint32_t ipappend_flags, uint32_t type)
+{
+ static com32sys_t ireg;
+ char *bbfilename = NULL;
+ char *bbcmdline = NULL;
+
+ bbfilename = lstrdup(filename);
+ if (!bbfilename)
+ goto fail;
+
+ bbcmdline = lstrdup(cmdline);
+ if (!bbcmdline)
+ goto fail;
+
+
+ ireg.eax.w[0] = 0x0016;
+ ireg.ds = SEG(bbfilename);
+ /* ireg.esi.w[0] = OFFS(bbfilename); */
+ ireg.es = SEG(bbcmdline);
+ /* ireg.ebx.w[0] = OFFS(bbcmdline); */
+ ireg.ecx.l = ipappend_flags;
+ ireg.edx.l = type;
+
+ __intcall(0x22, &ireg, 0);
+
+fail:
+ if (bbcmdline)
+ lfree(bbcmdline);
+ if (bbfilename)
+ lfree(bbfilename);
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/serial.c b/contrib/syslinux-4.02/com32/lib/syslinux/serial.c
new file mode 100644
index 0000000..f06e8c8
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/serial.c
@@ -0,0 +1,52 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/serial.c
+ *
+ * SYSLINUX serial console query
+ */
+
+#include <klibc/compiler.h>
+#include <syslinux/config.h>
+#include <string.h>
+#include <com32.h>
+
+struct syslinux_serial_console_info __syslinux_serial_console_info;
+
+void __constructor __syslinux_get_serial_console_info(void)
+{
+ static com32sys_t reg;
+
+ memset(&reg, 0, sizeof reg);
+ reg.eax.w[0] = 0x000b;
+ __intcall(0x22, &reg, &reg);
+
+ __syslinux_serial_console_info.iobase = reg.edx.w[0];
+ __syslinux_serial_console_info.divisor = reg.ecx.w[0];
+ __syslinux_serial_console_info.flowctl = reg.ebx.w[0];
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/setadv.c b/contrib/syslinux-4.02/com32/lib/syslinux/setadv.c
new file mode 100644
index 0000000..40f00a4
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/setadv.c
@@ -0,0 +1,116 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/setadv.c
+ *
+ * (Over)write a data item in the auxilliary data vector. To
+ * delete an item, set its length to zero.
+ *
+ * Return 0 on success, -1 on error, and set errno.
+ *
+ * NOTE: Data is not written to disk unless
+ * syslinux_adv_write() is called.
+ */
+
+#include <syslinux/adv.h>
+#include <klibc/compiler.h>
+#include <inttypes.h>
+#include <string.h>
+#include <errno.h>
+#include <alloca.h>
+
+int syslinux_setadv(int tag, size_t size, const void *data)
+{
+ uint8_t *p, *advtmp;
+ size_t rleft, left;
+
+ if ((unsigned)tag - 1 > 254) {
+ errno = EINVAL;
+ return -1; /* Impossible tag value */
+ }
+
+ if (size > 255) {
+ errno = ENOSPC; /* Max 255 bytes for a data item */
+ return -1;
+ }
+
+ rleft = left = syslinux_adv_size();
+ p = advtmp = alloca(left);
+ memcpy(p, syslinux_adv_ptr(), left); /* Make working copy */
+
+ while (rleft >= 2) {
+ uint8_t ptag = p[0];
+ size_t plen = p[1] + 2;
+
+ if (ptag == ADV_END)
+ break;
+
+ if (ptag == tag) {
+ /* Found our tag. Delete it. */
+
+ if (plen >= rleft) {
+ /* Entire remainder is our tag */
+ break;
+ }
+ memmove(p, p + plen, rleft - plen);
+ rleft -= plen; /* Fewer bytes to read, but not to write */
+ } else {
+ /* Not our tag */
+ if (plen > rleft)
+ break; /* Corrupt tag (overrun) - overwrite it */
+
+ left -= plen;
+ rleft -= plen;
+ p += plen;
+ }
+ }
+
+ /* Now (p, left) reflects the position to write in and how much space
+ we have for our data. */
+
+ if (size) {
+ if (left < size + 2) {
+ errno = ENOSPC; /* Not enough space for data */
+ return -1;
+ }
+
+ *p++ = tag;
+ *p++ = size;
+ memcpy(p, data, size);
+ p += size;
+ left -= size + 2;
+ }
+
+ memset(p, 0, left);
+
+ /* If we got here, everything went OK, commit the write to low memory */
+ memcpy(syslinux_adv_ptr(), advtmp, syslinux_adv_size());
+
+ return 0;
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/shuffle.c b/contrib/syslinux-4.02/com32/lib/syslinux/shuffle.c
new file mode 100644
index 0000000..6b5a601
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/shuffle.c
@@ -0,0 +1,275 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * shuffle.c
+ *
+ * Common code for "shuffle and boot" operation; generates a shuffle list
+ * and puts it in the bounce buffer. Returns the number of shuffle
+ * descriptors.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <com32.h>
+#include <minmax.h>
+#include <syslinux/movebits.h>
+#include <klibc/compiler.h>
+
+#ifndef DEBUG
+# define DEBUG 0
+#endif
+
+#define dprintf(f, ...) ((void)0)
+#define dprintf2(f, ...) ((void)0)
+
+#if DEBUG
+# include <stdio.h>
+# undef dprintf
+# define dprintf printf
+# if DEBUG > 1
+# undef dprintf2
+# define dprintf2 printf
+# endif
+#endif
+
+struct shuffle_descriptor {
+ uint32_t dst, src, len;
+};
+
+static int shuffler_size;
+
+static void __constructor __syslinux_get_shuffer_size(void)
+{
+ static com32sys_t reg;
+
+ reg.eax.w[0] = 0x0023;
+ __intcall(0x22, &reg, &reg);
+
+ shuffler_size = (reg.eflags.l & EFLAGS_CF) ? 2048 : reg.ecx.w[0];
+}
+
+/*
+ * Allocate descriptor memory in these chunks; if this is large we may
+ * waste memory, if it is small we may get slow convergence.
+ */
+#define DESC_BLOCK_SIZE 256
+
+int syslinux_do_shuffle(struct syslinux_movelist *fraglist,
+ struct syslinux_memmap *memmap,
+ addr_t entry_point, addr_t entry_type,
+ uint16_t bootflags)
+{
+ int rv = -1;
+ struct syslinux_movelist *moves = NULL, *mp;
+ struct syslinux_memmap *rxmap = NULL, *ml;
+ struct shuffle_descriptor *dp, *dbuf;
+ int np;
+ int desc_blocks, need_blocks;
+ int need_ptrs;
+ addr_t desczone, descfree, descaddr, descoffs;
+ int nmoves, nzero;
+ com32sys_t ireg;
+
+ descaddr = 0;
+ dp = dbuf = NULL;
+
+ /* Count the number of zero operations */
+ nzero = 0;
+ for (ml = memmap; ml->type != SMT_END; ml = ml->next) {
+ if (ml->type == SMT_ZERO)
+ nzero++;
+ }
+
+ /* Find the largest contiguous region unused by input *and* output;
+ this is where we put the move descriptor list and safe area */
+
+ rxmap = syslinux_dup_memmap(memmap);
+ if (!rxmap)
+ goto bail;
+ /* Avoid using the low 1 MB for the shuffle area -- this avoids
+ possible interference with the real mode code or stack */
+ if (syslinux_add_memmap(&rxmap, 0, 1024 * 1024, SMT_RESERVED))
+ goto bail;
+ for (mp = fraglist; mp; mp = mp->next) {
+ if (syslinux_add_memmap(&rxmap, mp->src, mp->len, SMT_ALLOC) ||
+ syslinux_add_memmap(&rxmap, mp->dst, mp->len, SMT_ALLOC))
+ goto bail;
+ }
+ if (syslinux_memmap_largest(rxmap, SMT_FREE, &desczone, &descfree))
+ goto bail;
+
+ syslinux_free_memmap(rxmap);
+
+ dprintf("desczone = 0x%08x, descfree = 0x%08x\n", desczone, descfree);
+
+ rxmap = syslinux_dup_memmap(memmap);
+ if (!rxmap)
+ goto bail;
+
+ desc_blocks = (nzero + DESC_BLOCK_SIZE - 1) / DESC_BLOCK_SIZE;
+ for (;;) {
+ /* We want (desc_blocks) allocation blocks, plus the terminating
+ descriptor, plus the shuffler safe area. */
+ addr_t descmem = desc_blocks *
+ sizeof(struct shuffle_descriptor) * DESC_BLOCK_SIZE
+ + sizeof(struct shuffle_descriptor) + shuffler_size;
+
+ descaddr = (desczone + descfree - descmem) & ~3;
+
+ if (descaddr < desczone)
+ goto bail; /* No memory block large enough */
+
+ /* Mark memory used by shuffle descriptors as reserved */
+ if (syslinux_add_memmap(&rxmap, descaddr, descmem, SMT_RESERVED))
+ goto bail;
+
+#if DEBUG > 1
+ syslinux_dump_movelist(stdout, fraglist);
+#endif
+
+ if (syslinux_compute_movelist(&moves, fraglist, rxmap))
+ goto bail;
+
+ nmoves = 0;
+ for (mp = moves; mp; mp = mp->next)
+ nmoves++;
+
+ need_blocks = (nmoves + nzero + DESC_BLOCK_SIZE - 1) / DESC_BLOCK_SIZE;
+
+ if (desc_blocks >= need_blocks)
+ break; /* Sufficient memory, yay */
+
+ desc_blocks = need_blocks; /* Try again... */
+ }
+
+#if DEBUG > 1
+ dprintf("Final movelist:\n");
+ syslinux_dump_movelist(stdout, moves);
+#endif
+
+ syslinux_free_memmap(rxmap);
+ rxmap = NULL;
+
+ need_ptrs = nmoves + nzero + 1;
+ dbuf = malloc(need_ptrs * sizeof(struct shuffle_descriptor));
+ if (!dbuf)
+ goto bail;
+
+ descoffs = descaddr - (addr_t) dbuf;
+
+#if DEBUG
+ dprintf("nmoves = %d, nzero = %d, dbuf = %p, offs = 0x%08x\n",
+ nmoves, nzero, dbuf, descoffs);
+#endif
+
+ /* Copy the move sequence into the descriptor buffer */
+ np = 0;
+ dp = dbuf;
+ for (mp = moves; mp; mp = mp->next) {
+ dp->dst = mp->dst;
+ dp->src = mp->src;
+ dp->len = mp->len;
+ dprintf2("[ %08x %08x %08x ]\n", dp->dst, dp->src, dp->len);
+ dp++;
+ np++;
+ }
+
+ /* Copy bzero operations into the descriptor buffer */
+ for (ml = memmap; ml->type != SMT_END; ml = ml->next) {
+ if (ml->type == SMT_ZERO) {
+ dp->dst = ml->start;
+ dp->src = (addr_t) - 1; /* bzero region */
+ dp->len = ml->next->start - ml->start;
+ dprintf2("[ %08x %08x %08x ]\n", dp->dst, dp->src, dp->len);
+ dp++;
+ np++;
+ }
+ }
+
+ /* Finally, record the termination entry */
+ dp->dst = entry_point;
+ dp->src = entry_type;
+ dp->len = 0;
+ dp++;
+ np++;
+
+ if (np != need_ptrs) {
+ dprintf("!!! np = %d : nmoves = %d, nzero = %d, desc_blocks = %d\n",
+ np, nmoves, nzero, desc_blocks);
+ }
+
+ rv = 0;
+
+bail:
+ /* This is safe only because free() doesn't use the bounce buffer!!!! */
+ if (moves)
+ syslinux_free_movelist(moves);
+ if (rxmap)
+ syslinux_free_memmap(rxmap);
+
+ if (rv)
+ return rv;
+
+ /* Actually do it... */
+ memset(&ireg, 0, sizeof ireg);
+ ireg.edi.l = descaddr;
+ ireg.esi.l = (addr_t) dbuf;
+ ireg.ecx.l = (addr_t) dp - (addr_t) dbuf;
+ ireg.edx.w[0] = bootflags;
+ ireg.eax.w[0] = 0x0024;
+ __intcall(0x22, &ireg, NULL);
+
+ return -1; /* Shouldn't have returned! */
+}
+
+/*
+ * Common helper routine: takes a memory map and blots out the
+ * zones which are used in the destination of a fraglist
+ */
+struct syslinux_memmap *syslinux_target_memmap(struct syslinux_movelist
+ *fraglist,
+ struct syslinux_memmap *memmap)
+{
+ struct syslinux_memmap *tmap;
+ struct syslinux_movelist *mp;
+
+ tmap = syslinux_dup_memmap(memmap);
+ if (!tmap)
+ return NULL;
+
+ for (mp = fraglist; mp; mp = mp->next) {
+ if (syslinux_add_memmap(&tmap, mp->dst, mp->len, SMT_ALLOC)) {
+ syslinux_free_memmap(tmap);
+ return NULL;
+ }
+ }
+
+ return tmap;
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/shuffle_pm.c b/contrib/syslinux-4.02/com32/lib/syslinux/shuffle_pm.c
new file mode 100644
index 0000000..5e3183b
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/shuffle_pm.c
@@ -0,0 +1,77 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * shuffle_pm.c
+ *
+ * Shuffle and boot to protected mode code
+ */
+
+#include <inttypes.h>
+#include <syslinux/movebits.h>
+#include <syslinux/bootpm.h>
+
+int syslinux_shuffle_boot_pm(struct syslinux_movelist *fraglist,
+ struct syslinux_memmap *memmap,
+ uint16_t bootflags, struct syslinux_pm_regs *regs)
+{
+ uint8_t handoff_code[9 * 5], *p;
+ const uint32_t *rp;
+ int i, rv;
+ struct syslinux_memmap *tmap;
+ addr_t regstub, stublen;
+
+ tmap = syslinux_target_memmap(fraglist, memmap);
+ if (!tmap)
+ return -1;
+
+ regstub = 0x800; /* Locate anywhere above this point */
+ stublen = sizeof handoff_code;
+ rv = syslinux_memmap_find(tmap, SMT_FREE, &regstub, &stublen, 1);
+ syslinux_free_memmap(tmap);
+ if (rv)
+ return -1;
+
+ /* Build register-setting stub */
+ p = handoff_code;
+ rp = (const uint32_t *)regs;
+ for (i = 0; i < 8; i++) {
+ *p = 0xb8 + i; /* MOV gpr,imm32 */
+ *(uint32_t *) (p + 1) = *rp++;
+ p += 5;
+ }
+ *p = 0xe9; /* JMP */
+ *(uint32_t *) (p + 1) = regs->eip - regstub - sizeof handoff_code;
+
+ /* Add register-setting stub to shuffle list */
+ if (syslinux_add_movelist(&fraglist, regstub, (addr_t) handoff_code,
+ sizeof handoff_code))
+ return -1;
+
+ return syslinux_do_shuffle(fraglist, memmap, regstub, 1, bootflags);
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/shuffle_rm.c b/contrib/syslinux-4.02/com32/lib/syslinux/shuffle_rm.c
new file mode 100644
index 0000000..a7d16d6
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/shuffle_rm.c
@@ -0,0 +1,171 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * shuffle_rm.c
+ *
+ * Shuffle and boot to protected mode code
+ */
+
+#include <stdlib.h>
+#include <inttypes.h>
+#include <com32.h>
+#include <string.h>
+#include <syslinux/movebits.h>
+#include <syslinux/bootrm.h>
+
+enum gpr_index { R_AX, R_CX, R_DX, R_BX, R_SP, R_BP, R_SI, R_DI };
+enum seg_index { R_ES, R_CS, R_SS, R_DS, R_FS, R_GS };
+
+#define ST8(P,V) \
+ do { \
+ uint8_t *_p = (void *)(P); \
+ *_p++ = (V); \
+ (P) = (void *)_p; \
+ } while (0);
+#define ST16(P,V) \
+ do { \
+ uint16_t *_p = (void *)(P); \
+ *_p++ = (V); \
+ (P) = (void *)_p; \
+ } while (0)
+#define ST32(P,V) \
+ do { \
+ uint32_t *_p = (void *)(P); \
+ *_p++ = (V); \
+ (P) = (void *)_p; \
+ } while (0)
+
+#define MOV_TO_SEG(P,S,R) \
+ ST16(P, 0xc08e + ((R) << 8) + ((S) << 11))
+#define MOV_TO_R16(P,R,V) \
+ do { \
+ ST8(P, 0xb8 + (R)); \
+ ST16(P, V); \
+ } while (0)
+#define MOV_TO_R32(P,R,V) \
+ do { \
+ ST16(P, 0xb866 + ((R) << 8)); \
+ ST32(P, V); \
+ } while (0)
+
+int syslinux_shuffle_boot_rm(struct syslinux_movelist *fraglist,
+ struct syslinux_memmap *memmap,
+ uint16_t bootflags, struct syslinux_rm_regs *regs)
+{
+ const struct syslinux_rm_regs_alt {
+ uint16_t seg[6];
+ uint32_t gpr[8];
+ uint32_t csip;
+ bool sti;
+ } *rp;
+ int i, rv;
+ uint8_t handoff_code[8 + 5 * 5 + 8 * 6 + 1 + 5], *p;
+ uint16_t off;
+ struct syslinux_memmap *tmap;
+ addr_t regstub, stublen;
+ /* Assign GPRs for each sreg, don't use AX and SP */
+ static const uint8_t gpr_for_seg[6] =
+ { R_CX, R_DX, R_BX, R_BP, R_SI, R_DI };
+
+ tmap = syslinux_target_memmap(fraglist, memmap);
+ if (!tmap)
+ return -1;
+
+ /*
+ * Search for a good place to put the real-mode register stub.
+ * We prefer it as low as possible above 0x800. KVM barfs horribly
+ * if we're not aligned to a paragraph boundary, so set the alignment
+ * appropriately.
+ */
+ regstub = 0x800;
+ stublen = sizeof handoff_code;
+ rv = syslinux_memmap_find(tmap, SMT_FREE, &regstub, &stublen, 16);
+
+ if (rv || (regstub > 0x100000 - sizeof handoff_code)) {
+ /*
+ * Uh-oh. This isn't real-mode accessible memory.
+ * It might be possible to do something insane here like
+ * putting the stub in the IRQ vectors, or in the 0x5xx segment.
+ * This code tries the 0x510-0x7ff range and hopes for the best.
+ */
+ regstub = 0x510; /* Try the 0x5xx segment... */
+ stublen = sizeof handoff_code;
+ rv = syslinux_memmap_find(tmap, SMT_FREE, &regstub, &stublen, 16);
+
+ if (!rv && (regstub > 0x100000 - sizeof handoff_code))
+ rv = -1; /* No acceptable memory found */
+ }
+
+ syslinux_free_memmap(tmap);
+ if (rv)
+ return -1;
+
+ /* Build register-setting stub */
+ p = handoff_code;
+ rp = (const struct syslinux_rm_regs_alt *)regs;
+
+ /* Set up GPRs with segment registers - don't use AX */
+ for (i = 0; i < 6; i++) {
+ if (i != R_CS)
+ MOV_TO_R16(p, gpr_for_seg[i], rp->seg[i]);
+ }
+
+ /* Actual transition to real mode */
+ ST32(p, 0xeac0220f); /* MOV CR0,EAX; JMP FAR */
+ off = (p - handoff_code) + 4;
+ ST16(p, off); /* Offset */
+ ST16(p, regstub >> 4); /* Segment */
+
+ /* Load SS and ESP immediately */
+ MOV_TO_SEG(p, R_SS, R_BX);
+ MOV_TO_R32(p, R_SP, rp->gpr[R_SP]);
+
+ /* Load the other segments */
+ MOV_TO_SEG(p, R_ES, R_CX);
+ MOV_TO_SEG(p, R_DS, R_BP);
+ MOV_TO_SEG(p, R_FS, R_SI);
+ MOV_TO_SEG(p, R_GS, R_DI);
+
+ for (i = 0; i < 8; i++) {
+ if (i != R_SP)
+ MOV_TO_R32(p, i, rp->gpr[i]);
+ }
+
+ ST8(p, rp->sti ? 0xfb : 0xfa); /* STI/CLI */
+
+ ST8(p, 0xea); /* JMP FAR */
+ ST32(p, rp->csip);
+
+ /* Add register-setting stub to shuffle list */
+ if (syslinux_add_movelist(&fraglist, regstub, (addr_t) handoff_code,
+ sizeof handoff_code))
+ return -1;
+
+ return syslinux_do_shuffle(fraglist, memmap, regstub, 0, bootflags);
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/version.c b/contrib/syslinux-4.02/com32/lib/syslinux/version.c
new file mode 100644
index 0000000..15b617b
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/version.c
@@ -0,0 +1,46 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <syslinux/config.h>
+#include <klibc/compiler.h>
+#include <com32.h>
+
+struct syslinux_version __syslinux_version;
+
+void __constructor __syslinux_get_version(void)
+{
+ static com32sys_t reg;
+
+ reg.eax.w[0] = 0x0001;
+ __intcall(0x22, &reg, &reg);
+
+ __syslinux_version.version = reg.ecx.w[0];
+ __syslinux_version.max_api = reg.eax.w[0];
+ __syslinux_version.filesystem = reg.edx.b[0];
+ __syslinux_version.version_string = MK_PTR(reg.es, reg.esi.w[0]);
+ __syslinux_version.copyright_string = MK_PTR(reg.es, reg.edi.w[0]);
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/video/fontquery.c b/contrib/syslinux-4.02/com32/lib/syslinux/video/fontquery.c
new file mode 100644
index 0000000..dd5d86e
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/video/fontquery.c
@@ -0,0 +1,54 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/video/forcetext.c
+ */
+
+#include <syslinux/video.h>
+#include <com32.h>
+
+/*
+ * Returns height of font or zero if no custom font loaded
+ */
+int syslinux_font_query(uint8_t **font)
+{
+ static com32sys_t ireg;
+ com32sys_t oreg;
+ int height;
+
+ ireg.eax.w[0] = 0x0018;
+ __intcall(0x22, &ireg, &oreg);
+
+ height = !(oreg.eflags.l & EFLAGS_CF) ? oreg.eax.b[0] : 0;
+ if (height)
+ *font = MK_PTR(oreg.es, oreg.ebx.w[0]);
+
+ return height;
+}
+
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/video/forcetext.c b/contrib/syslinux-4.02/com32/lib/syslinux/video/forcetext.c
new file mode 100644
index 0000000..136cb27
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/video/forcetext.c
@@ -0,0 +1,42 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/video/forcetext.c
+ */
+
+#include <syslinux/video.h>
+#include <com32.h>
+
+void syslinux_force_text_mode(void)
+{
+ static com32sys_t ireg;
+
+ ireg.eax.w[0] = 0x0005;
+ __intcall(0x22, &ireg, NULL);
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/video/reportmode.c b/contrib/syslinux-4.02/com32/lib/syslinux/video/reportmode.c
new file mode 100644
index 0000000..57fd6fd
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/video/reportmode.c
@@ -0,0 +1,45 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/video/reportmode.c
+ */
+
+#include <syslinux/video.h>
+#include <com32.h>
+
+void syslinux_report_video_mode(uint16_t flags, uint16_t xsize, uint16_t ysize)
+{
+ static com32sys_t ireg;
+
+ ireg.eax.w[0] = 0x0017;
+ ireg.ebx.w[0] = flags;
+ ireg.ecx.w[0] = xsize;
+ ireg.edx.w[0] = ysize;
+ __intcall(0x22, &ireg, NULL);
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/zloadfile.c b/contrib/syslinux-4.02/com32/lib/syslinux/zloadfile.c
new file mode 100644
index 0000000..286d070
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/zloadfile.c
@@ -0,0 +1,59 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2005-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * zloadfile.c
+ *
+ * Read the contents of a possibly compressed data file into a malloc'd buffer
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <syslinux/zio.h>
+
+#include <syslinux/loadfile.h>
+
+#define INCREMENTAL_CHUNK 1024*1024
+
+int zloadfile(const char *filename, void **ptr, size_t * len)
+{
+ FILE *f;
+ int rv;
+
+ f = zfopen(filename, "r");
+ if (!f)
+ return -1;
+
+ rv = floadfile(f, ptr, len, NULL, 0);
+ fclose(f);
+
+ return rv;
+}
diff --git a/contrib/syslinux-4.02/com32/lib/syslinux/zonelist.c b/contrib/syslinux-4.02/com32/lib/syslinux/zonelist.c
new file mode 100644
index 0000000..b548211
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/lib/syslinux/zonelist.c
@@ -0,0 +1,301 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * zonelist.c
+ *
+ * Deal with syslinux_memmap's, which are data structures designed to
+ * hold memory maps. A zonelist is a sorted linked list of memory
+ * ranges, with the guarantee that no two adjacent blocks have the
+ * same range type. Additionally, all unspecified memory have a range
+ * type of zero.
+ */
+
+#include <stdlib.h>
+#include <syslinux/align.h>
+#include <syslinux/movebits.h>
+
+#ifndef DEBUG
+# ifdef TEST
+# define DEBUG 1
+# else
+# define DEBUG 0
+# endif
+#endif
+
+#if DEBUG
+# include <stdio.h>
+# define dprintf printf
+#else
+# define dprintf(...) ((void)0)
+#endif
+
+/*
+ * Create an empty syslinux_memmap list.
+ */
+struct syslinux_memmap *syslinux_init_memmap(void)
+{
+ struct syslinux_memmap *sp, *ep;
+
+ sp = malloc(sizeof(*sp));
+ if (!sp)
+ return NULL;
+
+ ep = malloc(sizeof(*ep));
+ if (!ep) {
+ free(sp);
+ return NULL;
+ }
+
+ sp->start = 0;
+ sp->type = SMT_UNDEFINED;
+ sp->next = ep;
+
+ ep->start = 0; /* Wrap around... */
+ ep->type = SMT_END; /* End of chain */
+ ep->next = NULL;
+
+ return sp;
+}
+
+/*
+ * Add an item to a syslinux_memmap list, potentially overwriting
+ * what is already there.
+ */
+int syslinux_add_memmap(struct syslinux_memmap **list,
+ addr_t start, addr_t len,
+ enum syslinux_memmap_types type)
+{
+ addr_t last;
+ struct syslinux_memmap *mp, **mpp;
+ struct syslinux_memmap *range;
+ enum syslinux_memmap_types oldtype;
+
+#if DEBUG
+ dprintf("Input memmap:\n");
+ syslinux_dump_memmap(stdout, *list);
+#endif
+
+ /* Remove this to make len == 0 mean all of memory */
+ if (len == 0)
+ return 0;
+
+ /* Last byte -- to avoid rollover */
+ last = start + len - 1;
+
+ mpp = list;
+ oldtype = SMT_END; /* Impossible value */
+ while (mp = *mpp, start > mp->start && mp->type != SMT_END) {
+ oldtype = mp->type;
+ mpp = &mp->next;
+ }
+
+ if (start < mp->start || mp->type == SMT_END) {
+ if (type != oldtype) {
+ /* Splice in a new start token */
+ range = malloc(sizeof(*range));
+ if (!range)
+ return -1;
+
+ range->start = start;
+ range->type = type;
+ *mpp = range;
+ range->next = mp;
+ mpp = &range->next;
+ }
+ } else {
+ /* mp is exactly aligned with the start of our region */
+ if (type != oldtype) {
+ /* Reclaim this entry as our own boundary marker */
+ oldtype = mp->type;
+ mp->type = type;
+ mpp = &mp->next;
+ }
+ }
+
+ while (mp = *mpp, last > mp->start - 1) {
+ oldtype = mp->type;
+ *mpp = mp->next;
+ free(mp);
+ }
+
+ if (last < mp->start - 1) {
+ if (oldtype != type) {
+ /* Need a new end token */
+ range = malloc(sizeof(*range));
+ if (!range)
+ return -1;
+
+ range->start = last + 1;
+ range->type = oldtype;
+ *mpp = range;
+ range->next = mp;
+ }
+ } else {
+ if (mp->type == type) {
+ /* Merge this region with the following one */
+ *mpp = mp->next;
+ free(mp);
+ }
+ }
+
+#if DEBUG
+ dprintf("After adding (%#x,%#x,%d):\n", start, len, type);
+ syslinux_dump_memmap(stdout, *list);
+#endif
+
+ return 0;
+}
+
+/*
+ * Verify what type a certain memory region is. This function returns
+ * SMT_ERROR if the memory region has multiple types.
+ */
+enum syslinux_memmap_types syslinux_memmap_type(struct syslinux_memmap *list,
+ addr_t start, addr_t len)
+{
+ addr_t last, llast;
+
+ last = start + len - 1;
+
+ while (list->type != SMT_END) {
+ llast = list->next->start - 1;
+ if (list->start <= start) {
+ if (llast >= last)
+ return list->type; /* Region has a well-defined type */
+ else if (llast >= start)
+ return SMT_ERROR; /* Crosses region boundary */
+ }
+ list = list->next;
+ }
+
+ return SMT_ERROR; /* Internal error? */
+}
+
+/*
+ * Find the largest zone of a specific type. Returns -1 on failure.
+ */
+int syslinux_memmap_largest(struct syslinux_memmap *list,
+ enum syslinux_memmap_types type,
+ addr_t * start, addr_t * len)
+{
+ addr_t size, best_size = 0;
+ struct syslinux_memmap *best = NULL;
+
+ while (list->type != SMT_END) {
+ size = list->next->start - list->start;
+
+ if (list->type == type && size > best_size) {
+ best = list;
+ best_size = size;
+ }
+
+ list = list->next;
+ }
+
+ if (!best)
+ return -1;
+
+ *start = best->start;
+ *len = best_size;
+
+ return 0;
+}
+
+/*
+ * Find the first (lowest address) zone of a specific type and of
+ * a certain minimum size, with an optional starting address.
+ * The input values of start and len are used as minima.
+ */
+int syslinux_memmap_find(struct syslinux_memmap *list,
+ enum syslinux_memmap_types type,
+ addr_t * start, addr_t * len, addr_t align)
+{
+ addr_t min_start = *start;
+ addr_t min_len = *len;
+
+ while (list->type != SMT_END) {
+ if (list->type == type) {
+ addr_t xstart, xlen;
+ xstart = min_start > list->start ? min_start : list->start;
+ xstart = ALIGN_UP(xstart, align);
+
+ if (xstart < list->next->start) {
+ xlen = list->next->start - xstart;
+ if (xlen >= min_len) {
+ *start = xstart;
+ *len = xlen;
+ return 0;
+ }
+ }
+ }
+ list = list->next;
+ }
+
+ return -1; /* Not found */
+}
+
+/*
+ * Free a zonelist.
+ */
+void syslinux_free_memmap(struct syslinux_memmap *list)
+{
+ struct syslinux_memmap *ml;
+
+ while (list) {
+ ml = list;
+ list = list->next;
+ free(ml);
+ }
+}
+
+/*
+ * Duplicate a zonelist. Returns NULL on failure.
+ */
+struct syslinux_memmap *syslinux_dup_memmap(struct syslinux_memmap *list)
+{
+ struct syslinux_memmap *newlist = NULL, **nlp = &newlist;
+ struct syslinux_memmap *ml;
+
+ while (list) {
+ ml = malloc(sizeof(*ml));
+ if (!ml) {
+ syslinux_free_memmap(newlist);
+ return NULL;
+ }
+ ml->start = list->start;
+ ml->type = list->type;
+ ml->next = NULL;
+ *nlp = ml;
+ nlp = &ml->next;
+
+ list = list->next;
+ }
+
+ return newlist;
+}