wok view syslinux/stuff/extra/ifmem.c @ rev 9214

nvidia: allow post_install without tty (again)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Fri Mar 11 11:22:16 2011 +0100 (2011-03-11)
parents e2bb5ccdcbeb
children 48283b8cd35d
line source
1 /* ----------------------------------------------------------------------- *
2 *
3 * Copyright 2009 Pascal Bellard - All Rights Reserved
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
8 * Boston MA 02110-1301, USA; either version 2 of the License, or
9 * (at your option) any later version; incorporated herein by reference.
10 *
11 * ----------------------------------------------------------------------- */
13 /*
14 * ifmem.c
15 *
16 * Run one command if the memory is large enought, and another if it isn't.
17 *
18 * Usage:
19 *
20 * label boot_kernel
21 * kernel ifmem.c
22 * append size_in_KB boot_large [size_in_KB boot_medium] boot_small
23 *
24 * label boot_large
25 * kernel vmlinuz_large_memory
26 * append ...
27 *
28 * label boot_small
29 * kernel vmlinuz_small_memory
30 * append ...
31 */
33 #include <inttypes.h>
34 #include <com32.h>
35 #include <console.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include <alloca.h>
39 #include <stdlib.h>
40 #include <syslinux/boot.h>
42 struct e820_data {
43 uint64_t base;
44 uint64_t len;
45 uint32_t type;
46 uint32_t extattr;
47 } __attribute__((packed));
49 // Get memory size in Kb
50 static unsigned long memory_size(void)
51 {
52 uint64_t bytes = 0;
53 com32sys_t ireg, oreg;
54 struct e820_data ed;
56 memset(&ireg, 0, sizeof ireg);
58 ireg.eax.w[0] = 0xe820;
59 ireg.edx.l = 0x534d4150;
60 ireg.ecx.l = sizeof(struct e820_data);
61 ireg.edi.w[0] = OFFS(__com32.cs_bounce);
62 ireg.es = SEG(__com32.cs_bounce);
64 memset(&ed, 0, sizeof ed);
65 ed.extattr = 1;
67 do {
68 memcpy(__com32.cs_bounce, &ed, sizeof ed);
70 __intcall(0x15, &ireg, &oreg);
71 if (oreg.eflags.l & EFLAGS_CF ||
72 oreg.eax.l != 0x534d4150 ||
73 oreg.ecx.l < 20)
74 break;
76 memcpy(&ed, __com32.cs_bounce, sizeof ed);
78 if (ed.type == 1)
79 bytes += ed.len;
81 ireg.ebx.l = oreg.ebx.l;
82 } while (ireg.ebx.l);
84 if (!bytes) {
85 memset(&ireg, 0, sizeof ireg);
86 ireg.eax.w[0] = 0x8800;
87 __intcall(0x15, &ireg, &oreg);
88 return ireg.eax.w[0];
89 }
90 return bytes / 1024;
91 }
93 int main(int argc, char *argv[])
94 {
95 char *s;
96 int i, j = 1;
97 unsigned long ram_size;
99 for (s = argv[1]; *s && (*s < '0' || *s > '9'); s++);
101 openconsole(&dev_null_r, &dev_stdcon_w);
102 if (argc < 4 || !*s) {
103 perror("\nUsage: ifmem.c32 size_KB boot_large_memory boot_small_memory\n");
104 return 1;
105 }
107 // find target according to ram size
108 ram_size = memory_size();
109 printf("Total memory found %luK.\n",ram_size);
110 for (i = 1; i + 2 < argc; ) {
111 char *p = s;
112 unsigned long scale = 1;
114 if (*p) while (p[1]) p++;
115 switch (*p | 0x20) {
116 case 'g': scale = 1024*1024; *p = 0; break;
117 case 'm': scale = 1024;
118 case 'k': *p = 0; break;
119 }
120 j = i++; // size
121 if (ram_size >= scale * strtoul(s, NULL, 0)) break;
122 s = argv[++i];
123 }
125 // find and copy extra parameters to command line
126 // assume the command line ends with two words (not number)
127 for (s = argv[i++]; i < argc; i++) {
128 char c = *argv[i];
129 if (c >= '0' && c <= '9') j = i;
130 if (i - j > 2 && i < argc) {
131 #define SZ 4096
132 static char cmdline[SZ];
133 char *p = cmdline, *q = s;
134 int j;
135 for (j = i; j <= argc; j++) {
136 while (*q && p < cmdline + SZ -1) *p++ = *q++;
137 if (p < cmdline + SZ -1) *p++ = ' ';
138 q = argv[j];
139 }
140 *p++ = 0;
141 s = cmdline;
142 break;
143 }
144 }
146 if (s) syslinux_run_command(s);
147 else syslinux_run_default();
148 return -1;
149 }