mirror of
https://github.com/ipxe/ipxe
synced 2025-12-19 11:00:27 +03:00
Removed the Etherboot-specific ELF-image code and replaced it with a
generic ELF loader, to be used by the multiboot code.
This commit is contained in:
@@ -1,136 +0,0 @@
|
||||
#include "etherboot.h"
|
||||
#include "elf.h"
|
||||
#include "memsizes.h"
|
||||
|
||||
|
||||
#define NAME "Etherboot"
|
||||
|
||||
#if defined(PCBIOS)
|
||||
#define FIRMWARE "PCBIOS"
|
||||
#endif
|
||||
#if defined(LINUXBIOS)
|
||||
#define FIRMWARE "LinuxBIOS"
|
||||
#endif
|
||||
#if !defined(FIRMWARE)
|
||||
#error "No BIOS selected"
|
||||
#endif
|
||||
|
||||
#define SZ(X) ((sizeof(X)+3) & ~3)
|
||||
#define CP(D,S) (memcpy(&(D), &(S), sizeof(S)))
|
||||
|
||||
struct elf_notes {
|
||||
/* The note header */
|
||||
struct Elf_Bhdr hdr;
|
||||
|
||||
/* First the Fixed sized entries that must be well aligned */
|
||||
|
||||
/* Pointer to bootp data */
|
||||
Elf_Nhdr nf1;
|
||||
char nf1_name[SZ(EB_PARAM_NOTE)];
|
||||
uint32_t nf1_bootp_data;
|
||||
|
||||
/* Pointer to ELF header */
|
||||
Elf_Nhdr nf2;
|
||||
char nf2_name[SZ(EB_PARAM_NOTE)];
|
||||
uint32_t nf2_header;
|
||||
|
||||
/* A copy of the i386 memory map */
|
||||
Elf_Nhdr nf3;
|
||||
char nf3_name[SZ(EB_PARAM_NOTE)];
|
||||
struct meminfo nf3_meminfo;
|
||||
|
||||
/* Then the variable sized data string data where alignment does not matter */
|
||||
|
||||
/* The bootloader name */
|
||||
Elf_Nhdr nv1;
|
||||
char nv1_desc[SZ(NAME)];
|
||||
/* The bootloader version */
|
||||
Elf_Nhdr nv2;
|
||||
char nv2_desc[SZ(VERSION)];
|
||||
/* The firmware type */
|
||||
Elf_Nhdr nv3;
|
||||
char nv3_desc[SZ(FIRMWARE)];
|
||||
/* Name of the loaded image */
|
||||
Elf_Nhdr nv4;
|
||||
char nv4_loaded_image[128];
|
||||
/* An empty command line */
|
||||
Elf_Nhdr nv5;
|
||||
char nv5_cmdline[SZ("")];
|
||||
};
|
||||
|
||||
#define ELF_NOTE_COUNT (3 + 5)
|
||||
|
||||
static struct elf_notes notes;
|
||||
struct Elf_Bhdr *prepare_boot_params(void *header)
|
||||
{
|
||||
memset(¬es, 0, sizeof(notes));
|
||||
notes.hdr.b_signature = ELF_BHDR_MAGIC;
|
||||
notes.hdr.b_size = sizeof(notes);
|
||||
notes.hdr.b_checksum = 0;
|
||||
notes.hdr.b_records = ELF_NOTE_COUNT;
|
||||
|
||||
/* Initialize the fixed length entries. */
|
||||
notes.nf1.n_namesz = sizeof(EB_PARAM_NOTE);
|
||||
notes.nf1.n_descsz = sizeof(notes.nf1_bootp_data);
|
||||
notes.nf1.n_type = EB_BOOTP_DATA;
|
||||
CP(notes.nf1_name, EB_PARAM_NOTE);
|
||||
notes.nf1_bootp_data = virt_to_phys(&bootp_data);
|
||||
|
||||
notes.nf2.n_namesz = sizeof(EB_PARAM_NOTE);
|
||||
notes.nf2.n_descsz = sizeof(notes.nf2_header);
|
||||
notes.nf2.n_type = EB_HEADER;
|
||||
CP(notes.nf2_name, EB_PARAM_NOTE);
|
||||
notes.nf2_header = virt_to_phys(header);
|
||||
|
||||
notes.nf3.n_namesz = sizeof(EB_PARAM_NOTE);
|
||||
notes.nf3.n_descsz = sizeof(notes.nf3_meminfo);
|
||||
notes.nf3.n_type = EB_I386_MEMMAP;
|
||||
CP(notes.nf3_name, EB_PARAM_NOTE);
|
||||
memcpy(¬es.nf3_meminfo, &meminfo, sizeof(meminfo));
|
||||
|
||||
/* Initialize the variable length entries */
|
||||
notes.nv1.n_namesz = 0;
|
||||
notes.nv1.n_descsz = sizeof(NAME);
|
||||
notes.nv1.n_type = EBN_BOOTLOADER_NAME;
|
||||
CP(notes.nv1_desc, NAME);
|
||||
|
||||
notes.nv2.n_namesz = 0;
|
||||
notes.nv2.n_descsz = sizeof(VERSION);
|
||||
notes.nv2.n_type = EBN_BOOTLOADER_VERSION;
|
||||
CP(notes.nv2_desc, VERSION);
|
||||
|
||||
notes.nv3.n_namesz = 0;
|
||||
notes.nv3.n_descsz = sizeof(FIRMWARE);
|
||||
notes.nv3.n_type = EBN_FIRMWARE_TYPE;
|
||||
CP(notes.nv3_desc, FIRMWARE);
|
||||
|
||||
/* Attempt to pass the name of the loaded image */
|
||||
notes.nv4.n_namesz = 0;
|
||||
notes.nv4.n_descsz = sizeof(notes.nv4_loaded_image);
|
||||
notes.nv4.n_type = EBN_LOADED_IMAGE;
|
||||
memcpy(¬es.nv4_loaded_image, KERNEL_BUF, sizeof(notes.nv4_loaded_image));
|
||||
|
||||
/* Pass an empty command line for now */
|
||||
notes.nv5.n_namesz = 0;
|
||||
notes.nv5.n_descsz = sizeof("");
|
||||
notes.nv5.n_type = EBN_COMMAND_LINE;
|
||||
CP(notes.nv5_cmdline, "");
|
||||
|
||||
|
||||
notes.hdr.b_checksum = ipchksum(¬es, sizeof(notes));
|
||||
/* Like UDP invert a 0 checksum to show that a checksum is present */
|
||||
if (notes.hdr.b_checksum == 0) {
|
||||
notes.hdr.b_checksum = 0xffff;
|
||||
}
|
||||
return ¬es.hdr;
|
||||
}
|
||||
|
||||
int elf_start(unsigned long machine __unused_i386, unsigned long entry, unsigned long params)
|
||||
{
|
||||
#if defined(CONFIG_X86_64)
|
||||
if (machine == EM_X86_64) {
|
||||
return xstart_lm(entry, params);
|
||||
}
|
||||
#endif
|
||||
return xstart32(entry, params);
|
||||
}
|
||||
Reference in New Issue
Block a user