|
|
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: #ifdef VERBOSE
24: puts("Reading the l.out header.\r\n");
25: #endif /* VERBOSE */
26:
27: /* Read the header. */
28: iread(ip, &imageheader,
29: (fsize_t) 0, (uint16) sizeof(struct ldheader));
30:
31:
32: /* Canonicalize the header. */
33: canint(imageheader.l_magic);
34: canint(imageheader.l_flag);
35: canint(imageheader.l_machine);
36: canvaddr(imageheader.l_entry);
37: for(i = 0; i < NLSEG; ++i) {
38: cansize(imageheader.l_ssize[i]);
39: }
40:
41: /* Copy the l.out header info into table. */
42:
43: #define L_TEXT table[0]
44: #define L_DATA table[1]
45: /* Calculate remaining entries. */
46: if (imageheader.l_flag & LF_SEP) { /* if sep i/d executable */
47: #ifdef VERBOSE
48: puts("Generating table for sep i/d l.out.\r\n");
49: #endif /* VERBOSE */
50: L_TEXT.valid = (1==1);
51: L_TEXT.message = "\r\nLoading l.out code segments...\r\n";
52: /* Load the shared and private code segments as one. */
53: L_TEXT.load_toseg = sys_base; /* This is where we want the OS. */
54: L_TEXT.load_tooffset = 0;
55: L_TEXT.load_offset = sizeof(struct ldheader); /* Skip the header. */
56: L_TEXT.load_length = imageheader.l_ssize[L_SHRI] + /* Both segments as one. */
57: imageheader.l_ssize[L_PRVI];
58:
59:
60: L_DATA.valid = (1==1);
61: L_DATA.message = "\r\nLoading l.out data segments...\r\n";
62: /* Load both data segments. */
63:
64: /* Round up to next 16 byte paragraph. */
65: L_DATA.load_toseg = (sys_base +
66: (imageheader.l_ssize[L_SHRI] + /* Shared code */
67: imageheader.l_ssize[L_PRVI] + /* Private code */
68: 15) / 16);
69: L_DATA.load_tooffset = 0;
70: L_DATA.load_offset = (fsize_t) sizeof(struct ldheader) + /* l.out header */
71: imageheader.l_ssize[L_SHRI] + /* Shared code */
72: imageheader.l_ssize[L_PRVI]; /* Private code */
73: L_DATA.load_length = imageheader.l_ssize[L_SHRD] + /* Both segments as one. */
74: imageheader.l_ssize[L_PRVD];
75:
76: table[2].valid = (1==2); /* Terminate the list. */
77:
78: *data_seg = (uint16) (sys_base +
79: (imageheader.l_ssize[L_SHRI] + /* Shared code */
80: imageheader.l_ssize[L_PRVI] + /* Private code */
81: 15) / 16); /* Rounded up a paragraph. */
82:
83: } else { /* if not sep i/d executable */
84: #define SEGMENT table[0]
85:
86: #ifdef VERBOSE
87: puts("Generating table for non-sep i/d l.out.\r\n");
88: #endif /* VERBOSE */
89:
90: SEGMENT.valid = (1==1);
91: SEGMENT.message = "\r\nLoading all l.out segments...\r\n";
92: /* Load the shared and private code segments as one. */
93: SEGMENT.load_toseg = sys_base; /* This is where we */
94: SEGMENT.load_tooffset = 0; /* want the OS. */
95: /* Skip the header. */
96: SEGMENT.load_offset = (fsize_t) sizeof(struct ldheader);
97: /* Load all segments as one. */
98: SEGMENT.load_length = imageheader.l_ssize[L_SHRI] +
99: imageheader.l_ssize[L_PRVI] +
100: imageheader.l_ssize[L_SHRD] +
101: imageheader.l_ssize[L_PRVD];
102:
103: table[1].valid = (1==2); /* Terminate the list. */
104:
105: /* Tiny model: ds = cs */
106: *data_seg = sys_base;
107: } /* if not sep i/d executable */
108:
109: return (1==1);
110: }
111:
112:
113: /*
114: * Get entries from l.out name list.
115: */
116:
117: void
118: l_out_nlist(fn, nlp)
119: char *fn;
120: struct nlist *nlp;
121: {
122: register struct nlist *np;
123: register int ntodo = 0;
124: int lfp;
125: struct ldheader lh;
126: struct ldsym ste;
127: fsize_t symsize;
128: register int n;
129:
130: for (np = nlp; np->n_name[0] != '\0'; np++) {
131: np->n_type = np->n_value = 0;
132: ntodo++;
133: }
134:
135: if ((lfp = open(fn, 0)) == -1)
136: return;
137:
138:
139: n = read(lfp, &lh, sizeof lh);
140:
141: canint(lh.l_magic);
142: if (n!=sizeof(lh) || lh.l_magic!=L_MAGIC) {
143: puts("L.out bad MAGIC.\r\n");
144: close(lfp);
145: return;
146: }
147: for (n=0; n<=L_SYM; n++)
148: cansize(lh.l_ssize[n]);
149: symsize = sizeof lh + lh.l_ssize[L_SHRI] + lh.l_ssize[L_SHRD]
150: + lh.l_ssize[L_PRVI] + lh.l_ssize[L_PRVD] + lh.l_ssize[L_DEBUG];
151: lseek(lfp, symsize, 0);
152: symsize = lh.l_ssize[L_SYM];
153: for ( ; symsize>0 && ntodo; symsize -= sizeof ste) {
154: if (read(lfp, &ste, sizeof ste) != sizeof(ste))
155: break;
156: for (np = nlp; np->n_name[0] != '\0'; np++)
157: if (strncmp(np->n_name, ste.ls_id, NCPLN) == 0) {
158: canint(ste.ls_type);
159: canvaddr(ste.ls_addr);
160: np->n_type = ste.ls_type;
161: np->n_value = ste.ls_addr;
162: if (--ntodo == 0)
163: break;
164: }
165: }
166: close(lfp);
167: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.