Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Headers redesign #3

Open
wants to merge 11 commits into
base: landing_zone
Choose a base branch
from
3 changes: 2 additions & 1 deletion src/arch/x86/image/bzimage.c
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,8 @@ static int bzimage_exec ( struct image *image ) {
*/
bzimg.pm_sz = ( bzimg.pm_sz + LZ_ALIGN - 1 ) & ~( LZ_ALIGN - 1 );

lz_set_bzimage ( lz, bzimg.rm_kernel, bzimg.pm_kernel + bzimg.pm_sz );
lz_set ( lz, bzimg.rm_kernel, bzimg.pm_kernel + bzimg.pm_sz,
LZ_PROTO_LINUX_BOOT );
bzimg.pm_sz += SLB_SIZE;
}

Expand Down
4 changes: 2 additions & 2 deletions src/arch/x86/image/elfboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ static int elfboot_exec ( struct image *image ) {
int rc;

/* Load the image using core ELF support */
if ( ( rc = elf_load ( image, &entry, &max ) ) != 0 ) {
if ( ( rc = elf_load ( image, NULL, &entry, &max ) ) != 0 ) {
DBGC ( image, "ELF %p could not load: %s\n",
image, strerror ( rc ) );
return rc;
Expand Down Expand Up @@ -129,7 +129,7 @@ static int elfboot_probe ( struct image *image ) {

/* Check that this image uses flat physical addressing */
if ( ( rc = elf_segments ( image, &ehdr, elfboot_check_segment,
&entry, &max ) ) != 0 ) {
NULL, &entry, &max ) ) != 0 ) {
DBGC ( image, "Unloadable ELF image\n" );
return rc;
}
Expand Down
157 changes: 140 additions & 17 deletions src/arch/x86/image/landing_zone.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,22 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/segment.h>
#include <ipxe/cpuid.h>
#include <ipxe/acpi.h>
#include <ipxe/hash_df.h>
#include <ipxe/sha1.h>
#include <ipxe/sha256.h>
#include <landing_zone.h>

struct sl_header {
u16 lz_offet;
u16 lz_length;
u16 lz_entry_point;
u16 bootloader_data_offset;
u16 lz_info_offset;
} __attribute__ (( packed ));

struct lz_header {
struct lz_info {
u8 uuid[16];
u32 slaunch_loader_size;
u32 zero_page_addr;
u32 event_log_addr;
u32 event_log_size;
u8 msb_key_hash[20];
u8 lz_hashes[];
u32 version;
u16 msb_key_algo;
u8 msb_key_hash[];
} __attribute__ (( packed ));

const unsigned char
Expand All @@ -44,6 +45,59 @@ struct drtm_t {
u8 var_len_fields[];
} __attribute__ (( packed ));

#define LZ_TAG_CLASS_MASK 0xF0

/* Tags with no particular class */
#define LZ_TAG_NO_CLASS 0x00
#define LZ_TAG_END 0x00
#define LZ_TAG_UNAWARE_OS 0x01
#define LZ_TAG_TAGS_SIZE 0x0F /* Always first */

/* Tags specifying kernel type */
#define LZ_TAG_BOOT_CLASS 0x10
#define LZ_TAG_BOOT_LINUX 0x10
#define LZ_TAG_BOOT_MB2 0x11

/* Tags specific to TPM event log */
#define LZ_TAG_EVENT_LOG_CLASS 0x20
#define LZ_TAG_EVENT_LOG 0x20
#define LZ_TAG_HASH 0x21

struct lz_tag_hdr {
u8 type;
u8 len;
} __attribute__ (( packed ));

struct lz_tag_tags_size {
struct lz_tag_hdr hdr;
u16 size;
} __attribute__ (( packed ));

struct lz_tag_boot_linux {
struct lz_tag_hdr hdr;
u32 zero_page;
} __attribute__ (( packed ));

struct lz_tag_boot_mb2 {
struct lz_tag_hdr hdr;
u32 mbi;
u32 kernel_entry;
u32 kernel_size;
} __attribute__ (( packed ));

struct lz_tag_evtlog {
struct lz_tag_hdr hdr;
u32 address;
u32 size;
} __attribute__ (( packed ));

struct lz_tag_hash {
struct lz_tag_hdr hdr;
u16 algo_id;
u8 digest[];
} __attribute__ (( packed ));


static physaddr_t target;

/**
Expand All @@ -52,7 +106,7 @@ static physaddr_t target;
* @v image LZ file
* @v zeropage Address of zero page
*/
int lz_set_bzimage ( struct image *image, userptr_t zeropage, userptr_t tgt ) {
int lz_set ( struct image *image, userptr_t zeropage, userptr_t tgt, int proto ) {
target = user_to_phys ( tgt, 0 );
int rc;

Expand All @@ -68,23 +122,91 @@ int lz_set_bzimage ( struct image *image, userptr_t zeropage, userptr_t tgt ) {
memcpy_user ( tgt, 0, image->data, 0, image->len );

struct sl_header *sl_hdr = ( struct sl_header *) tgt;
struct lz_header *hdr = ( struct lz_header *) ( tgt + sl_hdr->lz_length );
struct lz_tag_tags_size *tags = ( struct lz_tag_tags_size *)
( tgt + sl_hdr->bootloader_data_offset );

/* Tags header */
tags->hdr.type = LZ_TAG_TAGS_SIZE;
tags->hdr.len = sizeof(struct lz_tag_tags_size);
tags->size = sizeof(struct lz_tag_tags_size);

/* Hashes of LZ */
{
u8 buff[SHA256_CTX_SIZE]; /* SHA1_CTX_SIZE is smaller */
struct lz_tag_hash *h = ((void *)tags) + tags->size;
h->hdr.type = LZ_TAG_HASH;
h->hdr.len = sizeof(struct lz_tag_hash) + SHA256_DIGEST_SIZE;
h->algo_id = 0x000B;
sha256_algorithm.init ( buff );
sha256_algorithm.update ( buff, (void *) tgt,
sl_hdr->bootloader_data_offset );
sha256_algorithm.final ( buff, h->digest );
tags->size += h->hdr.len;

h = ((void *)tags) + tags->size;
h->hdr.type = LZ_TAG_HASH;
h->hdr.len = sizeof(struct lz_tag_hash) + SHA1_DIGEST_SIZE;
h->algo_id = 0x0004;
sha1_algorithm.init ( buff );
sha1_algorithm.update ( buff, (void *) tgt,
sl_hdr->bootloader_data_offset );
sha1_algorithm.final ( buff, h->digest );
tags->size += h->hdr.len;
}

/* Boot protocol data */
DBGC ( image, "LZ %p writing zeropage address: 0x%lx\n", image,
user_to_phys ( zeropage, 0 ) );

hdr->zero_page_addr = user_to_phys ( zeropage, 0 );
switch (proto) {
case LZ_PROTO_LINUX_BOOT:
{
struct lz_tag_boot_linux *b = ((void *)tags) + tags->size;
b->hdr.type = LZ_TAG_BOOT_LINUX;
b->hdr.len = sizeof(struct lz_tag_boot_linux);
b->zero_page = user_to_phys ( zeropage, 0 );
tags->size += b->hdr.len;
break;
}
case LZ_PROTO_MULTIBOOT2:
{
struct lz_tag_boot_mb2 *b = ((void *)tags) + tags->size;
physaddr_t *args = (physaddr_t *)zeropage;
b->hdr.type = LZ_TAG_BOOT_MB2;
b->hdr.len = sizeof(struct lz_tag_boot_mb2);
b->mbi = user_to_phys ( zeropage, 0 );
b->kernel_entry = args[0];
b->kernel_size = args[1];
tags->size += b->hdr.len;
break;

}
default:
return 1;
}

/* DRTM Event log address and size */
struct drtm_t *drtm = ( struct drtm_t *)
acpi_find ( ACPI_SIGNATURE ('D', 'R', 'T', 'M'), 0 );

if ( drtm != UNULL ) {
DBGC ( image, "ACPI DRTM table at %p (0x%lx physical)\n",
drtm, user_to_phys ( ( userptr_t ) drtm, 0 ) );
hdr->event_log_addr = drtm->Log_Area_Start;
hdr->event_log_size = drtm->Log_Area_Length;

struct lz_tag_evtlog *e = ((void *)tags) + tags->size;
e->hdr.type = LZ_TAG_EVENT_LOG;
e->hdr.len = sizeof(struct lz_tag_evtlog);
e->address = drtm->Log_Area_Start;
e->size = drtm->Log_Area_Length;
tags->size += e->hdr.len;
}

/* Mark end of tags */
struct lz_tag_hdr *end = ((void *)tags) + tags->size;
end->type = LZ_TAG_END;
end->len = sizeof(struct lz_tag_hdr);
tags->size += end->len;

return 0;
}

Expand Down Expand Up @@ -150,6 +272,7 @@ static int lz_exec ( struct image *image ) {
/* There is no way for the image to return, since we provide
* no return address.
*/
DBGC ( image, "LZ %p SKINIT returned\n", image );
assert ( 0 );

return -ECANCELED; /* -EIMPOSSIBLE */
Expand All @@ -164,7 +287,7 @@ static int lz_exec ( struct image *image ) {
static int lz_probe ( struct image *image ) {
int rc;
struct sl_header sl_hdr;
struct lz_header hdr;
struct lz_info lzi;
uint32_t eax, ebx, ecx, edx;

cpuid ( CPUID_AMD_CHECK, 0, &eax, &ebx, &ecx, &edx );
Expand All @@ -186,9 +309,9 @@ static int lz_probe ( struct image *image ) {
return -ENOEXEC;
}
copy_from_user ( &sl_hdr, image->data, 0, sizeof ( sl_hdr ) );
copy_from_user ( &hdr, image->data, sl_hdr.lz_length, sizeof ( hdr ) );
copy_from_user ( &lzi, image->data, sl_hdr.lz_info_offset, sizeof ( lzi ) );

rc = memcmp ( hdr.uuid, lz_header_uuid, sizeof ( lz_header_uuid ) );
rc = memcmp ( lzi.uuid, lz_header_uuid, sizeof ( lz_header_uuid ) );

if ( rc == 0 ) {
image_set_name ( image, "landing_zone" );
Expand Down
2 changes: 1 addition & 1 deletion src/arch/x86/image/multiboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ static int multiboot_load_elf ( struct image *image, physaddr_t *entry,
int rc;

/* Load ELF image*/
if ( ( rc = elf_load ( image, entry, max ) ) != 0 ) {
if ( ( rc = elf_load ( image, NULL, entry, max ) ) != 0 ) {
DBGC ( image, "MULTIBOOT %p ELF image failed to load: %s\n",
image, strerror ( rc ) );
return rc;
Expand Down
Loading