wok-current 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 +}