# HG changeset patch # User Pascal Bellard # Date 1334397003 -7200 # Node ID af17de69f5350c2c5cfa7a4c598253802b1f3851 # Parent a7297503ad9ba105045d1b797ee96e67695438b7 syslinux: merge md5sum, ifmem, reboot & poweroff modules diff -r a7297503ad9b -r af17de69f535 syslinux/receipt --- a/syslinux/receipt Fri Apr 13 02:16:05 2012 +0200 +++ b/syslinux/receipt Sat Apr 14 11:50:03 2012 +0200 @@ -18,10 +18,9 @@ cd $src cp $stuff/tools/isohybrid.sh . cp $stuff/tools/keytab-lilo.pl . - cp $stuff/extra/ifmem.c com32/modules cp $stuff/extra/md5sum.c com32/modules - grep -q ifmem.c32 com32/modules/Makefile || - sed -i 's/ifcpu64.c32/ifcpu64.c32 ifmem.c32 md5sum.c32/' com32/modules/Makefile + grep -q md5sum.c32 com32/modules/Makefile || + sed -i 's/ifcpu64.c32/ifcpu64.c32 md5sum.c32/' com32/modules/Makefile make -C com32 ./isohybrid.sh --build for i in /usr/share/kbd/keymaps/i386/*/*.map.gz; do @@ -37,11 +36,8 @@ { mkdir -p $fs/boot/isolinux cp -a $src/core/isolinux.bin $fs/boot/isolinux - cp -a $src/com32/modules/reboot.c32 $fs/boot/isolinux - cp -a $src/com32/modules/ifmem.c32 $fs/boot/isolinux cp -a $src/com32/modules/md5sum.c32 $fs/boot/isolinux cp -a $src/com32/menu/vesamenu.c32 $fs/boot/isolinux - cp -a $src/modules/poweroff.com $fs/boot/isolinux # $stuff/isolinux.msg is the old way the have a splash image. cp $stuff/*.cfg $stuff/*.txt $stuff/help.* $stuff/opts.* $fs/boot/isolinux while read cfg kbd loc ; do @@ -79,4 +75,7 @@ post_install() { sed -i "s/XXXXXXXX/$(date +%Y%m%d)/" $1/boot/isolinux/isolinux.cfg + for i in ifmem reboot poweroff; do + ln $fs/boot/isolinux/md5sum.c32 $fs/boot/isolinux/$i.c32 + done } diff -r a7297503ad9b -r af17de69f535 syslinux/stuff/extra/ifmem.c --- a/syslinux/stuff/extra/ifmem.c Fri Apr 13 02:16:05 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2009 Pascal Bellard - All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston MA 02110-1301, USA; either version 2 of the License, or - * (at your option) any later version; incorporated herein by reference. - * - * ----------------------------------------------------------------------- */ - -/* - * ifmem.c - * - * Run one command if the memory is large enought, and another if it isn't. - * - * Usage: - * - * label boot_kernel - * kernel ifmem.c - * append size_in_KB boot_large [size_in_KB boot_medium] boot_small - * - * label boot_large - * kernel vmlinuz_large_memory - * append ... - * - * label boot_small - * kernel vmlinuz_small_memory - * append ... - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -struct e820_data { - uint64_t base; - uint64_t len; - uint32_t type; - uint32_t extattr; -} __attribute__((packed)); - -// Get memory size in Kb -static unsigned long memory_size(void) -{ - uint64_t bytes = 0; - static com32sys_t ireg, oreg; - static struct e820_data ed; - - ireg.eax.w[0] = 0xe820; - ireg.edx.l = 0x534d4150; - ireg.ecx.l = sizeof(struct e820_data); - ireg.edi.w[0] = OFFS(__com32.cs_bounce); - ireg.es = SEG(__com32.cs_bounce); - - ed.extattr = 1; - - do { - memcpy(__com32.cs_bounce, &ed, sizeof ed); - - __intcall(0x15, &ireg, &oreg); - if (oreg.eflags.l & EFLAGS_CF || - oreg.eax.l != 0x534d4150 || - oreg.ecx.l < 20) - break; - - memcpy(&ed, __com32.cs_bounce, sizeof ed); - - if (ed.type == 1) - bytes += ed.len; - - ireg.ebx.l = oreg.ebx.l; - } while (ireg.ebx.l); - - if (!bytes) { - memset(&ireg, 0, sizeof ireg); - ireg.eax.w[0] = 0x8800; - __intcall(0x15, &ireg, &oreg); - return ireg.eax.w[0]; - } - return bytes >> 10; -} - -int main(int argc, char *argv[]) -{ - int i; - unsigned long ram_size; - - openconsole(&dev_null_r, &dev_stdcon_w); - - if (argc < 4) { - perror("\nUsage: ifmem.c32 size_KB boot_large_memory boot_small_memory\n"); - return 1; - } - - // find target according to ram size - ram_size = memory_size(); - printf("Total memory found %luK.\n",ram_size); - ram_size += (1 << 10); // add 1M to round boundaries... - - i = 1; - do { - char *s = argv[i]; - char *p = s; - unsigned long scale = 1; - - while (*p >= '0' && *p <= '9') p++; - switch (*p | 0x20) { - case 'g': scale <<= 10; - case 'm': scale <<= 10; - default : *p = 0; break; - } - i++; // seek to label - if (ram_size >= scale * strtoul(s, NULL, 0)) break; - i++; // next size or default label - } while (i + 1 < argc); - - if (i != argc) syslinux_run_command(argv[i]); - else syslinux_run_default(); - return -1; -} diff -r a7297503ad9b -r af17de69f535 syslinux/stuff/extra/md5sum.c --- a/syslinux/stuff/extra/md5sum.c Fri Apr 13 02:16:05 2012 +0200 +++ b/syslinux/stuff/extra/md5sum.c Sat Apr 14 11:50:03 2012 +0200 @@ -299,14 +299,13 @@ return hash_value; } -int main(int argc, char **argv) +static int main_md5sum(int argc, char **argv) { int files = 0, tested = 0, good = 0; static char clear_eol[] = " "; (void) argc; /* -c implied */ - openconsole(&dev_rawcon_r, &dev_stdcon_w); do { FILE *fp; @@ -356,5 +355,209 @@ } while (*++argv); printf("\r%d files OK, %d broken, %d not checked.%s\n", good, tested - good, files - tested, clear_eol); + return 0; } +/* + * ifmem.c + * + * Run one command if the memory is large enought, and another if it isn't. + * + * Usage: + * + * label boot_kernel + * kernel ifmem.c + * append size_in_KB boot_large [size_in_KB boot_medium] boot_small + * + * label boot_large + * kernel vmlinuz_large_memory + * append ... + * + * label boot_small + * kernel vmlinuz_small_memory + * append ... + */ + +#include +#include +#include + +struct e820_data { + uint64_t base; + uint64_t len; + uint32_t type; + uint32_t extattr; +} __attribute__((packed)); + +// Get memory size in Kb +static unsigned long memory_size(void) +{ + uint64_t bytes = 0; + static com32sys_t ireg, oreg; + static struct e820_data ed; + + ireg.eax.w[0] = 0xe820; + ireg.edx.l = 0x534d4150; + ireg.ecx.l = sizeof(struct e820_data); + ireg.edi.w[0] = OFFS(__com32.cs_bounce); + ireg.es = SEG(__com32.cs_bounce); + + ed.extattr = 1; + + do { + memcpy(__com32.cs_bounce, &ed, sizeof ed); + + __intcall(0x15, &ireg, &oreg); + if (oreg.eflags.l & EFLAGS_CF || + oreg.eax.l != 0x534d4150 || + oreg.ecx.l < 20) + break; + + memcpy(&ed, __com32.cs_bounce, sizeof ed); + + if (ed.type == 1) + bytes += ed.len; + + ireg.ebx.l = oreg.ebx.l; + } while (ireg.ebx.l); + + if (!bytes) { + memset(&ireg, 0, sizeof ireg); + ireg.eax.w[0] = 0x8800; + __intcall(0x15, &ireg, &oreg); + return ireg.eax.w[0]; + } + return bytes >> 10; +} + +static int main_ifmem(int argc, char *argv[]) +{ + int i; + unsigned long ram_size; + + if (argc < 4) { + perror("\nUsage: ifmem.c32 size_KB boot_large_memory boot_small_memory\n"); + return 1; + } + + // find target according to ram size + ram_size = memory_size(); + printf("Total memory found %luK.\n",ram_size); + ram_size += (1 << 10); // add 1M to round boundaries... + + i = 1; + do { + char *s = argv[i]; + char *p = s; + unsigned long scale = 1; + + while (*p >= '0' && *p <= '9') p++; + switch (*p | 0x20) { + case 'g': scale <<= 10; + case 'm': scale <<= 10; + default : *p = 0; break; + } + i++; // seek to label + if (ram_size >= scale * strtoul(s, NULL, 0)) break; + i++; // next size or default label + } while (i + 1 < argc); + + if (i != argc) syslinux_run_command(argv[i]); + else syslinux_run_default(); + return -1; +} + +#include + +static int main_reboot(int argc, char *argv[]) +{ + int warm = 0; + int i; + + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-w") || !strcmp(argv[i], "--warm")) + warm = 1; + } + + syslinux_reboot(warm); +} + +/* APM poweroff module. + * based on poweroff.asm, Copyright 2009 Sebastian Herbszt + */ + +static int main_poweroff(int argc, char *argv[]) +{ + static com32sys_t ireg, oreg; + static char notsupported[] ="APM 1.1+ not supported"; + unsigned i; + static struct { + unsigned short ax; + unsigned short bx; + unsigned short cx; + char *msg; + } inst[] = { + { 0x5300, // APM Installation Check (00h) + 0, // APM BIOS (0000h) + 0, "APM not present" }, + { 0x5301, // APM Real Mode Interface Connect (01h) + 0, // APM BIOS (0000h) + 0, "APM RM interface connect failed" }, + { 0x530E, // APM Driver Version (0Eh) + 0, // APM BIOS (0000h) + 0x0101, // APM Driver Version version 1.1 + notsupported }, + { 0x5307, // Set Power State (07h) + 1, // All devices power managed by the APM + 3, // Power state off + "Power off failed" } + }; + + (void) argc; + (void) argv; + for (i = 0; i < sizeof(inst)/sizeof(inst[0]); i++) { + char *msg = inst[i].msg; + + ireg.eax.w[0] = inst[i].ax; + ireg.ebx.w[0] = inst[i].bx; + ireg.ecx.w[0] = inst[i].cx; + __intcall(0x15, &ireg, &oreg); + if ((oreg.eflags.l & EFLAGS_CF) == 0) { + switch (inst[i].ax) { + case 0x5300 : + if (oreg.ebx.w[0] != 0x504D /* 'PM' */) break; + msg = "Power management disabled"; + if (oreg.ecx.w[0] & 8) break; // bit 3 APM BIOS Power Management disabled + case 0x530E : + msg = notsupported; + if (oreg.eax.w[0] < 0x101) break; + default : continue; + } + } + printf("%s.\n", msg); + return 1; + } + return 0; +} + +int main(int argc, char *argv[]) +{ + unsigned i; + static struct { + char *name; + int (*main)(int argc, char *argv[]); + } bin[] = { + { "md5sum", main_md5sum }, + { "ifmem", main_ifmem }, + { "reboot", main_reboot }, + { "poweroff", main_poweroff } + }; + + openconsole(&dev_null_r, &dev_stdcon_w); + + if (strstr(argv[0], "c32box")) { argc--; argv++; } + for (i = 0; i < sizeof(bin)/sizeof(bin[0]); i++) + if (strstr(argv[0], bin[i].name)) + return bin[i].main(argc, argv); + return 1; +}