wok-next diff syslinux/stuff/extra/md5sum.c @ rev 12273
syslinux: merge md5sum, ifmem, reboot & poweroff modules
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Sat Apr 14 11:50:03 2012 +0200 (2012-04-14) |
parents | 188ed036ce84 |
children | 02a3222651d5 |
line diff
1.1 --- a/syslinux/stuff/extra/md5sum.c Tue Apr 03 13:12:44 2012 +0200 1.2 +++ b/syslinux/stuff/extra/md5sum.c Sat Apr 14 11:50:03 2012 +0200 1.3 @@ -299,14 +299,13 @@ 1.4 return hash_value; 1.5 } 1.6 1.7 -int main(int argc, char **argv) 1.8 +static int main_md5sum(int argc, char **argv) 1.9 { 1.10 int files = 0, tested = 0, good = 0; 1.11 static char clear_eol[] = " "; 1.12 1.13 (void) argc; 1.14 /* -c implied */ 1.15 - openconsole(&dev_rawcon_r, &dev_stdcon_w); 1.16 1.17 do { 1.18 FILE *fp; 1.19 @@ -356,5 +355,209 @@ 1.20 } while (*++argv); 1.21 printf("\r%d files OK, %d broken, %d not checked.%s\n", 1.22 good, tested - good, files - tested, clear_eol); 1.23 + return 0; 1.24 } 1.25 1.26 +/* 1.27 + * ifmem.c 1.28 + * 1.29 + * Run one command if the memory is large enought, and another if it isn't. 1.30 + * 1.31 + * Usage: 1.32 + * 1.33 + * label boot_kernel 1.34 + * kernel ifmem.c 1.35 + * append size_in_KB boot_large [size_in_KB boot_medium] boot_small 1.36 + * 1.37 + * label boot_large 1.38 + * kernel vmlinuz_large_memory 1.39 + * append ... 1.40 + * 1.41 + * label boot_small 1.42 + * kernel vmlinuz_small_memory 1.43 + * append ... 1.44 + */ 1.45 + 1.46 +#include <inttypes.h> 1.47 +#include <alloca.h> 1.48 +#include <syslinux/boot.h> 1.49 + 1.50 +struct e820_data { 1.51 + uint64_t base; 1.52 + uint64_t len; 1.53 + uint32_t type; 1.54 + uint32_t extattr; 1.55 +} __attribute__((packed)); 1.56 + 1.57 +// Get memory size in Kb 1.58 +static unsigned long memory_size(void) 1.59 +{ 1.60 + uint64_t bytes = 0; 1.61 + static com32sys_t ireg, oreg; 1.62 + static struct e820_data ed; 1.63 + 1.64 + ireg.eax.w[0] = 0xe820; 1.65 + ireg.edx.l = 0x534d4150; 1.66 + ireg.ecx.l = sizeof(struct e820_data); 1.67 + ireg.edi.w[0] = OFFS(__com32.cs_bounce); 1.68 + ireg.es = SEG(__com32.cs_bounce); 1.69 + 1.70 + ed.extattr = 1; 1.71 + 1.72 + do { 1.73 + memcpy(__com32.cs_bounce, &ed, sizeof ed); 1.74 + 1.75 + __intcall(0x15, &ireg, &oreg); 1.76 + if (oreg.eflags.l & EFLAGS_CF || 1.77 + oreg.eax.l != 0x534d4150 || 1.78 + oreg.ecx.l < 20) 1.79 + break; 1.80 + 1.81 + memcpy(&ed, __com32.cs_bounce, sizeof ed); 1.82 + 1.83 + if (ed.type == 1) 1.84 + bytes += ed.len; 1.85 + 1.86 + ireg.ebx.l = oreg.ebx.l; 1.87 + } while (ireg.ebx.l); 1.88 + 1.89 + if (!bytes) { 1.90 + memset(&ireg, 0, sizeof ireg); 1.91 + ireg.eax.w[0] = 0x8800; 1.92 + __intcall(0x15, &ireg, &oreg); 1.93 + return ireg.eax.w[0]; 1.94 + } 1.95 + return bytes >> 10; 1.96 +} 1.97 + 1.98 +static int main_ifmem(int argc, char *argv[]) 1.99 +{ 1.100 + int i; 1.101 + unsigned long ram_size; 1.102 + 1.103 + if (argc < 4) { 1.104 + perror("\nUsage: ifmem.c32 size_KB boot_large_memory boot_small_memory\n"); 1.105 + return 1; 1.106 + } 1.107 + 1.108 + // find target according to ram size 1.109 + ram_size = memory_size(); 1.110 + printf("Total memory found %luK.\n",ram_size); 1.111 + ram_size += (1 << 10); // add 1M to round boundaries... 1.112 + 1.113 + i = 1; 1.114 + do { 1.115 + char *s = argv[i]; 1.116 + char *p = s; 1.117 + unsigned long scale = 1; 1.118 + 1.119 + while (*p >= '0' && *p <= '9') p++; 1.120 + switch (*p | 0x20) { 1.121 + case 'g': scale <<= 10; 1.122 + case 'm': scale <<= 10; 1.123 + default : *p = 0; break; 1.124 + } 1.125 + i++; // seek to label 1.126 + if (ram_size >= scale * strtoul(s, NULL, 0)) break; 1.127 + i++; // next size or default label 1.128 + } while (i + 1 < argc); 1.129 + 1.130 + if (i != argc) syslinux_run_command(argv[i]); 1.131 + else syslinux_run_default(); 1.132 + return -1; 1.133 +} 1.134 + 1.135 +#include <syslinux/reboot.h> 1.136 + 1.137 +static int main_reboot(int argc, char *argv[]) 1.138 +{ 1.139 + int warm = 0; 1.140 + int i; 1.141 + 1.142 + for (i = 1; i < argc; i++) { 1.143 + if (!strcmp(argv[i], "-w") || !strcmp(argv[i], "--warm")) 1.144 + warm = 1; 1.145 + } 1.146 + 1.147 + syslinux_reboot(warm); 1.148 +} 1.149 + 1.150 +/* APM poweroff module. 1.151 + * based on poweroff.asm, Copyright 2009 Sebastian Herbszt 1.152 + */ 1.153 + 1.154 +static int main_poweroff(int argc, char *argv[]) 1.155 +{ 1.156 + static com32sys_t ireg, oreg; 1.157 + static char notsupported[] ="APM 1.1+ not supported"; 1.158 + unsigned i; 1.159 + static struct { 1.160 + unsigned short ax; 1.161 + unsigned short bx; 1.162 + unsigned short cx; 1.163 + char *msg; 1.164 + } inst[] = { 1.165 + { 0x5300, // APM Installation Check (00h) 1.166 + 0, // APM BIOS (0000h) 1.167 + 0, "APM not present" }, 1.168 + { 0x5301, // APM Real Mode Interface Connect (01h) 1.169 + 0, // APM BIOS (0000h) 1.170 + 0, "APM RM interface connect failed" }, 1.171 + { 0x530E, // APM Driver Version (0Eh) 1.172 + 0, // APM BIOS (0000h) 1.173 + 0x0101, // APM Driver Version version 1.1 1.174 + notsupported }, 1.175 + { 0x5307, // Set Power State (07h) 1.176 + 1, // All devices power managed by the APM 1.177 + 3, // Power state off 1.178 + "Power off failed" } 1.179 + }; 1.180 + 1.181 + (void) argc; 1.182 + (void) argv; 1.183 + for (i = 0; i < sizeof(inst)/sizeof(inst[0]); i++) { 1.184 + char *msg = inst[i].msg; 1.185 + 1.186 + ireg.eax.w[0] = inst[i].ax; 1.187 + ireg.ebx.w[0] = inst[i].bx; 1.188 + ireg.ecx.w[0] = inst[i].cx; 1.189 + __intcall(0x15, &ireg, &oreg); 1.190 + if ((oreg.eflags.l & EFLAGS_CF) == 0) { 1.191 + switch (inst[i].ax) { 1.192 + case 0x5300 : 1.193 + if (oreg.ebx.w[0] != 0x504D /* 'PM' */) break; 1.194 + msg = "Power management disabled"; 1.195 + if (oreg.ecx.w[0] & 8) break; // bit 3 APM BIOS Power Management disabled 1.196 + case 0x530E : 1.197 + msg = notsupported; 1.198 + if (oreg.eax.w[0] < 0x101) break; 1.199 + default : continue; 1.200 + } 1.201 + } 1.202 + printf("%s.\n", msg); 1.203 + return 1; 1.204 + } 1.205 + return 0; 1.206 +} 1.207 + 1.208 +int main(int argc, char *argv[]) 1.209 +{ 1.210 + unsigned i; 1.211 + static struct { 1.212 + char *name; 1.213 + int (*main)(int argc, char *argv[]); 1.214 + } bin[] = { 1.215 + { "md5sum", main_md5sum }, 1.216 + { "ifmem", main_ifmem }, 1.217 + { "reboot", main_reboot }, 1.218 + { "poweroff", main_poweroff } 1.219 + }; 1.220 + 1.221 + openconsole(&dev_null_r, &dev_stdcon_w); 1.222 + 1.223 + if (strstr(argv[0], "c32box")) { argc--; argv++; } 1.224 + for (i = 0; i < sizeof(bin)/sizeof(bin[0]); i++) 1.225 + if (strstr(argv[0], bin[i].name)) 1.226 + return bin[i].main(argc, argv); 1.227 + return 1; 1.228 +}