mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
initial import of openbios--main--1.0--patch-26
git-svn-id: svn://coreboot.org/openbios/openbios-devel@1 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
151
modules/elfnote.c
Normal file
151
modules/elfnote.c
Normal file
@@ -0,0 +1,151 @@
|
||||
/* Support for ELF Boot Proposal as a boot image */
|
||||
#include "openbios/config.h"
|
||||
#include "elf_boot.h"
|
||||
#include "sys_info.h"
|
||||
#include "asm/io.h"
|
||||
#include "ipchecksum.h"
|
||||
#define printf printk
|
||||
#define debug printk
|
||||
|
||||
/* ELF image notes provide information to the loader who boots us */
|
||||
|
||||
/* This compiles and generates correct PT_NOTE segment for me.
|
||||
* If it doesn't, use assembly version below. */
|
||||
|
||||
struct elf_image_note {
|
||||
Elf_Nhdr hdr0;
|
||||
char name0[sizeof(ELF_NOTE_BOOT)];
|
||||
char prog_name[sizeof(PROGRAM_NAME)];
|
||||
|
||||
Elf_Nhdr hdr1;
|
||||
char name1[sizeof(ELF_NOTE_BOOT)];
|
||||
char version[sizeof(PROGRAM_VERSION)];
|
||||
|
||||
Elf_Nhdr hdr2;
|
||||
char name2[sizeof(ELF_NOTE_BOOT)];
|
||||
unsigned short checksum;
|
||||
};
|
||||
|
||||
const struct elf_image_note elf_image_notes
|
||||
__attribute__ ((section (".note.ELFBoot"))) =
|
||||
{
|
||||
.hdr0 = {
|
||||
.n_namesz = sizeof(ELF_NOTE_BOOT),
|
||||
.n_descsz = sizeof(PROGRAM_NAME),
|
||||
.n_type = EIN_PROGRAM_NAME,
|
||||
},
|
||||
.name0 = ELF_NOTE_BOOT,
|
||||
.prog_name = PROGRAM_NAME,
|
||||
|
||||
.hdr1 = {
|
||||
.n_namesz = sizeof(ELF_NOTE_BOOT),
|
||||
.n_descsz = sizeof(PROGRAM_VERSION),
|
||||
.n_type = EIN_PROGRAM_VERSION,
|
||||
},
|
||||
.name1 = ELF_NOTE_BOOT,
|
||||
.version = PROGRAM_VERSION,
|
||||
|
||||
.hdr2 = {
|
||||
.n_namesz = sizeof(ELF_NOTE_BOOT),
|
||||
.n_descsz = sizeof(unsigned short),
|
||||
.n_type = EIN_PROGRAM_CHECKSUM,
|
||||
},
|
||||
.name2 = ELF_NOTE_BOOT,
|
||||
.checksum = 0, /* to be computed by external tool */
|
||||
};
|
||||
|
||||
/* This is refered by other files */
|
||||
const char *program_name = elf_image_notes.prog_name;
|
||||
const char *program_version = elf_image_notes.version;
|
||||
|
||||
#if 0
|
||||
|
||||
/* This tells the linker to make a PT_NOTE segment.
|
||||
* If the section is named just ".note", it will be
|
||||
* mixed up with useless .version notes generated by GCC.
|
||||
*/
|
||||
.section ".note.ELFBoot", "a"
|
||||
|
||||
.align 4
|
||||
.int 2f - 1f
|
||||
.int 4f - 3f
|
||||
.int EIN_PROGRAM_NAME
|
||||
1: .asciz "ELFBoot"
|
||||
2: .align 4
|
||||
3: .asciz PROGRAM_NAME
|
||||
4:
|
||||
|
||||
.align 4
|
||||
.int 2f - 1f
|
||||
.int 4f - 3f
|
||||
.int EIN_PROGRAM_VERSION
|
||||
1: .asciz "ELFBoot"
|
||||
2: .align 4
|
||||
3: .asciz PROGRAM_VERSION
|
||||
4:
|
||||
|
||||
.align 4
|
||||
.int 2f - 1f
|
||||
.int 4f - 3f
|
||||
.int EIN_PROGRAM_CHECKSUM
|
||||
1: .asciz "ELFBoot"
|
||||
2: .align 4
|
||||
3: .short 0
|
||||
4:
|
||||
#endif
|
||||
|
||||
/* Collect information from the ELF bootloader
|
||||
* Note that we have to copy them to our own memory,
|
||||
* otherwise they might be overwritten afterward. */
|
||||
void collect_elfboot_info(struct sys_info *info)
|
||||
{
|
||||
Elf_Bhdr *hdr = NULL;
|
||||
char *addr, *end;
|
||||
Elf_Nhdr *nhdr;
|
||||
char *name, *desc;
|
||||
|
||||
if (info->boot_type == ELF_BHDR_MAGIC)
|
||||
hdr = phys_to_virt(info->boot_data);
|
||||
else
|
||||
hdr = phys_to_virt(info->boot_arg);
|
||||
|
||||
if (hdr->b_signature != ELF_BHDR_MAGIC)
|
||||
return;
|
||||
|
||||
if (ipchksum(hdr, hdr->b_size) != 0) {
|
||||
printf("Broken ELF boot notes\n");
|
||||
return;
|
||||
}
|
||||
|
||||
addr = (char *) (hdr + 1);
|
||||
end = addr + hdr->b_size;
|
||||
while (addr < end) {
|
||||
nhdr = (Elf_Nhdr *) addr;
|
||||
addr += sizeof(Elf_Nhdr);
|
||||
name = addr;
|
||||
addr += (nhdr->n_namesz + 3) & ~3;
|
||||
desc = addr;
|
||||
addr += (nhdr->n_descsz + 3) & ~3;
|
||||
|
||||
if (nhdr->n_namesz == 0) {
|
||||
/* Standard notes */
|
||||
switch (nhdr->n_type) {
|
||||
case EBN_FIRMWARE_TYPE:
|
||||
info->firmware = strdup(desc);
|
||||
break;
|
||||
case EBN_BOOTLOADER_NAME:
|
||||
debug("Bootloader: %s\n", desc);
|
||||
break;
|
||||
case EBN_BOOTLOADER_VERSION:
|
||||
debug("Version: %s\n", desc);
|
||||
break;
|
||||
case EBN_COMMAND_LINE:
|
||||
info->command_line = strdup(desc);
|
||||
break;
|
||||
case EBN_LOADED_IMAGE:
|
||||
debug("Image name: %s\n", desc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user