📄 misc.c
字号:
/* This file contains a collection of miscellaneous procedures:
* mem_init: initialize memory tables. Some memory is reported
* by the BIOS, some is guesstimated and checked later
* env_parse parse environment variable.
* bad_assertion for debugging
* bad_compare for debugging
*/
#include "kernel.h"
#include "assert.h"
#include <stdlib.h>
#include <minix/com.h>
#if (CHIP == INTEL)
#define EM_BASE 0x100000L /* base of extended memory on AT's */
#define SHADOW_BASE 0xFA0000L /* base of RAM shadowing ROM on some AT's */
#define SHADOW_MAX 0x060000L /* maximum usable shadow memory (16M limit) */
/*=========================================================================*
* mem_init *
*=========================================================================*/
PUBLIC void mem_init()
{
/* Initialize the memory size tables. This is complicated by fragmentation
* and different access strategies for protected mode. There must be a
* chunk at 0 big enough to hold Minix proper. For 286 and 386 processors,
* there can be extended memory (memory above 1MB). This usually starts at
* 1MB, but there may be another chunk just below 16MB, reserved under DOS
* for shadowing ROM, but available to Minix if the hardware can be re-mapped.
* In protected mode, extended memory is accessible assuming CLICK_SIZE is
* large enough, and is treated as ordinary memory.
*/
u32_t ext_clicks;
phys_clicks max_clicks;
/* Get the size of ordinary memory from the BIOS. */
mem[0].size = k_to_click(low_memsize); /* base = 0 */
if (pc_at && protected_mode) {
/* Get the size of extended memory from the BIOS. This is special
* except in protected mode, but protected mode is now normal.
* Note that no more than 16M can be addressed in 286 mode, so make
* sure that the highest memory address fits in a short when counted
* in clicks.
*/
ext_clicks = k_to_click((u32_t) ext_memsize);
max_clicks = USHRT_MAX - (EM_BASE >> CLICK_SHIFT);
mem[1].size = MIN(ext_clicks, max_clicks);
mem[1].base = EM_BASE >> CLICK_SHIFT;
if (ext_memsize <= (unsigned) ((SHADOW_BASE - EM_BASE) / 1024)
&& check_mem(SHADOW_BASE, SHADOW_MAX) == SHADOW_MAX) {
/* Shadow ROM memory. */
mem[2].size = SHADOW_MAX >> CLICK_SHIFT;
mem[2].base = SHADOW_BASE >> CLICK_SHIFT;
}
}
/* Total system memory. */
tot_mem_size = mem[0].size + mem[1].size + mem[2].size;
}
#endif /* (CHIP == INTEL) */
/*=========================================================================*
* env_parse *
*=========================================================================*/
PUBLIC int env_parse(env, fmt, field, param, min, max)
char *env; /* environment variable to inspect */
char *fmt; /* template to parse it with */
int field; /* field number of value to return */
long *param; /* address of parameter to get */
long min, max; /* minimum and maximum values for the parameter */
{
/* Parse an environment variable setting, something like "DPETH0=300:3".
* Panic if the parsing fails. Return EP_UNSET if the environment variable
* is not set, EP_OFF if it is set to "off", EP_ON if set to "on" or a
* field is left blank, or EP_SET if a field is given (return value through
* *param). Commas and colons may be used in the environment and format
* string, fields in the environment string may be empty, and punctuation
* may be missing to skip fields. The format string contains characters
* 'd', 'o', 'x' and 'c' to indicate that 10, 8, 16, or 0 is used as the
* last argument to strtol.
*/
char *val, *end;
long newpar;
int i = 0, radix, r;
if ((val = k_getenv(env)) == NIL_PTR) return(EP_UNSET);
if (strcmp(val, "off") == 0) return(EP_OFF);
if (strcmp(val, "on") == 0) return(EP_ON);
r = EP_ON;
for (;;) {
while (*val == ' ') val++;
if (*val == 0) return(r); /* the proper exit point */
if (*fmt == 0) break; /* too many values */
if (*val == ',' || *val == ':') {
/* Time to go to the next field. */
if (*fmt == ',' || *fmt == ':') i++;
if (*fmt++ == *val) val++;
} else {
/* Environment contains a value, get it. */
switch (*fmt) {
case 'd': radix = 10; break;
case 'o': radix = 010; break;
case 'x': radix = 0x10; break;
case 'c': radix = 0; break;
default: goto badenv;
}
newpar = strtol(val, &end, radix);
if (end == val) break; /* not a number */
val = end;
if (i == field) {
/* The field requested. */
if (newpar < min || newpar > max) break;
*param = newpar;
r = EP_SET;
}
}
}
badenv:
printf("Bad environment setting: '%s = %s'\n", env, k_getenv(env));
panic("", NO_NUM);
/*NOTREACHED*/
}
#if DEBUG
/*=========================================================================*
* bad_assertion *
*=========================================================================*/
PUBLIC void bad_assertion(file, line, what)
char *file;
int line;
char *what;
{
printf("panic at %s(%d): assertion \"%s\" failed\n", file, line, what);
panic(NULL, NO_NUM);
}
/*=========================================================================*
* bad_compare *
*=========================================================================*/
PUBLIC void bad_compare(file, line, lhs, what, rhs)
char *file;
int line;
int lhs;
char *what;
int rhs;
{
printf("panic at %s(%d): compare (%d) %s (%d) failed\n",
file, line, lhs, what, rhs);
panic(NULL, NO_NUM);
}
#endif /* DEBUG */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -