mirror of
https://github.com/ipxe/ipxe
synced 2025-12-09 10:50:28 +03:00
[fdt] Allow an initrd to be specified when creating a device tree
Allow an initrd location to be specified in our constructed device tree via the "linux,initrd-start" and "linux,initrd-end" properties. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -1055,18 +1055,17 @@ static int fdt_ensure_child ( struct fdt *fdt, unsigned int offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensure property exists with specified value
|
* Set property value
|
||||||
*
|
*
|
||||||
* @v fdt Device tree
|
* @v fdt Device tree
|
||||||
* @v offset Starting node offset
|
* @v offset Starting node offset
|
||||||
* @v name Property name
|
* @v name Property name
|
||||||
* @v data Property data
|
* @v data Property data, or NULL to delete property
|
||||||
* @v len Length of property data
|
* @v len Length of property data
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int fdt_ensure_property ( struct fdt *fdt, unsigned int offset,
|
static int fdt_set ( struct fdt *fdt, unsigned int offset, const char *name,
|
||||||
const char *name, const void *data,
|
const void *data, size_t len ) {
|
||||||
size_t len ) {
|
|
||||||
struct fdt_descriptor desc;
|
struct fdt_descriptor desc;
|
||||||
struct {
|
struct {
|
||||||
fdt_token_t token;
|
fdt_token_t token;
|
||||||
@@ -1112,6 +1111,10 @@ static int fdt_ensure_property ( struct fdt *fdt, unsigned int offset,
|
|||||||
insert = ( sizeof ( *hdr ) + len );
|
insert = ( sizeof ( *hdr ) + len );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Leave property erased if applicable */
|
||||||
|
if ( ! data )
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* Insert space */
|
/* Insert space */
|
||||||
if ( ( rc = fdt_insert_nop ( fdt, desc.offset, insert ) ) != 0 )
|
if ( ( rc = fdt_insert_nop ( fdt, desc.offset, insert ) ) != 0 )
|
||||||
return rc;
|
return rc;
|
||||||
@@ -1166,10 +1169,15 @@ static int fdt_urealloc ( struct fdt *fdt, size_t len ) {
|
|||||||
*
|
*
|
||||||
* @v fdt Device tree
|
* @v fdt Device tree
|
||||||
* @v cmdline Command line, or NULL
|
* @v cmdline Command line, or NULL
|
||||||
|
* @v initrd Initial ramdisk address (or 0 for no initrd)
|
||||||
|
* @v initrd_len Initial ramdisk length (or 0 for no initrd)
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int fdt_bootargs ( struct fdt *fdt, const char *cmdline ) {
|
static int fdt_bootargs ( struct fdt *fdt, const char *cmdline,
|
||||||
|
physaddr_t initrd, size_t initrd_len ) {
|
||||||
unsigned int chosen;
|
unsigned int chosen;
|
||||||
|
physaddr_t addr;
|
||||||
|
const void *data;
|
||||||
size_t len;
|
size_t len;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@@ -1177,14 +1185,25 @@ static int fdt_bootargs ( struct fdt *fdt, const char *cmdline ) {
|
|||||||
if ( ( rc = fdt_ensure_child ( fdt, 0, "chosen", &chosen ) ) != 0 )
|
if ( ( rc = fdt_ensure_child ( fdt, 0, "chosen", &chosen ) ) != 0 )
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
/* Use empty command line if none specified */
|
/* Set or clear "bootargs" property */
|
||||||
if ( ! cmdline )
|
len = ( cmdline ? ( strlen ( cmdline ) + 1 /* NUL */ ) : 0 );
|
||||||
cmdline = "";
|
if ( ( rc = fdt_set ( fdt, chosen, "bootargs", cmdline, len ) ) != 0 )
|
||||||
|
return rc;
|
||||||
|
|
||||||
/* Ensure "bootargs" property exists */
|
/* Set or clear initrd properties */
|
||||||
len = ( strlen ( cmdline ) + 1 /* NUL */ );
|
data = ( initrd_len ? &addr : NULL );
|
||||||
if ( ( rc = fdt_ensure_property ( fdt, chosen, "bootargs", cmdline,
|
len = ( initrd_len ? sizeof ( addr ) : 0 );
|
||||||
len ) ) != 0 )
|
addr = initrd;
|
||||||
|
addr = ( ( sizeof ( addr ) == sizeof ( uint64_t ) ) ?
|
||||||
|
cpu_to_be64 ( addr ) : cpu_to_be32 ( addr ) );
|
||||||
|
if ( ( rc = fdt_set ( fdt, chosen, "linux,initrd-start", data,
|
||||||
|
len ) ) != 0 )
|
||||||
|
return rc;
|
||||||
|
addr = ( initrd + initrd_len );
|
||||||
|
addr = ( ( sizeof ( addr ) == sizeof ( uint64_t ) ) ?
|
||||||
|
cpu_to_be64 ( addr ) : cpu_to_be32 ( addr ) );
|
||||||
|
if ( ( rc = fdt_set ( fdt, chosen, "linux,initrd-end", data,
|
||||||
|
len ) ) != 0 )
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1195,9 +1214,12 @@ static int fdt_bootargs ( struct fdt *fdt, const char *cmdline ) {
|
|||||||
*
|
*
|
||||||
* @v hdr Device tree header to fill in (may be set to NULL)
|
* @v hdr Device tree header to fill in (may be set to NULL)
|
||||||
* @v cmdline Command line, or NULL
|
* @v cmdline Command line, or NULL
|
||||||
|
* @v initrd Initial ramdisk address (or 0 for no initrd)
|
||||||
|
* @v initrd_len Initial ramdisk length (or 0 for no initrd)
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
int fdt_create ( struct fdt_header **hdr, const char *cmdline ) {
|
int fdt_create ( struct fdt_header **hdr, const char *cmdline,
|
||||||
|
physaddr_t initrd, size_t initrd_len ) {
|
||||||
struct image *image;
|
struct image *image;
|
||||||
struct fdt fdt;
|
struct fdt fdt;
|
||||||
void *copy;
|
void *copy;
|
||||||
@@ -1228,7 +1250,7 @@ int fdt_create ( struct fdt_header **hdr, const char *cmdline ) {
|
|||||||
fdt.realloc = fdt_urealloc;
|
fdt.realloc = fdt_urealloc;
|
||||||
|
|
||||||
/* Populate boot arguments */
|
/* Populate boot arguments */
|
||||||
if ( ( rc = fdt_bootargs ( &fdt, cmdline ) ) != 0 )
|
if ( ( rc = fdt_bootargs ( &fdt, cmdline, initrd, initrd_len ) ) != 0 )
|
||||||
goto err_bootargs;
|
goto err_bootargs;
|
||||||
|
|
||||||
no_fdt:
|
no_fdt:
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ static int lkrn_fdt ( struct image *image, struct lkrn_context *ctx ) {
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Build device tree (which may change system memory map) */
|
/* Build device tree (which may change system memory map) */
|
||||||
if ( ( rc = fdt_create ( &fdt, image->cmdline ) ) != 0 )
|
if ( ( rc = fdt_create ( &fdt, image->cmdline, 0, 0 ) ) != 0 )
|
||||||
goto err_create;
|
goto err_create;
|
||||||
len = be32_to_cpu ( fdt->totalsize );
|
len = be32_to_cpu ( fdt->totalsize );
|
||||||
|
|
||||||
|
|||||||
@@ -199,7 +199,8 @@ extern int fdt_mac ( struct fdt *fdt, unsigned int offset,
|
|||||||
struct net_device *netdev );
|
struct net_device *netdev );
|
||||||
extern int fdt_parse ( struct fdt *fdt, struct fdt_header *hdr,
|
extern int fdt_parse ( struct fdt *fdt, struct fdt_header *hdr,
|
||||||
size_t max_len );
|
size_t max_len );
|
||||||
extern int fdt_create ( struct fdt_header **hdr, const char *cmdline );
|
extern int fdt_create ( struct fdt_header **hdr, const char *cmdline,
|
||||||
|
physaddr_t initrd, size_t initrd_len );
|
||||||
extern void fdt_remove ( struct fdt_header *hdr );
|
extern void fdt_remove ( struct fdt_header *hdr );
|
||||||
|
|
||||||
#endif /* _IPXE_FDT_H */
|
#endif /* _IPXE_FDT_H */
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ int efi_fdt_install ( const char *cmdline ) {
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Create device tree */
|
/* Create device tree */
|
||||||
if ( ( rc = fdt_create ( &efi_fdt_installed, cmdline ) ) != 0 ) {
|
if ( ( rc = fdt_create ( &efi_fdt_installed, cmdline, 0, 0 ) ) != 0 ) {
|
||||||
DBGC ( &efi_fdt, "EFI_FDT could not install: %s\n",
|
DBGC ( &efi_fdt, "EFI_FDT could not install: %s\n",
|
||||||
strerror ( rc ) );
|
strerror ( rc ) );
|
||||||
goto err_create;
|
goto err_create;
|
||||||
|
|||||||
Reference in New Issue
Block a user