diff options
author | Michael Brown | 2005-05-17 18:44:57 +0200 |
---|---|---|
committer | Michael Brown | 2005-05-17 18:44:57 +0200 |
commit | 1097cf8685cd81f0003bd6f17d050e5174a85b90 (patch) | |
tree | 47a39f2a1e980cca43c28c4d1a6dfdf431b910b2 /contrib/romid | |
parent | Quickly hacked to use a buffer rather than a processor. (diff) | |
download | ipxe-1097cf8685cd81f0003bd6f17d050e5174a85b90.tar.gz ipxe-1097cf8685cd81f0003bd6f17d050e5174a85b90.tar.xz ipxe-1097cf8685cd81f0003bd6f17d050e5174a85b90.zip |
Initial revision
Diffstat (limited to 'contrib/romid')
-rw-r--r-- | contrib/romid/pktdrv.bat | 84 | ||||
-rw-r--r-- | contrib/romid/readme | 8 | ||||
-rw-r--r-- | contrib/romid/romid.c | 124 | ||||
-rw-r--r-- | contrib/romid/setenvs.c | 200 |
4 files changed, 416 insertions, 0 deletions
diff --git a/contrib/romid/pktdrv.bat b/contrib/romid/pktdrv.bat new file mode 100644 index 00000000..058fd4e9 --- /dev/null +++ b/contrib/romid/pktdrv.bat @@ -0,0 +1,84 @@ +@echo off
+if (%PKTDRV%)==(P) goto end
+A:\PKT\ROMID
+if (%ROMID%)==() goto select
+if (%ROMID%)==(NE) goto NE
+if (%ROMID%)==(WD) goto WD
+if (%ROMID%)==(3C509) goto 3C509
+if (%ROMID%)==(3C905B) goto 3C905B
+if (%ROMID%)==(EEPRO100) goto EEPRO100
+if (%PCIID%)==(10EC:8029) goto RTL8029
+if (%PCIID%)==(10EC:8139) goto RTL8139
+if (%PCIID%)==(11AD:0002) goto LITEON
+if (%PCIID%)==(1011:0009) goto DEC
+echo No Driver installed!
+goto end
+:select
+cls
+echo *** Select your network card.... ***
+echo.
+echo 1 -- Intel EtherExpress 100B PCI Adapter
+echo 2 -- 3Com 3C90X Etherlink III PCI Adapter
+echo 3 -- 3Com 3C5X9 Etherlink III ISA Adapter
+echo 4 -- NE2000 Novell ISA Adapter
+echo 5 -- Realtek 8029 PCI Adapter
+echo 6 -- Realtek 8139 PCI Adapter
+echo 7 -- SMC EliteUltra 8216 ISA Adapter
+echo 8 -- DEC21x4 Busmaster PCI Adapter
+echo 9 -- LiteOn PNIC Busmaster PCI Adapter
+echo.
+echo *** **************************** ***
+echo.
+choice /c123456789 /n Select:
+if errorlevel 9 goto LITEON
+if errorlevel 8 goto DEC
+if errorlevel 7 goto WD
+if errorlevel 6 goto RTL8139
+if errorlevel 5 goto RTL8029
+if errorlevel 4 goto NE
+if errorlevel 3 goto 3C509
+if errorlevel 2 goto 3C905B
+if errorlevel 1 goto EEPRO100
+goto end
+
+:EEPRO100
+A:\PKT\E100BPKT 0x60
+if errorlevel 0 goto ok
+goto end
+:NE
+A:\PKT\NE2000 0x60 11 0x0300
+if errorlevel 0 goto ok
+goto end
+:RTL8029
+A:\PKT\PCIPKT 0x60
+if errorlevel 0 goto ok
+goto end
+:RTL8139
+A:\PKT\RTSPKT 0x60
+if ERRORLEVEL 0 goto OK
+goto end
+:WD
+A:\PKT\SMC_WD 0x60
+if errorlevel 0 goto ok
+goto end
+:3C509
+A:\PKT\3C5X9PD 0x60
+if errorlevel 0 goto ok
+goto end
+:3C905B
+A:\PKT\3C90XPD 0x60
+if errorlevel 0 goto ok
+goto end
+:LITEON
+A:\PKT\FEPD 0x60
+if ERRORLEVEL 0 goto ok
+goto end
+:DEC
+A:\PKT\ETHPCI 0x60
+if ERRORLEVEL 0 goto ok
+goto end
+
+:ok
+SET PKTDRV=P
+:end
+
diff --git a/contrib/romid/readme b/contrib/romid/readme new file mode 100644 index 00000000..6c6c500a --- /dev/null +++ b/contrib/romid/readme @@ -0,0 +1,8 @@ +This simple utility has currently no correct error checking.
+If your environment space couldn't hold up the variables, the
+program breaks without an error message, so be sure to add a
+line similar to the following to your config.sys:
+SHELL=A:\COMMAND.COM A:\ /P/E:2048
+
+The batch is a sample which shows how it could be used for those
+one not familar with batch files and environment variables.
\ No newline at end of file diff --git a/contrib/romid/romid.c b/contrib/romid/romid.c new file mode 100644 index 00000000..f6049bfd --- /dev/null +++ b/contrib/romid/romid.c @@ -0,0 +1,124 @@ +/* This little program is my try to provide information about the + EtherBoot rom via environment variables to a batch file. This + could be done better, I think, but it works... + The program compiles with Borland C 3.1; other versions not tested. + The C code for setting the environment variables I got from an + archive, it was written by Richard Marks <rmarks@KSP.unisys.COM>. + ROMID is written by Guenter Knauf <eflash@gmx.net> +*/ +#define VERSION "0.6" +#define VDATE "2003-08-24" + +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define ROMSTART 0xC8000 +#define ROMEND 0xE8000 +#define ROMINCREMENT 0x00800 +#define ROMMASK 0x03FFF + +int verbose = 0; + +int settheenv(char *symbol, char *val); + +static int rom_scan(const unsigned char huge *rom,long offset,long len) { + long size,i,j; + char symbol[16]; + char val[64]; + char romid[64]; + char *rptr; + + if (rom[offset] != 0x55 || rom[offset+1] != 0xAA) + return 0; + + size = (long)rom[offset+2]*512L; + if (verbose) { + printf("Found ROM header at %04lX:0000; announces %ldk image\n", offset/16,(size+512)/1024); + if (offset & ROMMASK) + printf(" This is a unusual position; not all BIOSs might find it.\n" + " Try to move to a 16kB boundary.\n"); + if (size > len) { + printf(" This image extends beyond %04X:0000. It clashes with the system BIOS\n", ROMEND/16); + size = len; + } + } + + for (i=0; i<64; i++) { + if (rom[offset+size-3-i] == 0xff) + break; + } + if (20<i && i<63) { + i--; + for (j=0; j<i; j++) + val[j] = rom[offset+size-3-i+j]; + val[i] = 0; + } else + return 0; + + if (strstr(val, "therboot") == NULL) + return 0; + + if (verbose) + printf("ROM Signature '%s'\n", val); + if ((rptr = strstr(val, "rom")) != NULL) { + for (i=1; i<4; i++) { + rptr--; + if (rptr[0] == 0x2E) + break; + } + i = 0; + while (!(rptr[0] == 0x20 || rptr < val)) { + i++; + rptr--; + } + rptr++; + i--; + strncpy(romid, rptr, i); + romid[i] = 0; + if (verbose) + printf("ROM Driver ID '%s'\n", romid); + strcpy(symbol, "ROMID"); + if (settheenv(symbol, romid)) + printf("Error setting evironment var %s with value %s\n", symbol, romid); + } else { + if (verbose) + printf("Couldnt find driver name!\n"); + return 0; + } + if (rom[offset+0x1C] == 'P' && rom[offset+0x1D] == 'C' && rom[offset+0x1E] == 'I') { + sprintf(val, "%02X%02X:%02X%02X", rom[offset+0x21], rom[offset+0x20], + rom[offset+0x23], rom[offset+0x22]); + if (verbose) + printf("ROM Vendor ID '%s'\n", val); + strcpy(symbol, "PCIID"); + if (settheenv(symbol, val)) + printf("Error setting evironment var %s with value %s\n", symbol, val); + } + return 1; +} + +/* **************** main stuff **************** */ +int main (int argc, char *argv[]) { + long i; + + printf("\nROM-ID for Etherboot v%s (c) G. Knauf %s\n", VERSION, VDATE); + if (argc > 1) { + /* parse input parameters */ + for (argc--, argv++; *argv; argc--, argv++) { + if ((strnicmp (*argv, "-", 1) == 0) || (strnicmp (*argv, "/", 1) == 0)) { + if ((strnicmp (*argv, "-V", 2) == 0) || (strnicmp (*argv, "/V", 2) == 0)) { + verbose = 1; + } else { + printf("Usage: %s [-v]\n"); + } + } + } + } + for (i = ROMEND; (i -= ROMINCREMENT) >= ROMSTART;) + if (rom_scan(0,i,ROMEND-i)) + break; + + return 0; +} diff --git a/contrib/romid/setenvs.c b/contrib/romid/setenvs.c new file mode 100644 index 00000000..e18e399e --- /dev/null +++ b/contrib/romid/setenvs.c @@ -0,0 +1,200 @@ +/* subroutine to put a value string into an environment symbol. + Uses the controling command.com environment, not the programs. + This means that the env variable is set so other routines in + a .BAT file may use it. + + call: settheenv (char * symbol, char * val); + symbol is an asciiz string containing the env variable name, + val is an asciiz string containing the value to assign to this vbl. + + returns: 0 = OK, + 1 = failure. + failure is not unlikely. The env block may be full. Or on some + systems the env block might not be found + + SETENVS.C was written by Richard Marks <rmarks@KSP.unisys.COM>. +*/ + + +#include <stdio.h> +#include <dos.h> +#include <string.h> +#include <stdlib.h> + +typedef struct { + char fill1[0x0A]; + int *prev_term_handler; + int *prev_ctrl_c; + int *prev_crit_error; + char fill2[0x16]; + int envir_seg; +} psp; + +typedef struct { + char type; + int psp_segment; + int num_segments; + char fill[11]; + char arena_data; +} arena; + + +#define NORMAL_ATYPE 0x4D +#define LAST_ATYPE 0x5A + + +static arena * get_next_arena (arena * ap) { + return( MK_FP( FP_SEG(ap)+1+ap->num_segments, 0) ); +} + +/* returns 0 if passed pointer is to an arena, else returns 1 */ +static int is_valid_arena (arena * ap) { + arena * ap1; + if (ap->type == NORMAL_ATYPE && + (ap1=get_next_arena(ap))->type == NORMAL_ATYPE && + ( (ap1=get_next_arena(ap1))->type == NORMAL_ATYPE || + ap1->type == LAST_ATYPE) ) + return(0); + return (1); +} + + +static arena * get_first_arena () { +/* return pointer to the first arena. + * scan memory for a 0x4D on a segment start, + * see if this points to another two levels of arena + */ + arena * ap, * ap1; + int * temp; + int segment; + + for (segment=0; segment<_CS; segment++) { + ap = MK_FP(segment, 0); + if ( is_valid_arena (ap) == 0) return (ap); + } + return(NULL); +} /* end get_first_arena */ + + +static int is_valid_env (char * ad, int num_segs) { + char * base_ad; + base_ad = ad; + while ( (*ad) && (((ad-base_ad)>>4) < num_segs) ) { + if (strnicmp(ad, "COMSPEC=", 8)==0) return(0); + ad += strlen(ad) + 1; + } + return (1); +} + + +static arena * get_arena_of_environment () { +/* to get the arena of first environment block: + First get segment of COMMAND.COM from segment of previous critical err code. + Then scan all the arenas for an environment block with a matching PSP + segment */ + +arena * ap; +psp * pspp, * pspc; +unsigned int i, ccseg; + +/* set pspp to psp of this program */ +pspp = MK_FP(_psp,0); + +#ifdef DEBUG +printf("prog psp=%p\n",pspp); +#endif + +/* set pspc to psp of COMMAND.COM, back up a bit to get it if needed */ +ccseg = FP_SEG (pspp->prev_crit_error); +if ( (i=ccseg-32) < 60) i=60; + +while (ccseg>i) { + pspc = MK_FP (ccseg, 0); + if ( is_valid_arena((arena *) pspc) == 0) goto L1; + ccseg--; +} +return (NULL); + +L1: pspc = MK_FP (++ccseg, 0); +#ifdef DEBUG +printf("comm.com=%p\n",pspc); +#endif + +/* first see if env seg in command.com points to valid env block + if env seg is in a valid arena, then arena must point to this command.com + else assume env block is fabricated like for 4DOS, use 128 bytes */ + +ap = MK_FP (pspc->envir_seg-1, 0); +i = ap->num_segments; + +if (is_valid_arena (ap) == 0) { + if (ap->psp_segment != FP_SEG(pspc)) goto L2; +} else { + i = 9; +} + +if ( is_valid_env (&ap->arena_data, i) == 0 ) + return (ap); + +/* command.com did not so point, search thru all env blocks */ + +L2: +if ( (ap=get_first_arena()) != NULL ) { + while (ap->type != LAST_ATYPE) { +#ifdef DEBUG + printf("%p\n",ap); +#endif + if (ap->psp_segment == FP_SEG(pspc) && + is_valid_env (&ap->arena_data, ap->num_segments)==0 ) + return (ap); + + ap = get_next_arena(ap); + } +} return(NULL); +} /* end get_arena_of_environment */ + +/*****************************************************************************/ + +int settheenv(char * symbol, char * val) { +int total_size, + needed_size=0, + strlength; +char * sp, *op, *envir; +char symb_len=strlen(symbol); +char found=0; +arena * ap; + +strupr(symbol); + +/* first, can COMMAND.COM's envir block be found ? */ +if ( (ap=get_arena_of_environment()) == NULL) + return(1); + +/* search to end of the envir block, get sizes */ +total_size = 16 * ap->num_segments; +envir = &ap->arena_data; +op=sp=envir; +while (*sp) { + strlength = strlen(sp)+1; + if ( *(sp+symb_len)=='=' && + strnicmp(sp,symbol,symb_len)==0 ) + found=1; + else { + needed_size += strlength; + if (found) strcpy(op,sp); + op = &op[strlength]; + } + sp += strlength; +} +*op=0; +if (strlen(val) > 0) { + needed_size += 3 + strlen(symbol) + strlen(val); + if (needed_size > total_size) + return(1); /* could mess with environment expansion here */ + + strcpy(op, symbol); strcat(op, "="); strcat(op, val); + op += strlen(op)+1; + *op = 0; +} +return(0); +} /* end setheenv subroutine */ |