Annotation of coherent/d/conf/tboot/execute.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * execute.c -- Attempt to run a loadable file.
                      3:  * Returns only if it fails.
                      4:  * Takes the inode for the file to be loaded, and a command line vector
                      5:  * to pass in.
                      6:  */
                      7: #include <coff.h>
                      8: #include <canon.h>
                      9: #include <sys/typed.h>
                     10: #include <sys/inode.h>
                     11: #include <sys/dir.h>
                     12: 
                     13: #ifdef TEST
                     14: #define MAIN
                     15: #endif
                     16: #include "tboot.h"
                     17: #undef MAIN
                     18: 
                     19: void
                     20: execute( argv )
                     21:        char *argv[];
                     22: {
                     23:        extern uint16 myds;     /* My data segment, from Setup.s.  */
                     24:        char *cmd_name;         /* File to boot.  */
                     25:        char response[BLOCK];   /* Command typed at prompt.  */
                     26: 
                     27:        struct inode imageinode;  /* Inode structure for the boot image.  */
                     28:        ino_t imageinum;                /* inode number of the boot image.  */
                     29: 
                     30:        uint16 filemagic;               /* Magic number from file.  */
                     31:        struct load_segment imagetable[MAX_SEGS]; /* How to load a file.  */
                     32:        struct load_segment *cur_segment; /* Pointer for walking imagetable.  */ 
                     33: 
                     34:        uint16 data_seg;        /* Data segment register for image.  */
                     35: 
                     36:        uint16 boot_value;      /* Offset of boot_gift into
                     37:                                 * load image data segment.
                     38:                                 */
                     39: 
                     40:        uint16 cpu_type;        /* What kind of CPU are we running on?  */
                     41:        
                     42:        cpu_type = get_cpu_type();
                     43: 
                     44:        /*
                     45:         * Extract the command name from the command line.
                     46:         */
                     47:        cmd_name = argv[0];
                     48:        
                     49:        /*
                     50:         * Try to find the requested file.
                     51:         */
                     52:        if (0 == (imageinum = namei(cmd_name)) ) {
                     53:                puts("No such file: ");
                     54:                puts(cmd_name);
                     55:                puts("\r\n");
                     56:                return;
                     57:        }
                     58: 
                     59:        /*
                     60:         * Try to open that inode.
                     61:         */
                     62:        if (0 == iopen(&imageinode, imageinum)) {
                     63:                puts("Can't open ");
                     64:                puts(cmd_name);
                     65:                puts(".  Type \"dir\" for a list of files.\r\n");
                     66:                return;
                     67:        }
                     68: 
                     69:        /*
                     70:         * Read the magic number.
                     71:         */
                     72:        iread(&imageinode, &filemagic, (fsize_t) 0, (uint16) sizeof (uint16));
                     73:        canint(filemagic);      /* Harmless on 80386.  */
                     74: 
                     75:        /*
                     76:         * COFF executables probably should not be run on anything less
                     77:         * than a 386.
                     78:         */
                     79:        if (ISCOFF(filemagic)) {
                     80:                if (!IS_I386(cpu_type)) {
                     81:                        puts("This is not a 386 or 486--");
                     82:                        puts("you probably can not run this file.\r\n");
                     83:                        puts("Continue anyway?  ");
                     84:                        gets(response, BLOCK);
                     85:                        if ( 0 != strcmp(response, "y") &&
                     86:                             0 != strcmp(response, "Y") &&
                     87:                             0 != strcmp(response, "yes") &&
                     88:                             0 != strcmp(response, "YES") &&
                     89:                             0 != strcmp(response, "sure") ) {
                     90:                                return;
                     91:                        }
                     92:                }
                     93:        } /* Is it COFF?  */
                     94: 
                     95:        /*
                     96:         * If we haven't explicitly set sys_base, default it based
                     97:         * on the type of file we are loading.
                     98:         */
                     99:        if (!sys_base_set) {
                    100:                VERBOSE( {puts("Assuming default sys_base.\r\n");} );
                    101:                sys_base = object_sys_base(filemagic);
                    102:        }
                    103: 
                    104:        /*
                    105:         * Try to read the information we need to actually load this file.
                    106:         */
                    107:        if (! object2load(filemagic, &imageinode, imagetable, &data_seg)) {
                    108:                puts("File ");
                    109:                puts(cmd_name);
                    110:                puts(" is not an executable.\r\n");
                    111:                puts(".\r\n");
                    112:                return;
                    113:        }
                    114: 
                    115:        /* ASSERTION: imageinode and imagetable describe a valid executable.  */
                    116: 
                    117:        VERBOSE( {
                    118:                puts("OK!  Loading ");
                    119:                puts(cmd_name);
                    120:                puts("...\r\n");
                    121:        } );
                    122: 
                    123:        /* Now actually load everything into memory.  */
                    124:        for (cur_segment = &imagetable[0]; cur_segment->valid; ++cur_segment) {
                    125:                puts(cur_segment->message);
                    126: 
                    127:                /*
                    128:                 * Make sure that this segment will not overwrite tboot.
                    129:                 */
                    130:                if (seg_too_high(cur_segment)) {
                    131:                        puts("This segment would overwrite tboot.\r\n");
                    132:                        puts("Aborting...\r\n");
                    133:                        return;
                    134:                }
                    135:                ifread(&imageinode,
                    136:                        cur_segment->load_toseg,
                    137:                        cur_segment->load_tooffset,
                    138:                        cur_segment->load_offset,
                    139:                        cur_segment->load_length);
                    140:        }
                    141: 
                    142:        /* Does the program we just loaded want more info?  */
                    143: 
                    144:        /* Look up the variable "boot_gift" in the image.  */   
                    145:        puts("\r\nPlease wait...\r\n");
                    146:        boot_value = object_nlist(filemagic, cmd_name, "boot_gift");
                    147: 
                    148: 
                    149:        if (0 != boot_value) {
                    150:                VERBOSE( { puts("Preparing arguments.\r\n"); } );
                    151:                /* Yes, this program can accept more information.  */
                    152:                prepare_gift(data_seg, boot_value, argv);
                    153:        }
                    154: 
                    155:        VERBOSE( {
                    156:                puts("\r\nRunning ");
                    157:                puts(cmd_name);
                    158:                puts("...\r\n");
                    159:        } );
                    160: 
                    161:        if (want_monitor) {
                    162:                puts("The kernel is ready to run.\r\n");
                    163:                puts("SYS_START: ");
                    164:                print16(SYS_START);
                    165:                puts(" sys_base: ");
                    166:                print16(sys_base);
                    167:                puts(" data_seg: ");
                    168:                print16(data_seg);
                    169:                puts("\r\n");
                    170:                monitor();
                    171:        }
                    172: 
                    173:        /* Run the image (the kernel).  */
                    174:        gotoker(SYS_START, sys_base, data_seg);
                    175: } /* execute() */
                    176: 
                    177: 
                    178: /*
                    179:  * int
                    180:  * seg_too_high( struct load_segment *lseg )
                    181:  * Check to see if a segment will overlap tboot.
                    182:  * Returns TRUE if it would, FALSE otherwise.
                    183:  */
                    184: int
                    185: seg_too_high( lseg )
                    186:        struct load_segment *lseg;
                    187: {
                    188:        uint32 load_top;
                    189: 
                    190:        load_top =      (lseg->load_toseg << 4) +
                    191:                        lseg->load_tooffset +
                    192:                        lseg->load_length;
                    193:        
                    194: #if 0
                    195:        printf("%x:%x + %lx = %lx\n",
                    196:                lseg->load_toseg,
                    197:                lseg->load_tooffset,
                    198:                lseg->load_length, 
                    199:                load_top);
                    200: #endif /* 0 */ 
                    201: 
                    202:        return ( load_top >= ( ((uint32) RBOOTS) << 4 ) );
                    203: } /* seg_too_high() */
                    204: 
                    205: #ifdef TEST
                    206: int boot_gift; /* Lie.  */
                    207: main()
                    208: {
                    209:        struct load_segment lseg;
                    210: 
                    211:        lseg.load_toseg = 0x200;
                    212:        lseg.load_tooffset      = 0;
                    213:        lseg.load_length        = 128L*1024L;
                    214: 
                    215:        if (seg_too_high(&lseg)) {
                    216:                printf("BAD: %x:%x + %lx > %lx.\n", 
                    217:                        lseg.load_toseg,
                    218:                        lseg.load_tooffset,
                    219:                        lseg.load_length,
                    220:                        (((unsigned long)RBOOTS) << 4) );
                    221: 
                    222:        } else {
                    223:                printf("OK: %x:%x + %lx < %lx.\n", 
                    224:                        lseg.load_toseg,
                    225:                        lseg.load_tooffset,
                    226:                        lseg.load_length,
                    227:                        (((unsigned long)RBOOTS) << 4) );
                    228: 
                    229:        }
                    230: } /* main() */
                    231: #endif /* TEST */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.