Selaa lähdekoodia

Separate out the documentation of the PXE API from the documentation of

the Etherboot implementation (i.e. don't do what Intel did).
tags/v0.9.3
Michael Brown 19 vuotta sitten
vanhempi
commit
572483cc59
2 muutettua tiedostoa jossa 92 lisäystä ja 58 poistoa
  1. 22
    0
      src/include/pxe_api.h
  2. 70
    58
      src/interface/pxe/pxe_udp.c

+ 22
- 0
src/include/pxe_api.h Näytä tiedosto

@@ -1631,4 +1631,26 @@ extern PXENV_EXIT_t undi_loader ( struct s_UNDI_LOADER *undi_loader );
1631 1631
 
1632 1632
 /** @} */ /* pxe */
1633 1633
 
1634
+/** @page pxe_notes Etherboot PXE implementation notes
1635
+
1636
+@section pxe_x86_modes x86 processor mode restrictions
1637
+
1638
+On the x86 platform, different PXE API calls have different
1639
+restrictions on the processor modes (real or protected) that can be
1640
+used.  See the individual API call descriptions for the restrictions
1641
+that apply to any particular call.
1642
+
1643
+@subsection pxe_x86_pmode16 Real mode, or protected-mode with 16-bit stack
1644
+
1645
+The PXE specification states that the API function can be called in
1646
+protected mode only if the s_PXE::StatusCallout field is set to a
1647
+non-zero value, and that the API function cannot be called with a
1648
+32-bit stack segment.
1649
+
1650
+Etherboot does not enforce either of these restrictions; they seem (as
1651
+with so much of the PXE specification) to be artifacts of the Intel
1652
+implementation.
1653
+
1654
+*/
1655
+
1634 1656
 #endif /* PXE_API_H */

+ 70
- 58
src/interface/pxe/pxe_udp.c Näytä tiedosto

@@ -43,23 +43,20 @@
43 43
  * pxenv_udp_read().  (If s_PXENV_UDP_OPEN::src_ip is 0.0.0.0, the
44 44
  * local station's IP address will remain unchanged.)
45 45
  *
46
- * You can have multiple UDP connections open simultaneously (and
47
- * even open concurrently with TFTP connections), provided that
46
+ * You can only have one open UDP connection at a time.  You cannot
47
+ * have a UDP connection open at the same time as a TFTP connection.
48
+ * (This is not strictly true for Etherboot; see the relevant @ref
49
+ * pxe_note_udp "implementation note" for more details.)
48 50
  *
49
- *   - they all have the same local IP address, and
51
+ * On x86, you must set the s_PXE::StatusCallout field to a nonzero
52
+ * value before calling this function in protected mode.  You cannot
53
+ * call this function with a 32-bit stack segment.  (See the relevant
54
+ * @ref pxe_x86_pmode16 "implementation note" for more details.)
50 55
  *
51
- *   - you take the multiple connections into account when calling
52
- *     pxenv_udp_read().
53
- *
54
- * On x86, you can call pxenv_udp_open() in real mode, 16-bit
55
- * protected mode with a 16-bit stack segment, 16-bit protected mode
56
- * with a 32-bit stack segment, or V86 mode.  The pxe::StatusCallout
57
- * field may be zero even in protected mode.
58
- * 
59
- * @note The PXE specification states that you have only one UDP
60
- * connection open at a time, and that you cannot have a UDP
61
- * connection open simultaneously with a TFTP connection.  Etherboot
62
- * does not enforce this unnecessary restriction.
56
+ * @note The PXE specification does not make it clear whether the IP
57
+ * address supplied in s_PXENV_UDP_OPEN::src_ip should be used only
58
+ * for this UDP connection, or retained for all future communication.
59
+ * The latter seems more consistent with typical PXE stack behaviour.
63 60
  *
64 61
  */
65 62
 PXENV_EXIT_t pxenv_udp_open ( struct s_PXENV_UDP_OPEN *udp_open ) {
@@ -85,21 +82,19 @@ PXENV_EXIT_t pxenv_udp_open ( struct s_PXENV_UDP_OPEN *udp_open ) {
85 82
  * @ret s_PXENV_UDP_CLOSE::Status	PXE status code
86 83
  * @err None				-
87 84
  *
88
- * Closes a UDP "connection" opened with pxenv_udp_open().  Since UDP
89
- * is a connectionless protocol, this is a no-op.
90
- *
91
- * You can call pxenv_udp_close() even if there is another active UDP
92
- * or TFTP connection, since it has no effect on anything.
85
+ * Closes a UDP "connection" opened with pxenv_udp_open().
93 86
  *
94
- * You can call pxenv_udp_close() in real mode, 16-bit protected mode
95
- * with a 16-bit stack segment, 16-bit protected mode with a 32-bit
96
- * stack segment, or V86 mode.  The pxe::StatusCallout field may be
97
- * zero even in protected mode.
87
+ * You can only have one open UDP connection at a time.  You cannot
88
+ * have a UDP connection open at the same time as a TFTP connection.
89
+ * You cannot use pxenv_udp_close() to close a TFTP connection; use
90
+ * pxenv_tftp_close() instead.  (This is not strictly true for
91
+ * Etherboot; see the relevant @ref pxe_note_udp "implementation note"
92
+ * for more details.)
98 93
  *
99
- * @note The PXE specification states that you have only one UDP
100
- * connection open at a time, and that you cannot have a UDP
101
- * connection open simultaneously with a TFTP connection.  Etherboot
102
- * does not enforce this unnecessary restriction.
94
+ * On x86, you must set the s_PXE::StatusCallout field to a nonzero
95
+ * value before calling this function in protected mode.  You cannot
96
+ * call this function with a 32-bit stack segment.  (See the relevant
97
+ * @ref pxe_x86_pmode16 "implementation note" for more details.)
103 98
  *
104 99
  */
105 100
 PXENV_EXIT_t pxenv_udp_close ( struct s_PXENV_UDP_CLOSE *udp_close __unused ) {
@@ -119,7 +114,7 @@ PXENV_EXIT_t pxenv_udp_close ( struct s_PXENV_UDP_CLOSE *udp_close __unused ) {
119 114
  * @v s_PXENV_UDP_WRITE::buffer_size	Length of the UDP payload
120 115
  * @v s_PXENV_UDP_WRITE::buffer		Address of the UDP payload
121 116
  * @ret #PXENV_EXIT_SUCCESS		Packet was transmitted successfully
122
- * @ret #PXENV_EXIT_FAILURE		Packet could not be transmitter
117
+ * @ret #PXENV_EXIT_FAILURE		Packet could not be transmitted
123 118
  * @ret s_PXENV_UDP_WRITE::Status	PXE status code
124 119
  * @err #PXENV_STATUS_UNDI_INVALID_STATE NIC could not be initialised
125 120
  * @err #PXENV_STATUS_OUT_OF_RESOURCES	Packet was too large to transmit
@@ -138,20 +133,15 @@ PXENV_EXIT_t pxenv_udp_close ( struct s_PXENV_UDP_CLOSE *udp_close __unused ) {
138 133
  *
139 134
  * If s_PXENV_UDP_WRITE::src_port is 0, port 2069 will be used.
140 135
  *
141
- * It is not necessary to call pxenv_udp_open() before using
142
- * pxenv_udp_write(), unless you want to change the local station's IP
143
- * address.  pxenv_udp_write() can be called even if there is another
144
- * active UDP or TFTP connection,.
145
- *
146
- * You can call pxenv_udp_write() in real mode, 16-bit protected mode
147
- * with a 16-bit stack segment, 16-bit protected mode with a 32-bit
148
- * stack segment, or V86 mode.  The pxe::StatusCallout field may be
149
- * zero even in protected mode.
136
+ * You must have opened a UDP connection with pxenv_udp_open() before
137
+ * calling pxenv_udp_write().  (This is not strictly true for
138
+ * Etherboot; see the relevant @ref pxe_note_udp "implementation note"
139
+ * for more details.)
150 140
  *
151
- * @note The PXE specification states that you have only one UDP
152
- * connection open at a time, and that you cannot have a UDP
153
- * connection open simultaneously with a TFTP connection.  Etherboot
154
- * does not enforce this unnecessary restriction.
141
+ * On x86, you must set the s_PXE::StatusCallout field to a nonzero
142
+ * value before calling this function in protected mode.  You cannot
143
+ * call this function with a 32-bit stack segment.  (See the relevant
144
+ * @ref pxe_x86_pmode16 "implementation note" for more details.)
155 145
  *
156 146
  * @bug s_PXENV_UDP_WRITE::gw is ignored; the default routing table is
157 147
  * always used.
@@ -278,26 +268,20 @@ static int await_pxe_udp ( int ival __unused, void *ptr,
278 268
  * s_PXENV_UDP_READ::Status==PXENV_STATUS_FAILURE.
279 269
  *
280 270
  * If s_PXENV_UDP_READ::dest_ip is 0.0.0.0, UDP packets addressed to
281
- * any IP address will be accepted and may be returned.
271
+ * any IP address will be accepted and may be returned to the caller.
282 272
  *
283 273
  * If s_PXENV_UDP_READ::d_port is 0, UDP packets addressed to any UDP
284
- * port will be accepted and may be returned.
274
+ * port will be accepted and may be returned to the caller.
285 275
  *
286
- * It is not necessary to call pxenv_udp_open() before using
287
- * pxenv_udp_read().  pxenv_udp_read() can be called even if there is
288
- * another active UDP or TFTP connection, but be aware that you might
289
- * then receive (or cause to be lost) a packet belonging to another
290
- * connection.
276
+ * You must have opened a UDP connection with pxenv_udp_open() before
277
+ * calling pxenv_udp_read().  (This is not strictly true for
278
+ * Etherboot; see the relevant @ref pxe_note_udp "implementation note"
279
+ * for more details.)
291 280
  *
292
- * You can call pxenv_udp_read() in real mode, 16-bit protected mode
293
- * with a 16-bit stack segment, 16-bit protected mode with a 32-bit
294
- * stack segment, or V86 mode.  The pxe::StatusCallout field may be
295
- * zero even in protected mode.
296
- *
297
- * @note The PXE specification states that you have only one UDP
298
- * connection open at a time, and that you cannot have a UDP
299
- * connection open simultaneously with a TFTP connection.  Etherboot
300
- * does not enforce this unnecessary restriction.
281
+ * On x86, you must set the s_PXE::StatusCallout field to a nonzero
282
+ * value before calling this function in protected mode.  You cannot
283
+ * call this function with a 32-bit stack segment.  (See the relevant
284
+ * @ref pxe_x86_pmode16 "implementation note" for more details.)
301 285
  *
302 286
  * @note The PXE specification (version 2.1) does not state that we
303 287
  * should fill in s_PXENV_UDP_READ::dest_ip and
@@ -319,3 +303,31 @@ PXENV_EXIT_t pxenv_udp_read ( struct s_PXENV_UDP_READ *udp_read ) {
319 303
 	udp_read->Status = PXENV_STATUS_SUCCESS;
320 304
 	return PXENV_EXIT_SUCCESS;
321 305
 }
306
+
307
+/** @page pxe_notes PXE implementation notes
308
+
309
+@section pxe_note_udp The connectionless nature of UDP
310
+
311
+The PXE specification states that it is possible to have only one open
312
+UDP or TFTP connection at any one time.  Etherboot does not
313
+rigourously enforce this restriction, on the UNIX principle that the
314
+code should not prevent the user from doing stupid things, because
315
+that would also prevent the user from doing clever things.  Since UDP
316
+is a connectionless protocol, it is perfectly possible to have
317
+multiple concurrent UDP "connections" open, provided that you take the
318
+multiplicity of connections into account when calling
319
+pxenv_udp_read().  Similarly, there is no technical reason that
320
+prevents you from calling pxenv_udp_write() in the middle of a TFTP
321
+download.
322
+
323
+Etherboot will therefore never return error codes indicating "a
324
+connection is already open", such as #PXENV_STATUS_UDP_OPEN.  If you
325
+want to have multiple concurrent connections, go for it (but don't
326
+expect your perfectly sensible code to work with any other PXE stack).
327
+
328
+Since Etherboot treats UDP as the connectionless protocol that it
329
+really is, pxenv_udp_close() is actually a no-op, and there is no need
330
+to call pxenv_udp_open() before using pxenv_udp_write() or
331
+pxenv_udp_read().
332
+
333
+*/

Loading…
Peruuta
Tallenna