iBFT features.
Konrad Rzeszutek Wilk
maintainerThe iBFT firmware driver has seen some action this last month. Here is a short primer on what it is:
The iBFT is an equivalant to the Boot Flag, except that its geared towards iSCSI and hence requires much more information (such as the IP of target, passwords, which device to login, etc). iBFT is a data structure populated by the BIOS or the NIC to contain this so that the OS can read it and login to the iSCSI and present the boot device to the initrd for mounting / FS.
There has been two big features added in:
1) Updated to support the 1.03 of the spec:
ftp://ftp.software.ibm.com/systems/support/bladecenter/iscsi_boot_firmware_table_v1.03.pdf
2) Split in two modules: one presentation that exports SysFS entries and the other that actually contains the iBFT data. The presentation driver paves the road for iSCSI hardware drivers (QLogic iSCSI HBA for example) to present the boot information they contain via this SysFS interface as they don't put the data in iBFT format.
Please pull the 'for-linus' branch ofgit://git.kernel.org/pub/scm/linux/kernel/git/konrad/ibft-2.6.git for-linus
Thank you!
Konrad Rzeszutek Wilk (1):
ibft: For UEFI machines actually do scan ACPI for iBFT.
Mike Christie (2):
ibft: separate ibft parsing from sysfs interface
ibft: convert iscsi_ibft module to iscsi boot lib
Peter Jones (1):
ibft: Update iBFT handling for v1.03 of the spec.
drivers/firmware/Kconfig | 9 + drivers/firmware/Makefile | 1 + drivers/firmware/iscsi_boot_sysfs.c | 481 +++++++++++++++++++++++ drivers/firmware/iscsi_ibft.c | 726 +++++++++++++---------------------- drivers/firmware/iscsi_ibft_find.c | 55 ++- include/linux/iscsi_boot_sysfs.h | 123 ++++++ include/linux/iscsi_ibft.h | 12 +- 7 files changed, 923 insertions(+), 484 deletions(-)
Konrad Rzeszutek Wilk
maintainerPATCH 1/4 ibft: Update iBFT handling for v1.03 of the spec.
From: Peter Jones <[email protected]>
- Use struct acpi_table_ibft instead of struct ibft_table_header
- Don't do reserve_ibft_region() on UEFI machines (section 1.4.3.1)
- If ibft_addr isn't initialized when ibft_init() is called, check for ACPI-based tables.
Author: Peter Jones <[email protected]>
--- drivers/firmware/iscsi_ibft.c | 30 ++++++++++++++++++------------ drivers/firmware/iscsi_ibft_find.c | 34 +++++++++++++++++++++++++++++----- include/linux/iscsi_ibft.h | 12 ++---------- 3 files changed, 49 insertions(+), 27 deletions(-)
drivers/firmware/iscsi_ibft.c +18 -12
@@ -1,5 +1,5 @@/* -* Copyright 2007 Red Hat, Inc. +* Copyright 2007-2010 Red Hat, Inc. * by Peter Jones <[email protected]> * Copyright 2008 IBM, Inc. * by Konrad Rzeszutek <[email protected]>
@@ -19,6 +19,9 @@* * Changelog: * +* 06 Jan 2010 - Peter Jones <[email protected]> +* New changelog entries are in the git log from now on. Not here. +* * 14 Mar 2008 - Konrad Rzeszutek <[email protected]> * Updated comments and copyrights. (v0.4.9) *
@@ -78,9 +81,10 @@#include <linux/stat.h> #include <linux/string.h> #include <linux/types.h> +#include <linux/acpi.h> -#define IBFT_ISCSI_VERSION "0.4.9" -#define IBFT_ISCSI_DATE "2008-Mar-14" +#define IBFT_ISCSI_VERSION "0.5.0" +#define IBFT_ISCSI_DATE "2010-Feb-25"MODULE_AUTHOR ("Peter Jones <[email protected]> and \ Konrad Rzeszutek <[email protected]>" );
@@ -238,7 +242,7 @@ static const char *ibft_initiator_properties[] =*/ struct ibft_kobject { -struct ibft_table_header *header; +struct acpi_table_ibft *header;union {struct ibft_initiator *initiator;struct ibft_nic *nic;
@@ -536,12 +540,13 @@ static int __init ibft_check_device(void)u8 *pos;u8 csum =0 ; - len = ibft_addr->length; + len = ibft_addr->header.length;/* Sanity checking of iBFT. */ -if (ibft_addr->revision !=1 ) { +if (ibft_addr->header.revision !=1 ) {printk (KERN_ERR "iBFT module supports only revision 1, " \ -"while this is %d.\n" , ibft_addr->revision); +"while this is %d.\n" , + ibft_addr->header.revision);return -ENOENT ; }for (pos = (u8 *)ibft_addr; pos < (u8 *)ibft_addr + len; pos++)
@@ -558,7 +563,7 @@ static int __init ibft_check_device(void)/* * Helper function for ibft_register_kobjects. */ -static int __init ibft_create_kobject (struct ibft_table_header *header, +static int __init ibft_create_kobject (struct acpi_table_ibft *header,struct ibft_hdr *hdr,struct list_head *list) {
@@ -596,7 +601,7 @@ static int __init ibft_create_kobject(struct ibft_table_header *header,default :printk (KERN_ERR "iBFT has unknown structure type (%d). " \"Report this bug to %.6s!\n" , hdr->id, - header->oem_id); + header->header.oem_id); rc =1 ;break ; }
@@ -649,7 +654,7 @@ out_invalid_struct:* found add them on the passed-in list. We do not support the other * fields at this point, so they are skipped. */ -static int __init ibft_register_kobjects (struct ibft_table_header *header, +static int __init ibft_register_kobjects (struct acpi_table_ibft *header,struct list_head *list) {struct ibft_control *control =NULL ;
@@ -660,7 +665,7 @@ static int __init ibft_register_kobjects(struct ibft_table_header *header, control = (void *)header +sizeof (*header); end = (void *)control + control->hdr.length; - eot_offset = (void *)header + header->length - (void *)control; + eot_offset = (void *)header + header->header.length - (void *)control; rc =ibft_verify_hdr ("control" , (struct ibft_hdr *)control, id_control,sizeof (*control));
@@ -672,7 +677,8 @@ static int __init ibft_register_kobjects(struct ibft_table_header *header, }for (ptr = &control->initiator_off; ptr < end; ptr +=sizeof (u16)) { offset = *(u16 *)ptr; -if (offset && offset < header->length && offset < eot_offset) { +if (offset && offset < header->header.length && + offset < eot_offset) { rc =ibft_create_kobject (header, (void *)header + offset, list);
drivers/firmware/iscsi_ibft_find.c +29 -5
@@ -1,5 +1,5 @@/* -* Copyright 2007 Red Hat, Inc. +* Copyright 2007-2010 Red Hat, Inc. * by Peter Jones <[email protected]> * Copyright 2007 IBM, Inc. * by Konrad Rzeszutek <[email protected]>
@@ -22,6 +22,7 @@#include <linux/blkdev.h> #include <linux/ctype.h> #include <linux/device.h> +#include <linux/efi.h> #include <linux/err.h> #include <linux/init.h> #include <linux/limits.h>
@@ -30,13 +31,14 @@#include <linux/stat.h> #include <linux/string.h> #include <linux/types.h> +#include <linux/acpi.h> #include <asm/mmzone.h> /* * Physical location of iSCSI Boot Format Table. */ -struct ibft_table_header *ibft_addr; +struct acpi_table_ibft *ibft_addr;EXPORT_SYMBOL_GPL (ibft_addr);#define IBFT_SIGN "iBFT"
@@ -46,6 +48,13 @@ EXPORT_SYMBOL_GPL(ibft_addr);#define VGA_MEM 0xA0000/* VGA buffer */ #define VGA_SIZE 0x20000/* 128kB */ +#ifdef CONFIG_ACPI +static int __init acpi_find_ibft (struct acpi_table_header *header) +{ + ibft_addr = (struct acpi_table_ibft *)header; +return 0 ; +} +#endif /* CONFIG_ACPI */ /* * Routine used to find the iSCSI Boot Format Table. The logical
@@ -59,6 +68,11 @@ unsigned long __init find_ibft_region(unsigned long *sizep) ibft_addr =NULL ; +/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will +* only use ACPI for this */ +if (efi_enabled) +return 0 ; +for (pos =IBFT_START ; pos <IBFT_END ; pos +=16 ) {/* The table can't be inside the VGA BIOS reserved space, * so skip that area */
@@ -72,14 +86,24 @@ unsigned long __init find_ibft_region(unsigned long *sizep)/* if the length of the table extends past 1M, * the table cannot be valid. */ if (pos + len <= (IBFT_END -1 )) { - ibft_addr = (struct ibft_table_header *)virt; + ibft_addr = (struct acpi_table_ibft *)virt;break ; } } } +#ifdef CONFIG_ACPI +/* +* One spec says "IBFT", the other says "iBFT". We have to check +* for both. +*/ +if (!ibft_addr) +acpi_table_parse (ACPI_SIG_IBFT , acpi_find_ibft); +if (!ibft_addr) +acpi_table_parse ("iBFT" , acpi_find_ibft); +#endif /* CONFIG_ACPI */ if (ibft_addr) { - *sizep =PAGE_ALIGN (len); -return pos; + *sizep =PAGE_ALIGN (ibft_addr->header.length); +return (u64 )isa_virt_to_bus (ibft_addr); } *sizep =0 ;
include/linux/iscsi_ibft.h +2 -10
@@ -21,21 +21,13 @@#ifndef ISCSI_IBFT_H #define ISCSI_IBFT_H -struct ibft_table_header { -char signature[4 ]; -u32 length; -u8 revision; -u8 checksum; -char oem_id[6 ]; -char oem_table_id[8 ]; -char reserved[24 ]; -} __attribute__((__packed__ )); +#include <acpi/acpi.h> /* * Logical location of iSCSI Boot Format Table. * If the value is NULL there is no iBFT on the machine. */ -extern struct ibft_table_header *ibft_addr; +extern struct acpi_table_ibft *ibft_addr;/* * Routine used to find and reserve the iSCSI Boot Format Table. The
Signature · 1 line
1.7.0.5
Konrad Rzeszutek Wilk
maintainerPATCH 2/4 ibft: For UEFI machines actually do scan ACPI for iBFT.
In reply to Konrad Rzeszutek WilkFor machines with IBFT 1.03 do scan the ACPI table for 'iBFT' or for 'IBFT'. If the machine is in UEFI mode, only do the ACPI table scan. For all other machines (pre IBFT 1.03) do a memory scan if not found in the ACPI tables.
Author: Konrad Rzeszutek Wilk <[email protected]>
--- drivers/firmware/iscsi_ibft_find.c | 31 +++++++++++++++++++------------ 1 files changed, 19 insertions(+), 12 deletions(-)
drivers/firmware/iscsi_ibft_find.c +19 -12
@@ -56,23 +56,12 @@ static int __init acpi_find_ibft(struct acpi_table_header *header) }#endif /* CONFIG_ACPI */ -/* -* Routine used to find the iSCSI Boot Format Table. The logical -* kernel address is set in the ibft_addr global variable. -*/ -unsigned long __init find_ibft_region (unsigned long *sizep) +static int __init find_ibft_mem_scan (void ) {unsigned long pos;unsigned int len =0 ;void *virt; - ibft_addr =NULL ; - -/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will -* only use ACPI for this */ -if (efi_enabled) -return 0 ; -for (pos =IBFT_START ; pos <IBFT_END ; pos +=16 ) {/* The table can't be inside the VGA BIOS reserved space, * so skip that area */
@@ -91,6 +80,17 @@ unsigned long __init find_ibft_region(unsigned long *sizep) } } } +return len; +} +/* +* Routine used to find the iSCSI Boot Format Table. The logical +* kernel address is set in the ibft_addr global variable. +*/ +unsigned long __init find_ibft_region (unsigned long *sizep) +{ + + ibft_addr =NULL ; +#ifdef CONFIG_ACPI /* * One spec says "IBFT", the other says "iBFT". We have to check
@@ -101,6 +101,13 @@ unsigned long __init find_ibft_region(unsigned long *sizep)if (!ibft_addr)acpi_table_parse ("iBFT" , acpi_find_ibft);#endif /* CONFIG_ACPI */ + +/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will +* only use ACPI for this */ + +if (!ibft_addr && !efi_enabled) +find_ibft_mem_scan (); +if (ibft_addr) { *sizep =PAGE_ALIGN (ibft_addr->header.length);return (u64 )isa_virt_to_bus (ibft_addr);
Signature · 1 line
1.7.0.5
Konrad Rzeszutek Wilk
maintainerPATCH 3/4 ibft: separate ibft parsing from sysfs interface
In reply to Konrad Rzeszutek WilkFrom: Mike Christie <[email protected]>
Not all iscsi drivers support ibft. For drivers like be2iscsi that do not but are bootable through a vendor firmware specific format/process this patch moves the sysfs interface from the ibft code to a lib module. This then allows userspace tools to search for iscsi boot info in a common place and in a common format.
ibft iscsi boot info is exported in the same place as it was
before: /sys/firmware/ibft.
vendor/fw boot info gets export in /sys/firmware/iscsi_bootX, where X is the scsi host number of the HBA. Underneath these parent dirs, the target, ethernet, and initiator dirs are the same as they were before.
--- drivers/firmware/Kconfig | 8 + drivers/firmware/Makefile | 1 + drivers/firmware/iscsi_boot_sysfs.c | 481 +++++++++++++++++++++++++++++++++++ include/linux/iscsi_boot_sysfs.h | 123 +++++++++ 4 files changed, 613 insertions(+), 0 deletions(-) create mode 100644 drivers/firmware/iscsi_boot_sysfs.c create mode 100644 include/linux/iscsi_boot_sysfs.h
drivers/firmware/Kconfig +8 -0
@@ -122,6 +122,14 @@ config ISCSI_IBFT_FIND is necessary for iSCSI Boot Firmware Table Attributes module to work properly. +config ISCSI_BOOT_SYSFS + tristate "iSCSI Boot Sysfs Interface" + default n + help + This option enables support for exposing iSCSI boot information + via sysfs to userspace. If you wish to export this information, + say Y. Otherwise, say N. + config ISCSI_IBFT tristate "iSCSI Boot Firmware Table Attributes module" depends on ISCSI_IBFT_FIND
drivers/firmware/Makefile +1 -0
@@ -10,4 +10,5 @@ obj-$(CONFIG_DCDBAS) += dcdbas.o obj-$(CONFIG_DMIID) += dmi-id.o obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o +obj-$(CONFIG_ISCSI_BOOT_SYSFS) += iscsi_boot_sysfs.o obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o
drivers/firmware/iscsi_boot_sysfs.c new file +481 -0
481 lines not on this page · raw message
include/linux/iscsi_boot_sysfs.h new file +123 -0
123 lines not on this page · raw message
Signature · 1 line
1.7.0.5
Konrad Rzeszutek Wilk
maintainerPATCH 4/4 ibft: convert iscsi_ibft module to iscsi boot lib
In reply to Konrad Rzeszutek WilkFrom: Mike Christie <[email protected]>
This patch just converts the iscsi_ibft module to the iscsi boot sysfs lib module.
--- drivers/firmware/Kconfig | 1 + drivers/firmware/iscsi_ibft.c | 698 +++++++++++++++-------------------------- 2 files changed, 248 insertions(+), 451 deletions(-)
drivers/firmware/Kconfig +1 -0
@@ -132,6 +132,7 @@ config ISCSI_BOOT_SYSFS config ISCSI_IBFT tristate "iSCSI Boot Firmware Table Attributes module" + select ISCSI_BOOT_SYSFS depends on ISCSI_IBFT_FIND default n help
drivers/firmware/iscsi_ibft.c +247 -451
933 lines not on this page · raw message
Signature · 1 line
1.7.0.5