Annotation of coherent/d/conf/tboot/execute.c, revision 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.