wok-next annotate syslinux/stuff/extra/ifmem.c @ rev 3922

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