Browse Source

[autoboot] Allow autoboot device to be identified by link-layer address

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
00c745e5ff
3 changed files with 65 additions and 15 deletions
  1. 2
    4
      src/arch/i386/core/pci_autoboot.c
  2. 4
    2
      src/include/usr/autoboot.h
  3. 59
    9
      src/usr/autoboot.c

+ 2
- 4
src/arch/i386/core/pci_autoboot.c View File

@@ -34,10 +34,8 @@ uint16_t __bss16 ( autoboot_busdevfn );
34 34
  */
35 35
 static void pci_autoboot_init ( void ) {
36 36
 
37
-	if ( autoboot_busdevfn ) {
38
-		autoboot_device.bus_type = BUS_TYPE_PCI;
39
-		autoboot_device.location = autoboot_busdevfn;
40
-	}
37
+	if ( autoboot_busdevfn )
38
+		set_autoboot_busloc ( BUS_TYPE_PCI, autoboot_busdevfn );
41 39
 }
42 40
 
43 41
 /** PCI autoboot device initialisation function */

+ 4
- 2
src/include/usr/autoboot.h View File

@@ -9,8 +9,8 @@
9 9
 
10 10
 FILE_LICENCE ( GPL2_OR_LATER );
11 11
 
12
-#include <ipxe/in.h>
13 12
 #include <ipxe/device.h>
13
+
14 14
 struct net_device;
15 15
 struct uri;
16 16
 struct settings;
@@ -26,7 +26,9 @@ enum uriboot_flags {
26 26
 			 URIBOOT_NO_SAN_BOOT |	   \
27 27
 			 URIBOOT_NO_SAN_UNHOOK )
28 28
 
29
-extern struct device_description autoboot_device;
29
+extern void set_autoboot_busloc ( unsigned int bus_type,
30
+				  unsigned int location );
31
+extern void set_autoboot_ll_addr ( const void *ll_addr, size_t len );
30 32
 
31 33
 extern int uriboot ( struct uri *filename, struct uri *root_path, int drive,
32 34
 		     unsigned int flags );

+ 59
- 9
src/usr/autoboot.c View File

@@ -49,8 +49,14 @@ FILE_LICENCE ( GPL2_OR_LATER );
49 49
  *
50 50
  */
51 51
 
52
-/** Device location of preferred autoboot device */
53
-struct device_description autoboot_device;
52
+/** Link-layer address of preferred autoboot device, if known */
53
+static uint8_t autoboot_ll_addr[MAX_LL_ADDR_LEN];
54
+
55
+/** Device location of preferred autoboot device, if known */
56
+static struct device_description autoboot_desc;
57
+
58
+/** Autoboot device tester */
59
+static int ( * is_autoboot_device ) ( struct net_device *netdev );
54 60
 
55 61
 /* Disambiguate the various error causes */
56 62
 #define ENOENT_BOOT __einfo_error ( EINFO_ENOENT_BOOT )
@@ -422,15 +428,60 @@ int netboot ( struct net_device *netdev ) {
422 428
 }
423 429
 
424 430
 /**
425
- * Test if network device matches the autoboot device location
431
+ * Test if network device matches the autoboot device bus type and location
426 432
  *
427 433
  * @v netdev		Network device
428
- * @ret is_autoboot	Network device matches the autoboot device location
434
+ * @ret is_autoboot	Network device matches the autoboot device
435
+ */
436
+static int is_autoboot_busloc ( struct net_device *netdev ) {
437
+
438
+	return ( ( netdev->dev->desc.bus_type == autoboot_desc.bus_type ) &&
439
+		 ( netdev->dev->desc.location == autoboot_desc.location ) );
440
+}
441
+
442
+/**
443
+ * Identify autoboot device by bus type and location
444
+ *
445
+ * @v bus_type		Bus type
446
+ * @v location		Location
429 447
  */
430
-static int is_autoboot_device ( struct net_device *netdev ) {
448
+void set_autoboot_busloc ( unsigned int bus_type, unsigned int location ) {
449
+
450
+	/* Record autoboot device description */
451
+	autoboot_desc.bus_type = bus_type;
452
+	autoboot_desc.location = location;
453
+
454
+	/* Mark autoboot device as present */
455
+	is_autoboot_device = is_autoboot_busloc;
456
+}
457
+
458
+/**
459
+ * Test if network device matches the autoboot device link-layer address
460
+ *
461
+ * @v netdev		Network device
462
+ * @ret is_autoboot	Network device matches the autoboot device
463
+ */
464
+static int is_autoboot_ll_addr ( struct net_device *netdev ) {
465
+
466
+	return ( memcmp ( netdev->ll_addr, autoboot_ll_addr,
467
+			  netdev->ll_protocol->ll_addr_len ) == 0 );
468
+}
469
+
470
+/**
471
+ * Identify autoboot device by link-layer address
472
+ *
473
+ * @v ll_addr		Link-layer address
474
+ * @v len		Length of link-layer address
475
+ */
476
+void set_autoboot_ll_addr ( const void *ll_addr, size_t len ) {
477
+
478
+	/* Record autoboot link-layer address (truncated if necessary) */
479
+	if ( len > sizeof ( autoboot_ll_addr ) )
480
+		len = sizeof ( autoboot_ll_addr );
481
+	memcpy ( autoboot_ll_addr, ll_addr, len );
431 482
 
432
-	return ( ( netdev->dev->desc.bus_type == autoboot_device.bus_type ) &&
433
-		 ( netdev->dev->desc.location == autoboot_device.location ) );
483
+	/* Mark autoboot device as present */
484
+	is_autoboot_device = is_autoboot_ll_addr;
434 485
 }
435 486
 
436 487
 /**
@@ -447,8 +498,7 @@ static int autoboot ( void ) {
447 498
 	for_each_netdev ( netdev ) {
448 499
 
449 500
 		/* Skip any non-matching devices, if applicable */
450
-		if ( autoboot_device.bus_type &&
451
-		     ( ! is_autoboot_device ( netdev ) ) )
501
+		if ( is_autoboot_device && ( ! is_autoboot_device ( netdev ) ) )
452 502
 			continue;
453 503
 
454 504
 		/* Attempt booting from this device */

Loading…
Cancel
Save