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,22 +4,44 @@
4 4
 #include "gateA20.h"
5 5
 #include "osloader.h"
6 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 31
 struct imgheader {
10
-	unsigned long magic;
32
+	unsigned long magic;		/**< Magic number (NBI_MAGIC) */
11 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 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 41
 	} execaddr;
20 42
 } __attribute__ (( packed ));
21 43
 
22
-/* NBI magic number */
44
+/** NBI magic number */
23 45
 #define NBI_MAGIC 0x1B031336UL
24 46
 
25 47
 /* Interpretation of the "length" fields */
@@ -31,18 +53,24 @@ struct imgheader {
31 53
 #define	NBI_PROGRAM_RETURNS(flags)	( (flags) & ( 1 << 8 ) )
32 54
 #define	NBI_LINEAR_EXEC_ADDR(flags)	( (flags) & ( 1 << 31 ) )
33 55
 
34
-/* NBI header length */
56
+/** NBI header length */
35 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 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 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 76
 /* Interpretation of the "flags" fields */
@@ -53,28 +81,41 @@ struct segheader {
53 81
 #define NBI_LOADADDR_BEFORE		0x03
54 82
 #define NBI_LAST_SEGHEADER(flags)	( (flags) & ( 1 << 2 ) )
55 83
 
56
-/* Info passed to NBI image */
84
+/** Info passed to NBI image */
57 85
 static struct ebinfo loaderinfo = {
58 86
 	VERSION_MAJOR, VERSION_MINOR,
59 87
 	0
60 88
 };
61 89
 
62
-/*
90
+/**
63 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 104
 static int nbi_probe ( physaddr_t start, off_t len, void **context ) {
67 105
 	static struct imgheader imgheader;
68 106
 
69 107
 	if ( (unsigned)len < sizeof ( imgheader ) ) {
70 108
 		DBG ( "NBI image too small\n" );
109
+		errno = EBADIMG;
71 110
 		return 0;
72 111
 	}
73 112
 
74 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 117
 		return 0;
118
+	}
78 119
 
79 120
 	/* Record image context */
80 121
 	DBG ( "NBI found valid image\n" );
@@ -82,9 +123,17 @@ static int nbi_probe ( physaddr_t start, off_t len, void **context ) {
82 123
 	return 1;
83 124
 }
84 125
 
85
-/*
126
+/**
86 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 138
 static int nbi_prepare_segment ( physaddr_t dest, off_t imglen, off_t memlen,
90 139
 				 physaddr_t src __unused ) {
@@ -93,9 +142,15 @@ static int nbi_prepare_segment ( physaddr_t dest, off_t imglen, off_t memlen,
93 142
 	return prep_segment ( dest, dest + imglen, dest + memlen );
94 143
 }
95 144
 
96
-/*
145
+/**
97 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 155
 static int nbi_load_segment ( physaddr_t dest, off_t imglen,
101 156
 			      off_t memlen __unused, physaddr_t src ) {
@@ -104,9 +159,18 @@ static int nbi_load_segment ( physaddr_t dest, off_t imglen,
104 159
 	return 1;
105 160
 }
106 161
 
107
-/*
162
+/**
108 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 175
 static int nbi_process_segments ( physaddr_t start, off_t len,
112 176
 				  struct imgheader *imgheader,
@@ -136,6 +200,7 @@ static int nbi_process_segments ( physaddr_t start, off_t len,
136 200
 		if ( sh.length == 0 ) {
137 201
 			/* Avoid infinite loop? */
138 202
 			DBG ( "NBI invalid segheader length 0\n" );
203
+			errno = EBADIMG;
139 204
 			return 0;
140 205
 		}
141 206
 		
@@ -159,8 +224,8 @@ static int nbi_process_segments ( physaddr_t start, off_t len,
159 224
 				- sh.loadaddr;
160 225
 			break;
161 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 231
 		/* Process this segment */
@@ -175,6 +240,7 @@ static int nbi_process_segments ( physaddr_t start, off_t len,
175 240
 		sh_off += NBI_LENGTH ( sh.length );
176 241
 		if ( sh_off >= NBI_HEADER_LENGTH ) {
177 242
 			DBG ( "NBI header overflow\n" );
243
+			errno = EBADIMG;
178 244
 			return 0;
179 245
 		}
180 246
 
@@ -183,22 +249,35 @@ static int nbi_process_segments ( physaddr_t start, off_t len,
183 249
 	if ( offset != len ) {
184 250
 		DBG ( "NBI length mismatch (file %d, metadata %d)\n",
185 251
 		      len, offset );
252
+		errno = EBADIMG;
186 253
 		return 0;
187 254
 	}
188 255
 
189 256
 	return 1;
190 257
 }
191 258
 
192
-/*
259
+/**
193 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 273
 static int nbi_load ( physaddr_t start, off_t len, void *context ) {
197 274
 	struct imgheader *imgheader = context;
198 275
 
199 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 279
 		return 0;
280
+	}
202 281
 	
203 282
 	DBG ( "NBI placing header at %hx:%hx\n",
204 283
 	      imgheader->location.segment, imgheader->location.offset );
@@ -220,9 +299,14 @@ static int nbi_load ( physaddr_t start, off_t len, void *context ) {
220 299
 	return 1;
221 300
 }
222 301
 
223
-/*
302
+/**
224 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 311
 static int nbi_boot16 ( struct imgheader *imgheader ) {
228 312
 	uint16_t basemem_bootp;
@@ -256,12 +340,23 @@ static int nbi_boot16 ( struct imgheader *imgheader ) {
256 340
 		    CLOBBER ( "eax", "ecx", "edx", "ebp" ) );
257 341
 	BASEMEM_PARAMETER_DONE ( bootp_data );
258 342
 	
343
+	errno = EIMGRET;
259 344
 	return 0;
260 345
 }
261 346
 
262
-/*
347
+/**
263 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 361
 static int nbi_boot32 ( struct imgheader *imgheader ) {
267 362
 	int rc = 0;
@@ -270,6 +365,7 @@ static int nbi_boot32 ( struct imgheader *imgheader ) {
270 365
 	      imgheader->execaddr.linear );
271 366
 
272 367
 	/* no gateA20_unset for PM call */
368
+	errno = ENOERR;
273 369
 	rc = xstart32 ( imgheader->execaddr.linear,
274 370
 			virt_to_phys ( &loaderinfo ),
275 371
 			( ( imgheader->location.segment << 4 ) +
@@ -278,15 +374,24 @@ static int nbi_boot32 ( struct imgheader *imgheader ) {
278 374
 	printf ( "Secondary program returned %d\n", rc );
279 375
 	if ( ! NBI_PROGRAM_RETURNS ( imgheader->flags ) ) {
280 376
 		/* We shouldn't have returned */
377
+		errno = EIMGRET;
281 378
 		rc = 0;
282 379
 	}
283 380
 
284 381
 	return rc;
285 382
 }
286 383
 
287
-/*
384
+/**
288 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 396
 static int nbi_boot ( void *context ) {
292 397
 	struct imgheader *imgheader = context;
@@ -298,6 +403,7 @@ static int nbi_boot ( void *context ) {
298 403
 	}
299 404
 }
300 405
 
406
+/** Declaration of the NBI image format */
301 407
 static struct image nbi_image __image = {
302 408
 	.name	= "NBI",
303 409
 	.probe	= nbi_probe,

Loading…
Cancel
Save