> >I have got the BIOS boot specification from Phoenix and by making > >some changes to Etherboot loader (adding PCI and PnP headers) got > >my etherexpress to boot, just that I cannot erase the flash now > >as it does not want to do stiffy boot anymore. > >Will have to set up dos ramdisk I guess... > > Can you please send me the patches so that I can add them to the next > release of Etherboot? > > Thanks, Ken > Ok here they go, sorry they are a bit ugly... Cheers, Alex ---------------------loader.asm----------------------------------------- ! At entry, the processor is in 16 bit real mode and the code is being ! executed from an address it was not linked to. Code must be pic and ! 32 bit sensitive until things are fixed up. #include "loader.inc" .text .globl _main _main: #ifdef BOOTROM .word 0xAA55 ! BIOS extension signature size: .byte 0 ! number of 512 byte blocks ! = number of 256 word blocks ! filled in by makerom program jmp over ! skip over checksum .byte 0 ! checksum jmp shortjmp ! alternate entry point +6 ! used by floppyload .word 0x0000 ! reserverd .word 0x0000 ! reserved .word 0x0000 ! reserved .word 0x0000 ! reserved .word 0x0000 ! reserved .word 0x0000 ! reserved .word 0x0000 ! reserved .word 0x0000 ! reserved .word PCI ! offset to pci data structure .word PnP ! offset to PnP expansion header PCI: .ascii "PCIR" ! signature .word 0x8086 ! vendor id (hardcode as Intel) ! should be filled by makerom ? .word 0x1229 ! device ID Intel 82557 ! should be filled by makerom ? .word 0x0000 ! pointer to vital product data .word 0x0018 ! PCI data structure length .byte 0 ! PCI data structure revision .byte 0 ! Class code byte 1 .byte 0 ! Class code byte 2 .byte 0x02 ! Class code byte 3 (from hexdumping ! Intel bootrom image) .word 0x0000 ! Image length same as offset 02h .word 0x0001 ! revision level of code /data .byte 0 ! code type .byte 0x80 ! indicator (from hexdumping ! Intel bootrom image) .word 0x0000 ! reserved shortjmp: jmp blockmove PnP: .ascii "$PnP" ! signature .byte 0x01 ! structure revision .byte 0x02 ! length (in 16 byte increments) .word 0x0000 ! offset of next header .byte 0 ! Reserved .byte 0 ! checksum filled by makerom .long 0x00000000 ! Device identifier .word 0x0000 ! pointer to manufacturer str .word 0x0000 ! pointer to product name .byte 0 ! device type code byte 1 .byte 0 ! device type code byte 2 .byte 2 ! device type code byte 3 (from ! hexdumping Intel bootrom image) .byte 0x14 ! device indictors (from ! hexdumping Intel bootrom image) .word 0x0000 ! boot connection vector .word 0x0000 ! disconnect vector .word over ! bootstrap entry vector .word 0x0000 ! reserved .word 0x0000 ! static resource information vector over: #ifndef NOINT19H push ax push ds xor ax,ax mov ds,ax ! access first 64kB segment mov ax,SCRATCHVEC+4 ! check if already installed cmp ax,#MAGIC ! check magic word jz installed mov ax,INT19VEC ! hook into INT19h mov SCRATCHVEC,ax mov ax,INT19VEC+2 mov SCRATCHVEC+2,ax mov ax,#start19h mov INT19VEC,ax mov ax,cs mov INT19VEC+2,ax mov ax,#MAGIC ! set magic word mov SCRATCHVEC+4,ax installed: pop ds pop ax retf start19h: ! clobber magic id, so that we will xor ax,ax ! not inadvertendly end up in an mov ds,ax ! endless loop mov SCRATCHVEC+4,ax mov ax,SCRATCHVEC+2 ! restore original INT19h handler mov INT19VEC+2,ax mov ax,SCRATCHVEC mov INT19VEC,ax #endif /* NOINT19H */ blockmove: mov si,#_body-_main ! offset of _body /* fall thru */ #else /* BOOTROM */ mov si,#0x100+_body-_main #endif /* BOOTROM */ ! Relocate body of boot code to RELOC:0 cld xor di,di ! di = 0 mov ax,#RELOC>>4 mov es,ax #ifdef BOOTROM xor cx,cx mov ax,cs mov ds,ax ! for the ref to size below mov ch,size-_main #else /* BOOTROM */ mov cx,#[_main-_body+COMSIZE]/2 #endif /* BOOTROM */ seg cs rep movsw ! Change stack mov bx,#RELOC>>4 ! new ss mov ds,bx ! new ds mov cx,#STACKADDR ! new sp cli mov ss,bx mov sp,cx callf #0,RELOC>>4 ! call Etherboot body int #0x19 ! The body of etherboot is attached here at build time .align 4 _body: _______________________________________________________________ ___________________makerom.c______________________________________ /************************************************************************ Calculate ROM size for 3rd byte and ROM checksum for 6th byte in ROM image. -3 option makes the last two bytes of an 8k ROM 0x80. The 3c503 ASIC will report this value regardless of the ROM contents, so we need to make the checksum work properly. A 3Com EtherStart ROM I have handy sets these to 0x80, so we'll use that for now. 0x04 has also been reported. Any more offers? ************************************************************************/ #define PHOENIX #include <stdio.h> #include <fcntl.h> #include <stdlib.h> /* should be powers of 2 and MAX a multiple of MIN */ #define MINROMSIZE 8192L #define MAXROMSIZE 65536L #define MAGIC_3C503 0x80 unsigned char *rom; long romsize = 0L; /* for autosizing */ /* read the first three bytes to get the ROM size */ long getromsize(FILE *fd) { unsigned char buffer[3]; long size, i; if (fread(buffer, sizeof(char), 3, fd) != 3) { fprintf(stderr, "Cannot get first 3 bytes of file\n"); exit(1); } /* reset pointer to beginning of file */ if (fseek(fd, (off_t)0, SEEK_SET) < 0) { perror("fseek"); exit(1); } size = buffer[2] * 512L; /* sizes are usually powers of two, warn if not */ for (i = MINROMSIZE; i < MAXROMSIZE && i < size; i *= 2) ; if (size > 0 && i > size) fprintf(stderr, "%ld is a strange size for a boot ROM\n", size); return (size); } int main(int argc, char **argv) { int i; FILE *fd; unsigned int sum; char *progname; int is3c503; extern int optind; extern char *optarg; progname = argv[0]; is3c503 = 0; while ((i = getopt(argc, argv, "3s:")) >= 0) { switch (i) { case 's': romsize = atol(optarg); if (romsize <= 0) romsize = 32768L; break; case '3': is3c503 = 1; break; } } argc -= optind; argv += optind; if (argc < 1) { fprintf(stderr, "Usage: %s [-s romsize] [-3] rom-file\n", progname); exit(1); } if ((fd = fopen(argv[0], "r+")) == NULL) { perror(argv[0]); exit(1); } /* If size not specified, infer it from 3rd byte */ if (romsize == 0) romsize = getromsize(fd); /* If that is 0, choose the right size */ if (romsize == 0) romsize = MAXROMSIZE; if ((rom = malloc(romsize)) == 0) { fprintf(stderr, "Cannot malloc memory for ROM buffer\n"); exit(1); } /* fill with FFs, slightly less work for PROM burner and allows limited patching */ memset(rom, 0xFF, romsize); if ((i = fread(rom, sizeof(char), romsize, fd)) < 0) { perror("fread"); exit(1); } if (i == romsize && fgetc(fd) != EOF) { fprintf(stderr, "ROM size of %d not big enough for data\n", romsize); exit(1); } /* shrink it down to the smallest size that will do */ for (romsize = MAXROMSIZE; romsize > MINROMSIZE && romsize >= 2*i; ) romsize /= 2; rom[2] = romsize / 512L; rom[5] = 0; #ifdef PHOENIX rom[rom[0x18]+0x10] = rom[2]; #endif /* 3c503 requires last two bytes to be MAGIC_3C503 */ if (is3c503 && romsize == MINROMSIZE) { rom[MINROMSIZE - 1] = rom[MINROMSIZE - 2] = MAGIC_3C503; } for (i=0, sum=0; i < romsize; i++) sum += rom[i]; rom[5] = -sum; /* double check */ for (i=0, sum=0; i < romsize; i++) sum += rom[i]; if (sum & 0xFF) printf("checksum fails.\n"); #ifdef PHOENIX for (i=rom[0x1a], sum=0; i< 32; i++ ) sum += rom[i]; rom[rom[0x1a] + 0x09] = -sum; #endif if (fseek(fd, (off_t)0, SEEK_SET) < 0) { perror("fseek"); exit(1); } if (fwrite(rom, sizeof(char), romsize, fd) != romsize) { perror(argv[0]); exit(1); } fclose(fd); exit(0); } /* * Local variables: * c-basic-offset: 8 * End: */ --------------------------------------------------------------------------- Alex Harin, PhD Universal Computer Services Tel +27 11 339-6111 PO Box 31266 Braamfontein 2017, South Africa Cell +27 82 900-4779 20th Floor, Total House, Smit St, Braamfontein Fax +27 11 339-3421 Johannesburg, South Africa alex@ucs.co.za ********** http://www.ucs.co.za ****************************
For requests or suggestions regarding this mailing list archive please write to netboot@gkminix.han.de.