|
|
1.1 ! root 1: /* l.out.c -- routines for manipulating l.out executable files. */ ! 2: ! 3: #include <l.out.h> ! 4: #include <canon.h> ! 5: #include <sys/types.h> ! 6: ! 7: #include "tboot.h" ! 8: ! 9: /* Convert l.out to load table. ! 10: * Used to generate loading instructions for use by tboot main(). ! 11: * Returns true on successful translation. ! 12: */ ! 13: ! 14: int ! 15: lout2load(ip, table, data_seg) ! 16: struct inode *ip; /* input: File to read. */ ! 17: struct load_segment table[]; /* output: How to read it. */ ! 18: uint16 *data_seg; /* output: Where to point es. */ ! 19: { ! 20: int i; /* Loop counter. */ ! 21: struct ldheader imageheader; /* l.out header for boot image. */ ! 22: ! 23: VERBOSE( puts("Reading the l.out header.\r\n"); ); ! 24: ! 25: /* Read the header. */ ! 26: iread(ip, &imageheader, ! 27: (fsize_t) 0, (uint16) sizeof(struct ldheader)); ! 28: ! 29: ! 30: /* Canonicalize the header. */ ! 31: canint(imageheader.l_magic); ! 32: canint(imageheader.l_flag); ! 33: canint(imageheader.l_machine); ! 34: canvaddr(imageheader.l_entry); ! 35: for(i = 0; i < NLSEG; ++i) { ! 36: cansize(imageheader.l_ssize[i]); ! 37: } ! 38: ! 39: /* Copy the l.out header info into table. */ ! 40: ! 41: #define L_TEXT table[0] ! 42: #define L_DATA table[1] ! 43: /* Calculate remaining entries. */ ! 44: if (imageheader.l_flag & LF_SEP) { /* if sep i/d executable */ ! 45: VERBOSE( puts("Generating table for sep i/d l.out.\r\n"); ); ! 46: L_TEXT.valid = (1==1); ! 47: L_TEXT.message = "\r\nLoading 286 COHERENT...\r\n"; ! 48: /* Load the shared and private code segments as one. */ ! 49: L_TEXT.load_toseg = sys_base; /* This is where we want the OS. */ ! 50: L_TEXT.load_tooffset = 0; ! 51: L_TEXT.load_offset = sizeof(struct ldheader); /* Skip the header. */ ! 52: L_TEXT.load_length = imageheader.l_ssize[L_SHRI] + /* Both segments as one. */ ! 53: imageheader.l_ssize[L_PRVI]; ! 54: ! 55: ! 56: L_DATA.valid = (1==1); ! 57: L_DATA.message = "\r\nLoading 286 COHERENT data...\r\n"; ! 58: /* Load both data segments. */ ! 59: ! 60: /* Round up to next 16 byte paragraph. */ ! 61: L_DATA.load_toseg = (sys_base + ! 62: (imageheader.l_ssize[L_SHRI] + /* Shared code */ ! 63: imageheader.l_ssize[L_PRVI] + /* Private code */ ! 64: 15) / 16); ! 65: L_DATA.load_tooffset = 0; ! 66: L_DATA.load_offset = (fsize_t) sizeof(struct ldheader) + /* l.out header */ ! 67: imageheader.l_ssize[L_SHRI] + /* Shared code */ ! 68: imageheader.l_ssize[L_PRVI]; /* Private code */ ! 69: L_DATA.load_length = imageheader.l_ssize[L_SHRD] + /* Both segments as one. */ ! 70: imageheader.l_ssize[L_PRVD]; ! 71: ! 72: table[2].valid = (1==2); /* Terminate the list. */ ! 73: ! 74: *data_seg = (uint16) (sys_base + ! 75: (imageheader.l_ssize[L_SHRI] + /* Shared code */ ! 76: imageheader.l_ssize[L_PRVI] + /* Private code */ ! 77: 15) / 16); /* Rounded up a paragraph. */ ! 78: ! 79: } else { /* if not sep i/d executable */ ! 80: #define SEGMENT table[0] ! 81: ! 82: VERBOSE( puts("Generating table for non-sep i/d l.out.\r\n"); ); ! 83: ! 84: SEGMENT.valid = (1==1); ! 85: SEGMENT.message = "\r\nLoading ancient COHERENT...\r\n"; ! 86: /* Load the shared and private code segments as one. */ ! 87: SEGMENT.load_toseg = sys_base; /* This is where we */ ! 88: SEGMENT.load_tooffset = 0; /* want the OS. */ ! 89: /* Skip the header. */ ! 90: SEGMENT.load_offset = (fsize_t) sizeof(struct ldheader); ! 91: /* Load all segments as one. */ ! 92: SEGMENT.load_length = imageheader.l_ssize[L_SHRI] + ! 93: imageheader.l_ssize[L_PRVI] + ! 94: imageheader.l_ssize[L_SHRD] + ! 95: imageheader.l_ssize[L_PRVD]; ! 96: ! 97: table[1].valid = (1==2); /* Terminate the list. */ ! 98: ! 99: /* Tiny model: ds = cs */ ! 100: *data_seg = sys_base; ! 101: } /* if not sep i/d executable */ ! 102: ! 103: return (1==1); ! 104: } ! 105: ! 106: ! 107: /* ! 108: * Wrapper for l_out_nlist() to make it look palitable. ! 109: */ ! 110: unsigned int ! 111: wrap_l_out_nlist(filename, symbol) ! 112: char *filename; ! 113: char *symbol; ! 114: { ! 115: struct nlist nlp[2]; /* For talking with l_out_nlist(). */ ! 116: ! 117: strcpy(nlp[0].n_name, symbol); ! 118: strcat(nlp[0].n_name, "_"); ! 119: nlp[1].n_name[0] = '\0'; ! 120: l_out_nlist(filename, nlp); ! 121: return( nlp[0].n_value ); ! 122: } ! 123: ! 124: /* ! 125: * Get entries from l.out name list. ! 126: */ ! 127: void ! 128: l_out_nlist(fn, nlp) ! 129: char *fn; ! 130: struct nlist *nlp; ! 131: { ! 132: register struct nlist *np; ! 133: register int ntodo = 0; ! 134: int lfp; ! 135: struct ldheader lh; ! 136: struct ldsym ste; ! 137: fsize_t symsize; ! 138: register int n; ! 139: ! 140: for (np = nlp; np->n_name[0] != '\0'; np++) { ! 141: np->n_type = np->n_value = 0; ! 142: ntodo++; ! 143: } ! 144: ! 145: if ((lfp = open(fn, 0)) == -1) ! 146: return; ! 147: ! 148: ! 149: n = read(lfp, &lh, sizeof lh); ! 150: ! 151: canint(lh.l_magic); ! 152: if (n!=sizeof(lh) || lh.l_magic!=L_MAGIC) { ! 153: puts("L.out bad MAGIC.\r\n"); ! 154: close(lfp); ! 155: return; ! 156: } ! 157: for (n=0; n<=L_SYM; n++) ! 158: cansize(lh.l_ssize[n]); ! 159: symsize = sizeof lh + lh.l_ssize[L_SHRI] + lh.l_ssize[L_SHRD] ! 160: + lh.l_ssize[L_PRVI] + lh.l_ssize[L_PRVD] + lh.l_ssize[L_DEBUG]; ! 161: lseek(lfp, symsize, 0); ! 162: symsize = lh.l_ssize[L_SYM]; ! 163: for ( ; symsize>0 && ntodo; symsize -= sizeof ste) { ! 164: if (read(lfp, &ste, sizeof ste) != sizeof(ste)) ! 165: break; ! 166: for (np = nlp; np->n_name[0] != '\0'; np++) ! 167: if (strncmp(np->n_name, ste.ls_id, NCPLN) == 0) { ! 168: canint(ste.ls_type); ! 169: canvaddr(ste.ls_addr); ! 170: np->n_type = ste.ls_type; ! 171: np->n_value = ste.ls_addr; ! 172: if (--ntodo == 0) ! 173: break; ! 174: } ! 175: } ! 176: close(lfp); ! 177: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.