Port-vax archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

RE: Booting from memory

On Friday, February 12, 2016 at 12:51 AM. John Klos wrote:
> Hello, VAX people,
> Last summer I wrote about issues I am having with my VAXstation 4000/90a:
> http://mail-index.netbsd.org/port-vax/2015/08/22/msg002580.html
> I had a little time recently so I wrote a quick script which takes the converted
> hex of the MOP bootable COUGAR.SYS utility for updating the FEPROM and
> outputs it on a "d/L+" line starting at memory address 1000000 with a tenth
> of a second delay between each line. So far, so good, but it's going to take
> around four or five hours to send 512 megabytes this way.
> However, before I run anything which may possibly make things worse, I'd
> like to test to see if this would work.
> What's the usual address to which MOP loads on a 4000/90? Should I use that
> as the load address?
> IIRC, I'd start 512 (0x200) bytes in to the MOP image, or 1000200, correct?
> A quick test trying to boot MOPBOOT.SYS from memory this way didn't work:
> >>> unjam
> >>> start 1000200
>    PC= 01000234 PSL= 041F0004
> Ideas?

Hi John,

First, I'll guess at what might be wrong with your system:
	The boot failure message you were originally seeing:

		?02 EXT HLT

Contains the key phrase "EXT HLT".  This suggests to me that the HALT button on the motherboard might be depressed.  I think that the system will run out of the ROM with the external halt signal present, but might behave as you are seeing if it is somehow stuck.  Something to look at.

Second, I'll answer your question

There are 2 things which are important to what you are doing:

1) The MOP bootable image contains a 512 byte image header record.  
This header record isn't part of the data which is loaded into memory, but has some potentially useful information which is used when starting what has been loaded.  I'm pretty sure that the only useful thing is the starting address (offset from the base load address).  Many bootable images are structured so that the starting address is the beginning of the loaded code, so this may not matter.  You can confirm that detail if you've got this file on a VMS machine (or you can make it available to me and I'll check for you).  The checking merely involves:
   $ ANALYZE/IMAGE bootfile.sys
The interesting information to confirm this are the transfer address value(s).  Zero values make this simple and are likely what you've got:

        ANALYZ V07-04

        This is an OpenVMS VAX image file


                Fixed Header Information

                        image format major id: 02, minor id: 05
                        header block count: 1
                        image type: executable (IHD$K_EXE)
                        I/O channel count: default
                        I/O page count: default
                        linker flags:
                                (0)  IHD$V_LNKDEBUG   0
                                (1)  IHD$V_LNKNOTFR   0
                                (2)  IHD$V_NOP0BUFS   0
                                (3)  IHD$V_PICIMG     0
                                (4)  IHD$V_P0IMAGE    0
                                (5)  IHD$V_DBGDMT     1
                                (6)  IHD$V_INISHR     0
                                (7)  IHD$V_IHSLONG    0
                                (8)  IHD$V_UPCALLS    0

                Image Activation Information

                        first transfer address:  %X'00000000'
                        second transfer address: %X'00000000'
                        third transfer address:  %X'00000000'

So what you put into memory is everything in the COUGAR.SYS file BUT the first 512 bytes as your initial comment suggested.

2) The actual load address shouldn't really matter, BUT, the loaded image is started with some useful state:
     A) SP points to the someplace which may or may not be used by the loaded program, but is usually somewhere before the loaded program
     B) AP points at the VMB provided argument list which may or may not be used by the loaded program

        #define long unsigned int
        #define word unsigned short
        #define byte unsigned char
        struct vmb_arguements
            long vmb$q_filecache[2];
            long vmb$l_lo_pfn;
            long vmb$l_hi_pfn;
            long vmb$q_pfnmap[2];
            long vmb$q_ucode[2];
            byte vmb$b_systemid[6];
            word vmb$w_fill;
            long vmb$l_flags;
        #define VMB$V_LOAD_SCS          0
            long vmb$l_ci_hipfn;
            long vmb$q_nodename[2];
        #define VMB$C_ARGBYTCNT sizeof(struct vmb_arguements)
        #undef long
        #undef word
        #undef byte

     C) R11 points to an RPB structure.  RPB being a Restart Parameter Block.

During a normal boot, the ROM based VMB code builds the RPB, loads the program and passes control to the loaded program passing the pointer to the RPB in R11 and the VMB arguments in AP.

A structure definition for a RPB is below:

Likely the most interesting/useful for the program being loaded is the available memory description which if all memory was good would be merely represented by rpb$l_pfncnt which would contain the number of pages of memory in the system.

#define long unsigned int
#define word unsigned short
#define byte unsigned char
struct restart_parameter_block
#define RPB$C_NMEMDSC   8
#define RPB$K_LENGTH    265
#define RPB$C_LENGTH    265
#define RPB$S_RPBDEF    265
    long *rpb$l_base;
    long *rpb$l_restart;
    long rpb$l_chksum;
    long rpb$l_rstrtflg;
    long rpb$l_haltpc;
    long rpb$l_haltpsl;
    long rpb$l_haltcode;
    long rpb$l_bootr0;
#define rpb$b_r0devtyp rpb$l_bootr0
/*    rpb$w_r0ubvec     = rpb$l_bootr0 + 1 */
    long rpb$l_bootr1;
#define RPB$S_NEXUS     4
#define RPB$V_NEXUS     0
#define RPB$S_ABUS      2
#define RPB$V_ABUS      4
    long rpb$l_bootr2;
    long rpb$l_bootr3;
    long rpb$l_bootr4;
    long rpb$l_bootr5;
#define RPB$V_CONV      0
#define RPB$V_DEBUG     1
#define RPB$V_INIBPT    2
#define RPB$V_BBLOCK    3
#define RPB$V_DIAG      4
#define RPB$V_BOOBPT    5
#define RPB$V_HEADER    6
#define RPB$V_NOTEST    7
#define RPB$V_SOLICT    8
#define RPB$V_HALT      9
#define RPB$V_NOPFND    10
#define RPB$V_MPM       11
#define RPB$M_MPM       0x800
#define RPB$V_USEMPM    12
#define RPB$M_USEMPM    0x1000
#define RPB$V_MEMTEST   13
#define RPB$M_MEMTEST   0x2000
#define RPB$V_FINDMEM   14
#define RPB$M_FINDMEM   0x4000
#define RPB$V_AUTOTEST  15
#define RPB$M_AUTOTEST  0x8000
#define RPB$V_CRDTEST   16
#define RPB$M_CRDTEST   0x10000
#define RPB$V_DIFSYSDEV 17
#define RPB$M_DIFSYSDEV 0x20000
#define RPB$S_TOPSYS    4
#define RPB$V_TOPSYS    28
#define RPB$M_TOPSYS    0xF0000000
    long *rpb$l_iovec;
    long rpb$l_iovecsz;
    long rpb$l_fillbn;
    long rpb$l_filsiz;
#define RPB$S_PFNMAP    8
    long rpb$q_pfnmap[RPB$S_PFNMAP/4];
    long rpb$l_pfncnt;
    long *rpb$l_svaspt;
    long *rpb$l_csrphy;
    long *rpb$l_csrvir;
    long *rpb$l_adpphy;
    long *rpb$l_adpvir;
    word rpb$w_unit;
    byte rpb$b_devtyp;
    byte rpb$b_slave;
#define RPB$S_FILE      40
    char rpb$t_file[RPB$S_FILE];
#define RPB$S_CONFREG   16
    byte rpb$b_confreg[RPB$S_CONFREG];
    byte rpb$b_hdrpgcnt;
    word rpb$w_bootndt;
#define rpb$b_bootndt rpb$w_bootndt
    byte rpb$b_flags;
    long *rpb$l_isp;
    long *rpb$l_pcbb;
    long *rpb$l_sbr;
    long *rpb$l_scbb;
    long *rpb$l_sisr;
    long *rpb$l_slr;
#define RPB$S_MEMDSC    64
    long rpb$l_memdsc[RPB$S_MEMDSC/4];
#define RPB$S_PAGCNT    24
#define RPB$V_PAGCNT    0
#define RPB$S_TR        8
#define RPB$V_TR        24
#define RPB$S_BASEPFN   32
#define RPB$V_BASEPFN   32
    long *rpb$l_bugchk;
#define RPB$S_WAIT      4
    byte rpb$b_wait[RPB$S_WAIT];
    long rpb$l_badpgs;
    byte rpb$b_ctrlltr;
#undef long
#undef word
#undef byte

Good Luck.

- Mark Pizzolato

Home | Main Index | Thread Index | Old Index