Browse Source

Added doxygen comments and errno values.

tags/v0.9.3
Michael Brown 19 years ago
parent
commit
783e9ca396
1 changed files with 135 additions and 29 deletions
  1. 135
    29
      src/arch/i386/image/nbi.c

+ 135
- 29
src/arch/i386/image/nbi.c View File

4
 #include "gateA20.h"
4
 #include "gateA20.h"
5
 #include "osloader.h"
5
 #include "osloader.h"
6
 #include "etherboot.h"
6
 #include "etherboot.h"
7
+#include "errno.h"
7
 
8
 
8
-/* An NBI image header */
9
+/** @file
10
+ *
11
+ * NBI image format.
12
+ *
13
+ * The Net Boot Image format is defined by the "Draft Net Boot Image
14
+ * Proposal 0.3" by Jamie Honan, Gero Kuhlmann and Ken Yap.  It is now
15
+ * considered to be a legacy format, but it still included because a
16
+ * large amount of software (e.g. nymph, LTSP) makes use of NBI files.
17
+ *
18
+ * Etherboot does not implement the INT 78 callback interface
19
+ * described by the NBI specification.  For a callback interface on
20
+ * x86 architecture, use PXE.
21
+ *
22
+ */
23
+
24
+/**
25
+ * An NBI image header
26
+ *
27
+ * Note that the length field uses a peculiar encoding; use the
28
+ * NBI_LENGTH() macro to decode the actual header length.
29
+ *
30
+ */
9
 struct imgheader {
31
 struct imgheader {
10
-	unsigned long magic;
32
+	unsigned long magic;		/**< Magic number (NBI_MAGIC) */
11
 	union {
33
 	union {
12
-		unsigned char length;
13
-		unsigned long flags;
34
+		unsigned char length;	/**< Nibble-coded header length */
35
+		unsigned long flags;	/**< Image flags */
14
 	};
36
 	};
15
-	segoff_t location;
37
+	segoff_t location;		/**< 16-bit seg:off header location */
16
 	union {
38
 	union {
17
-		segoff_t segoff;
18
-		unsigned long linear;
39
+		segoff_t segoff;	/**< 16-bit seg:off entry point */
40
+		unsigned long linear;	/**< 32-bit entry point */
19
 	} execaddr;
41
 	} execaddr;
20
 } __attribute__ (( packed ));
42
 } __attribute__ (( packed ));
21
 
43
 
22
-/* NBI magic number */
44
+/** NBI magic number */
23
 #define NBI_MAGIC 0x1B031336UL
45
 #define NBI_MAGIC 0x1B031336UL
24
 
46
 
25
 /* Interpretation of the "length" fields */
47
 /* Interpretation of the "length" fields */
31
 #define	NBI_PROGRAM_RETURNS(flags)	( (flags) & ( 1 << 8 ) )
53
 #define	NBI_PROGRAM_RETURNS(flags)	( (flags) & ( 1 << 8 ) )
32
 #define	NBI_LINEAR_EXEC_ADDR(flags)	( (flags) & ( 1 << 31 ) )
54
 #define	NBI_LINEAR_EXEC_ADDR(flags)	( (flags) & ( 1 << 31 ) )
33
 
55
 
34
-/* NBI header length */
56
+/** NBI header length */
35
 #define NBI_HEADER_LENGTH	512
57
 #define NBI_HEADER_LENGTH	512
36
 
58
 
37
-/* An NBI segment header */
59
+/**
60
+ * An NBI segment header
61
+ *
62
+ * Note that the length field uses a peculiar encoding; use the
63
+ * NBI_LENGTH() macro to decode the actual header length.
64
+ *
65
+ */
38
 struct segheader {
66
 struct segheader {
39
-	unsigned char length;
40
-	unsigned char vendortag;
67
+	unsigned char length;		/**< Nibble-coded header length */
68
+	unsigned char vendortag;	/**< Vendor-defined private tag */
41
 	unsigned char reserved;
69
 	unsigned char reserved;
42
-	unsigned char flags;
43
-	unsigned long loadaddr;
44
-	unsigned long imglength;
45
-	unsigned long memlength;
70
+	unsigned char flags;		/**< Segment flags */
71
+	unsigned long loadaddr;		/**< Load address */
72
+	unsigned long imglength;	/**< Segment length in NBI file */
73
+	unsigned long memlength;	/**< Segment length in memory */
46
 };
74
 };
47
 
75
 
48
 /* Interpretation of the "flags" fields */
76
 /* Interpretation of the "flags" fields */
53
 #define NBI_LOADADDR_BEFORE		0x03
81
 #define NBI_LOADADDR_BEFORE		0x03
54
 #define NBI_LAST_SEGHEADER(flags)	( (flags) & ( 1 << 2 ) )
82
 #define NBI_LAST_SEGHEADER(flags)	( (flags) & ( 1 << 2 ) )
55
 
83
 
56
-/* Info passed to NBI image */
84
+/** Info passed to NBI image */
57
 static struct ebinfo loaderinfo = {
85
 static struct ebinfo loaderinfo = {
58
 	VERSION_MAJOR, VERSION_MINOR,
86
 	VERSION_MAJOR, VERSION_MINOR,
59
 	0
87
 	0
60
 };
88
 };
61
 
89
 
62
-/*
90
+/**
63
  * Determine whether or not this is a valid NBI image
91
  * Determine whether or not this is a valid NBI image
64
  *
92
  *
93
+ * @v start		Address of the image
94
+ * @v len		Length of the image
95
+ * @v context		NBI image context
96
+ * @ret	True		Image is a valid NBI image
97
+ * @ret	False		Image is not a valid NBI image
98
+ * @err	EBADIMG		Image is not a valid NBI image
99
+ * 
100
+ * "context" is filled in with a context pointer suitable for passing to
101
+ * nbi_load() and nbi_boot().
102
+ *
65
  */
103
  */
66
 static int nbi_probe ( physaddr_t start, off_t len, void **context ) {
104
 static int nbi_probe ( physaddr_t start, off_t len, void **context ) {
67
 	static struct imgheader imgheader;
105
 	static struct imgheader imgheader;
68
 
106
 
69
 	if ( (unsigned)len < sizeof ( imgheader ) ) {
107
 	if ( (unsigned)len < sizeof ( imgheader ) ) {
70
 		DBG ( "NBI image too small\n" );
108
 		DBG ( "NBI image too small\n" );
109
+		errno = EBADIMG;
71
 		return 0;
110
 		return 0;
72
 	}
111
 	}
73
 
112
 
74
 	copy_from_phys ( &imgheader, start, sizeof ( imgheader ) );
113
 	copy_from_phys ( &imgheader, start, sizeof ( imgheader ) );
75
 
114
 
76
-	if ( imgheader.magic != NBI_MAGIC )
115
+	if ( imgheader.magic != NBI_MAGIC ) {
116
+		errno = EBADIMG;
77
 		return 0;
117
 		return 0;
118
+	}
78
 
119
 
79
 	/* Record image context */
120
 	/* Record image context */
80
 	DBG ( "NBI found valid image\n" );
121
 	DBG ( "NBI found valid image\n" );
82
 	return 1;
123
 	return 1;
83
 }
124
 }
84
 
125
 
85
-/*
126
+/**
86
  * Prepare a segment for an NBI image
127
  * Prepare a segment for an NBI image
87
  *
128
  *
129
+ * @v dest		Address of segment
130
+ * @v imglen		Length of initialised-data portion of the segment
131
+ * @v memlen		Total length of the segment
132
+ * @v src		Source for initialised data
133
+ * @ret True		Segment can be used
134
+ * @ret False		Segment cannot be used
135
+ * @err other		As returned by prep_segment()
136
+ *
88
  */
137
  */
89
 static int nbi_prepare_segment ( physaddr_t dest, off_t imglen, off_t memlen,
138
 static int nbi_prepare_segment ( physaddr_t dest, off_t imglen, off_t memlen,
90
 				 physaddr_t src __unused ) {
139
 				 physaddr_t src __unused ) {
93
 	return prep_segment ( dest, dest + imglen, dest + memlen );
142
 	return prep_segment ( dest, dest + imglen, dest + memlen );
94
 }
143
 }
95
 
144
 
96
-/*
145
+/**
97
  * Load a segment for an NBI image
146
  * Load a segment for an NBI image
98
  *
147
  *
148
+ * @v dest		Address of segment
149
+ * @v imglen		Length of initialised-data portion of the segment
150
+ * @v memlen		Total length of the segment
151
+ * @v src		Source for initialised data
152
+ * @ret True		Always
153
+ *
99
  */
154
  */
100
 static int nbi_load_segment ( physaddr_t dest, off_t imglen,
155
 static int nbi_load_segment ( physaddr_t dest, off_t imglen,
101
 			      off_t memlen __unused, physaddr_t src ) {
156
 			      off_t memlen __unused, physaddr_t src ) {
104
 	return 1;
159
 	return 1;
105
 }
160
 }
106
 
161
 
107
-/*
162
+/**
108
  * Process segments of an NBI image
163
  * Process segments of an NBI image
109
  *
164
  *
165
+ * @v start		Address of the image
166
+ * @v len		Length of the image
167
+ * @v imgheader		Image header information
168
+ * @v process		Function to call for each segment
169
+ * @ret True		All segments were processed successfully
170
+ * @ret False		An error occurred processing a segment
171
+ * @err EBADIMG		Image is not a valid NBI image
172
+ * @err other		As returned by the "process" function
173
+ *
110
  */
174
  */
111
 static int nbi_process_segments ( physaddr_t start, off_t len,
175
 static int nbi_process_segments ( physaddr_t start, off_t len,
112
 				  struct imgheader *imgheader,
176
 				  struct imgheader *imgheader,
136
 		if ( sh.length == 0 ) {
200
 		if ( sh.length == 0 ) {
137
 			/* Avoid infinite loop? */
201
 			/* Avoid infinite loop? */
138
 			DBG ( "NBI invalid segheader length 0\n" );
202
 			DBG ( "NBI invalid segheader length 0\n" );
203
+			errno = EBADIMG;
139
 			return 0;
204
 			return 0;
140
 		}
205
 		}
141
 		
206
 		
159
 				- sh.loadaddr;
224
 				- sh.loadaddr;
160
 			break;
225
 			break;
161
 		default:
226
 		default:
162
-			DBG ( "NBI can't count up to three\n" );
163
-			return 0;
227
+			/* Cannot be reached */
228
+			DBG ( "NBI can't count up to three!\n" );
164
 		}
229
 		}
165
 
230
 
166
 		/* Process this segment */
231
 		/* Process this segment */
175
 		sh_off += NBI_LENGTH ( sh.length );
240
 		sh_off += NBI_LENGTH ( sh.length );
176
 		if ( sh_off >= NBI_HEADER_LENGTH ) {
241
 		if ( sh_off >= NBI_HEADER_LENGTH ) {
177
 			DBG ( "NBI header overflow\n" );
242
 			DBG ( "NBI header overflow\n" );
243
+			errno = EBADIMG;
178
 			return 0;
244
 			return 0;
179
 		}
245
 		}
180
 
246
 
183
 	if ( offset != len ) {
249
 	if ( offset != len ) {
184
 		DBG ( "NBI length mismatch (file %d, metadata %d)\n",
250
 		DBG ( "NBI length mismatch (file %d, metadata %d)\n",
185
 		      len, offset );
251
 		      len, offset );
252
+		errno = EBADIMG;
186
 		return 0;
253
 		return 0;
187
 	}
254
 	}
188
 
255
 
189
 	return 1;
256
 	return 1;
190
 }
257
 }
191
 
258
 
192
-/*
259
+/**
193
  * Load an NBI image into memory
260
  * Load an NBI image into memory
194
  *
261
  *
262
+ * @v start		Address of image
263
+ * @v len		Length of image
264
+ * @v context		NBI context (as returned by nbi_probe())
265
+ * @ret True		Image loaded into memory
266
+ * @ret False		Image not loaded into memory
267
+ * @err EBADIMG		Image is not a valid NBI image
268
+ * @err other		As returned by nbi_process_segments()
269
+ * @err other		As returned by nbi_prepare_segment()
270
+ * @err other		As returned by nbi_load_segment()
271
+ *
195
  */
272
  */
196
 static int nbi_load ( physaddr_t start, off_t len, void *context ) {
273
 static int nbi_load ( physaddr_t start, off_t len, void *context ) {
197
 	struct imgheader *imgheader = context;
274
 	struct imgheader *imgheader = context;
198
 
275
 
199
 	/* If we don't have enough data give up */
276
 	/* If we don't have enough data give up */
200
-	if ( len < NBI_HEADER_LENGTH )
277
+	if ( len < NBI_HEADER_LENGTH ) {
278
+		errno = EBADIMG;
201
 		return 0;
279
 		return 0;
280
+	}
202
 	
281
 	
203
 	DBG ( "NBI placing header at %hx:%hx\n",
282
 	DBG ( "NBI placing header at %hx:%hx\n",
204
 	      imgheader->location.segment, imgheader->location.offset );
283
 	      imgheader->location.segment, imgheader->location.offset );
220
 	return 1;
299
 	return 1;
221
 }
300
 }
222
 
301
 
223
-/*
302
+/**
224
  * Boot a 16-bit NBI image
303
  * Boot a 16-bit NBI image
225
  *
304
  *
305
+ * @v imgheader		Image header information
306
+ * @ret Never		NBI program booted successfully
307
+ * @ret False		NBI program returned
308
+ * @err EIMGRET		NBI program returned
309
+ *
226
  */
310
  */
227
 static int nbi_boot16 ( struct imgheader *imgheader ) {
311
 static int nbi_boot16 ( struct imgheader *imgheader ) {
228
 	uint16_t basemem_bootp;
312
 	uint16_t basemem_bootp;
256
 		    CLOBBER ( "eax", "ecx", "edx", "ebp" ) );
340
 		    CLOBBER ( "eax", "ecx", "edx", "ebp" ) );
257
 	BASEMEM_PARAMETER_DONE ( bootp_data );
341
 	BASEMEM_PARAMETER_DONE ( bootp_data );
258
 	
342
 	
343
+	errno = EIMGRET;
259
 	return 0;
344
 	return 0;
260
 }
345
 }
261
 
346
 
262
-/*
347
+/**
263
  * Boot a 32-bit NBI image
348
  * Boot a 32-bit NBI image
264
  *
349
  *
350
+ * @v imgheader		Image header information
351
+ * @ret False		NBI program should not have returned
352
+ * @ret other		As returned by NBI program
353
+ * @err EIMGRET		NBI program should not have returned
354
+ *
355
+ * To distinguish between the case of an NBI program returning false,
356
+ * and an NBI program that should not have returned, check errno.
357
+ * errno will be set to EIMGRET only if the NBI program should not
358
+ * have returned.
359
+ *
265
  */
360
  */
266
 static int nbi_boot32 ( struct imgheader *imgheader ) {
361
 static int nbi_boot32 ( struct imgheader *imgheader ) {
267
 	int rc = 0;
362
 	int rc = 0;
270
 	      imgheader->execaddr.linear );
365
 	      imgheader->execaddr.linear );
271
 
366
 
272
 	/* no gateA20_unset for PM call */
367
 	/* no gateA20_unset for PM call */
368
+	errno = ENOERR;
273
 	rc = xstart32 ( imgheader->execaddr.linear,
369
 	rc = xstart32 ( imgheader->execaddr.linear,
274
 			virt_to_phys ( &loaderinfo ),
370
 			virt_to_phys ( &loaderinfo ),
275
 			( ( imgheader->location.segment << 4 ) +
371
 			( ( imgheader->location.segment << 4 ) +
278
 	printf ( "Secondary program returned %d\n", rc );
374
 	printf ( "Secondary program returned %d\n", rc );
279
 	if ( ! NBI_PROGRAM_RETURNS ( imgheader->flags ) ) {
375
 	if ( ! NBI_PROGRAM_RETURNS ( imgheader->flags ) ) {
280
 		/* We shouldn't have returned */
376
 		/* We shouldn't have returned */
377
+		errno = EIMGRET;
281
 		rc = 0;
378
 		rc = 0;
282
 	}
379
 	}
283
 
380
 
284
 	return rc;
381
 	return rc;
285
 }
382
 }
286
 
383
 
287
-/*
384
+/**
288
  * Boot a loaded NBI image
385
  * Boot a loaded NBI image
289
  *
386
  *
387
+ * @v context		NBI context (as returned by nbi_probe())
388
+ * @ret Never		NBI program booted successfully
389
+ * @ret False		NBI program should not have returned
390
+ * @ret other		As returned by NBI program
391
+ * @err EIMGRET		NBI program should not have returned
392
+ *
393
+ * See also nbi_boot16() and nbi_boot32().
394
+ *
290
  */
395
  */
291
 static int nbi_boot ( void *context ) {
396
 static int nbi_boot ( void *context ) {
292
 	struct imgheader *imgheader = context;
397
 	struct imgheader *imgheader = context;
298
 	}
403
 	}
299
 }
404
 }
300
 
405
 
406
+/** Declaration of the NBI image format */
301
 static struct image nbi_image __image = {
407
 static struct image nbi_image __image = {
302
 	.name	= "NBI",
408
 	.name	= "NBI",
303
 	.probe	= nbi_probe,
409
 	.probe	= nbi_probe,

Loading…
Cancel
Save