mirror of
https://github.com/fail0verflow/switch-coreboot.git
synced 2025-05-04 01:39:18 -04:00
Updates to produce a linuxBIOS table. Modeled on the earlier
uniform_boot work, but relocated. You need the new mkelfImage to use the elf boot format. Previous tables were updated so I could find both the start and the end of where they were written in memory. Minor p4dc6 updates, to disable some debugging code. The mkelfImage-1.9 is checked in as util/mkelfImage
This commit is contained in:
parent
d9db3cd6c4
commit
9cda94e6d2
32 changed files with 3383 additions and 117 deletions
|
@ -1 +1,2 @@
|
|||
object boot.o
|
||||
object linuxbios_table.o
|
||||
|
|
|
@ -1,86 +1,59 @@
|
|||
#include <boot/uniform_boot.h>
|
||||
#include <ip_checksum.h>
|
||||
#include <boot/elf.h>
|
||||
#include <boot/elf_boot.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef CMD_LINE
|
||||
#define CMD_LINE ""
|
||||
#endif
|
||||
|
||||
/* FIXME: the current placement of ube_all could lead to problems...
|
||||
* It should be in a location normally reserved for the bios.
|
||||
*/
|
||||
|
||||
|
||||
#define UPSZ(X) ((sizeof(X) + 3) &~3)
|
||||
|
||||
static struct {
|
||||
struct uniform_boot_header header;
|
||||
struct linuxbios_header lb_header;
|
||||
struct {
|
||||
struct {
|
||||
struct ube_memory memory;
|
||||
struct ube_memory_range range[2];
|
||||
} mem;
|
||||
}env;
|
||||
unsigned char command_line[1024];
|
||||
} ube_all = {
|
||||
.header = {
|
||||
.header_bytes = sizeof(ube_all.header),
|
||||
.header_checksum = 0,
|
||||
.arg = (unsigned long)&ube_all.command_line,
|
||||
.arg_bytes = sizeof(ube_all.command_line),
|
||||
.env = (unsigned long)&ube_all.env,
|
||||
.env_bytes = sizeof(ube_all.env),
|
||||
Elf_Bhdr hdr;
|
||||
Elf_Nhdr ft_hdr;
|
||||
unsigned char ft_desc[UPSZ(FIRMWARE_TYPE)];
|
||||
Elf_Nhdr bl_hdr;
|
||||
unsigned char bl_desc[UPSZ(BOOTLOADER)];
|
||||
Elf_Nhdr blv_hdr;
|
||||
unsigned char blv_desc[UPSZ(BOOTLOADER_VERSION)];
|
||||
Elf_Nhdr cmd_hdr;
|
||||
unsigned char cmd_desc[UPSZ(CMD_LINE)];
|
||||
} elf_boot_notes = {
|
||||
.hdr = {
|
||||
.b_signature = 0x0E1FB007,
|
||||
.b_size = sizeof(elf_boot_notes),
|
||||
.b_checksum = 0,
|
||||
.b_records = 4,
|
||||
},
|
||||
.lb_header = {
|
||||
.signature = { 'L', 'B', 'I', 'O' },
|
||||
.header_bytes = sizeof(ube_all.lb_header),
|
||||
.header_checksum = 0,
|
||||
.env_bytes = sizeof(ube_all.env),
|
||||
.env_checksum = 0,
|
||||
.env_entries = 0,
|
||||
.ft_hdr = {
|
||||
.n_namesz = 0,
|
||||
.n_descsz = sizeof(FIRMWARE_TYPE),
|
||||
.n_type = EBN_FIRMWARE_TYPE,
|
||||
},
|
||||
.env = {
|
||||
.mem = {
|
||||
.memory = {
|
||||
.tag = UBE_TAG_MEMORY,
|
||||
.size = sizeof(ube_all.env.mem),
|
||||
},
|
||||
.range = {
|
||||
#if 0
|
||||
{
|
||||
.start = 0,
|
||||
.size = 0xa0000, /* 640k */
|
||||
.type = UBE_MEM_RAM,
|
||||
},
|
||||
#else
|
||||
{
|
||||
.start = 4096, /* skip the first page */
|
||||
.size = 0x9f000, /* 640k */
|
||||
.type = UBE_MEM_RAM,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.start = 0x00100000, /* 1M */
|
||||
.size = 0, /* Fill in the size */
|
||||
.type = UBE_MEM_RAM,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
.ft_desc = FIRMWARE_TYPE,
|
||||
.bl_hdr = {
|
||||
.n_namesz = 0,
|
||||
.n_descsz = sizeof(BOOTLOADER),
|
||||
.n_type = EBN_BOOTLOADER_NAME,
|
||||
},
|
||||
.command_line = CMD_LINE,
|
||||
.bl_desc = BOOTLOADER,
|
||||
.blv_hdr = {
|
||||
.n_namesz = 0,
|
||||
.n_descsz = sizeof(BOOTLOADER_VERSION),
|
||||
.n_type = EBN_BOOTLOADER_VERSION,
|
||||
},
|
||||
.blv_desc = BOOTLOADER_VERSION,
|
||||
.cmd_hdr = {
|
||||
.n_namesz = 0,
|
||||
.n_descsz = sizeof(CMD_LINE),
|
||||
.n_type = EBN_COMMAND_LINE,
|
||||
},
|
||||
.cmd_desc = CMD_LINE,
|
||||
};
|
||||
|
||||
void *get_ube_pointer(unsigned long totalram)
|
||||
{
|
||||
ube_all.env.mem.range[1].size = ((totalram - 1024) << 10);
|
||||
ube_all.header.header_checksum = 0;
|
||||
ube_all.header.header_checksum =
|
||||
uniform_boot_compute_header_checksum(&ube_all.header);
|
||||
ube_all.lb_header.env_entries = 1; /* FIXME remove this hardcode.. */
|
||||
ube_all.lb_header.env_checksum =
|
||||
compute_checksum(&ube_all.env, sizeof(ube_all.env));
|
||||
ube_all.lb_header.header_checksum =
|
||||
compute_checksum(&ube_all.lb_header, sizeof(ube_all.lb_header));
|
||||
return &ube_all.header;
|
||||
}
|
||||
|
||||
int elf_check_arch(Elf_ehdr *ehdr)
|
||||
{
|
||||
|
@ -92,9 +65,11 @@ int elf_check_arch(Elf_ehdr *ehdr)
|
|||
|
||||
}
|
||||
|
||||
void jmp_to_elf_entry(void *entry, void *ube)
|
||||
void jmp_to_elf_entry(void *entry)
|
||||
{
|
||||
unsigned long type = 0x0A11B007;
|
||||
unsigned long type = 0x0E1FB007;
|
||||
elf_boot_notes.hdr.b_checksum =
|
||||
compute_ip_checksum(&elf_boot_notes, sizeof(elf_boot_notes));
|
||||
|
||||
/* Jump to kernel */
|
||||
__asm__ __volatile__(
|
||||
|
@ -104,7 +79,7 @@ void jmp_to_elf_entry(void *entry, void *ube)
|
|||
"popl %%ebx\n\t"
|
||||
"popl %%eax\n\t"
|
||||
"ret\n\t"
|
||||
:: "g" (entry), "g"(type), "g"(ube));
|
||||
:: "g" (entry), "g"(type), "g"(&elf_boot_notes));
|
||||
}
|
||||
|
||||
|
||||
|
|
177
src/arch/i386/boot/linuxbios_table.c
Normal file
177
src/arch/i386/boot/linuxbios_table.c
Normal file
|
@ -0,0 +1,177 @@
|
|||
#include <ip_checksum.h>
|
||||
#include <boot/linuxbios_tables.h>
|
||||
#include <boot/linuxbios_table.h>
|
||||
#include <printk.h>
|
||||
|
||||
struct lb_header *lb_table_init(unsigned long addr)
|
||||
{
|
||||
struct lb_header *header;
|
||||
|
||||
/* 16 byte align the address */
|
||||
addr += 15;
|
||||
addr &= ~15;
|
||||
|
||||
header = (void *)addr;
|
||||
header->signature[0] = 'L';
|
||||
header->signature[1] = 'B';
|
||||
header->signature[2] = 'I';
|
||||
header->signature[3] = 'O';
|
||||
header->header_bytes = sizeof(*header);
|
||||
header->header_checksum = 0;
|
||||
header->table_bytes = 0;
|
||||
header->table_checksum = 0;
|
||||
header->table_entries = 0;
|
||||
return header;
|
||||
}
|
||||
|
||||
struct lb_record *lb_first_record(struct lb_header *header)
|
||||
{
|
||||
struct lb_record *rec;
|
||||
rec = (void *)(((char *)header) + sizeof(*header));
|
||||
return rec;
|
||||
}
|
||||
|
||||
struct lb_record *lb_last_record(struct lb_header *header)
|
||||
{
|
||||
struct lb_record *rec;
|
||||
rec = (void *)(((char *)header) + sizeof(*header) + header->table_bytes);
|
||||
return rec;
|
||||
}
|
||||
|
||||
struct lb_record *lb_next_record(struct lb_record *rec)
|
||||
{
|
||||
rec = (void *)(((char *)rec) + rec->size);
|
||||
return rec;
|
||||
}
|
||||
|
||||
struct lb_record *lb_new_record(struct lb_header *header)
|
||||
{
|
||||
struct lb_record *rec;
|
||||
rec = lb_last_record(header);
|
||||
if (header->table_entries) {
|
||||
header->table_bytes += rec->size;
|
||||
}
|
||||
rec = lb_last_record(header);
|
||||
header->table_entries++;
|
||||
rec->tag = LB_TAG_UNUSED;
|
||||
rec->size = sizeof(*rec);
|
||||
return rec;
|
||||
}
|
||||
|
||||
|
||||
struct lb_memory *lb_memory(struct lb_header *header)
|
||||
{
|
||||
struct lb_record *rec;
|
||||
struct lb_memory *mem;
|
||||
rec = lb_new_record(header);
|
||||
mem = (struct lb_memory *)rec;
|
||||
mem->tag = LB_TAG_MEMORY;
|
||||
mem->size = sizeof(*mem);
|
||||
return mem;
|
||||
}
|
||||
|
||||
/* Some version of gcc have problems with 64 bit types so
|
||||
* take an unsigned long instead of a uint64_t for now.
|
||||
*/
|
||||
void lb_memory_range(struct lb_memory *mem,
|
||||
uint32_t type, unsigned long start, unsigned long size)
|
||||
{
|
||||
int entries;
|
||||
entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
|
||||
mem->map[entries].start = start;
|
||||
mem->map[entries].size = size;
|
||||
mem->map[entries].type = type;
|
||||
mem->size += sizeof(mem->map[0]);
|
||||
}
|
||||
|
||||
static void lb_reserve_table_memory(struct lb_header *head)
|
||||
{
|
||||
struct lb_record *rec, *last_rec;
|
||||
struct lb_memory *mem;
|
||||
uint64_t start;
|
||||
uint64_t end;
|
||||
int i, entries;
|
||||
last_rec = lb_last_record(head);
|
||||
mem = 0;
|
||||
for(rec = lb_first_record(head); rec < last_rec; lb_next_record(rec)) {
|
||||
if (rec->tag == LB_TAG_MEMORY) {
|
||||
mem = (struct lb_memory *)rec;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!mem)
|
||||
return;
|
||||
printk_debug("head = %p last_rec = %p\n", head, last_rec);
|
||||
start = (unsigned long)head;
|
||||
end = (unsigned long)last_rec;
|
||||
printk_debug("start = 0x%08lx end = 0x%08lx\n", (unsigned long)start, (unsigned long)end);
|
||||
entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
|
||||
/* Resize the right two memory areas so this table is in
|
||||
* a reserved area of memory. Everything has been carefully
|
||||
* setup so that is all we need to do.
|
||||
*/
|
||||
for(i = 0; i < entries; i++ ) {
|
||||
uint64_t map_start = mem->map[i].start;
|
||||
uint64_t map_end = map_start + mem->map[i].size;
|
||||
/* Does this area need to be expanded? */
|
||||
if (map_end == start) {
|
||||
mem->map[i].size = end - map_start;
|
||||
}
|
||||
/* Does this area need to be contracted? */
|
||||
else if (map_start == start) {
|
||||
mem->map[i].start = end;
|
||||
mem->map[i].size = map_end - end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long lb_table_fini(struct lb_header *head)
|
||||
{
|
||||
struct lb_record *rec, *first_rec;
|
||||
rec = lb_last_record(head);
|
||||
if (head->table_entries) {
|
||||
head->table_bytes += rec->size;
|
||||
}
|
||||
lb_reserve_table_memory(head);
|
||||
first_rec = lb_first_record(head);
|
||||
head->table_checksum = compute_ip_checksum(first_rec, head->table_bytes);
|
||||
head->header_checksum = 0;
|
||||
head->header_checksum = compute_ip_checksum(head, sizeof(*head));
|
||||
printk_debug("Write linuxbios table at: %p - %p\n",
|
||||
head, rec);
|
||||
return (unsigned long)rec;
|
||||
}
|
||||
|
||||
unsigned long setup_memory_table(
|
||||
struct lb_memory *mem,
|
||||
unsigned long totalram,
|
||||
unsigned long low_table_start, unsigned long low_table_end)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned long write_linuxbios_table(
|
||||
unsigned long *processor_map,
|
||||
unsigned long totalram,
|
||||
unsigned long low_table_start, unsigned long low_table_end,
|
||||
unsigned long rom_table_start, unsigned long rom_table_end)
|
||||
{
|
||||
struct lb_header *head;
|
||||
struct lb_memory *mem;
|
||||
|
||||
head = lb_table_init(low_table_end);
|
||||
low_table_end = (unsigned long)head;
|
||||
|
||||
mem = lb_memory(head);
|
||||
/* Reserve our tables in low memory */
|
||||
lb_memory_range(mem, LB_MEM_RESERVED, low_table_start, low_table_end - low_table_start);
|
||||
lb_memory_range(mem, LB_MEM_RAM, low_table_end, 640*1024 - low_table_end);
|
||||
/* Reserve the whole dos BIOS reserved area, we can probably do
|
||||
* better but it isn't too important right now
|
||||
*/
|
||||
lb_memory_range(mem, LB_MEM_RESERVED, 0x000a0000, 0x00060000);
|
||||
/* Now show all of memory */
|
||||
lb_memory_range(mem, LB_MEM_RAM, 0x00100000, (totalram - 1024) << 10);
|
||||
|
||||
low_table_end = lb_table_fini(head);
|
||||
return low_table_end;
|
||||
}
|
|
@ -38,9 +38,9 @@ void check_pirq_routing_table(void);
|
|||
#endif
|
||||
|
||||
#if defined(HAVE_PIRQ_TABLE)
|
||||
void copy_pirq_routing_table(void);
|
||||
unsigned long copy_pirq_routing_table(unsigned long start);
|
||||
#else
|
||||
#define copy_pirq_routing_table() do {} while(0)
|
||||
#define copy_pirq_routing_table(start) (start)
|
||||
#endif
|
||||
|
||||
#endif /* ARCH_PIRQ_ROUTING_H */
|
||||
|
|
|
@ -264,8 +264,8 @@ void smp_write_compatibility_address_space(struct mp_config_table *mc,
|
|||
unsigned char busid, unsigned char address_modifier,
|
||||
unsigned int range_list);
|
||||
unsigned char smp_compute_checksum(void *v, int len);
|
||||
void smp_write_floating_table(void *v);
|
||||
void write_smp_table(void *v, unsigned long *processor_map);
|
||||
void *smp_write_floating_table(unsigned long addr);
|
||||
unsigned long write_smp_table(unsigned long addr, unsigned long *processor_map);
|
||||
|
||||
/* A table (per mainboard) listing the initial apicid of each cpu. */
|
||||
extern unsigned long initial_apicid[MAX_CPUS];
|
||||
|
@ -273,7 +273,7 @@ extern unsigned long initial_apicid[MAX_CPUS];
|
|||
#else /* HAVE_MP_TABLE */
|
||||
#define CPU_ENABLED 1 /* Processor is available */
|
||||
#define CPU_BOOTPROCESSOR 2 /* Processor is the BP */
|
||||
#define write_smp_table(v,p) do {} while(0)
|
||||
#define write_smp_table(v,p) ({ p; v; })
|
||||
#endif /* HAVE_MP_TABLE */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -57,6 +57,7 @@ static char rcsid[] = "$Id$";
|
|||
#include <arch/ioapic.h>
|
||||
#include <smp/atomic.h>
|
||||
#include <arch/smp/mpspec.h>
|
||||
#include <boot/linuxbios_table.h>
|
||||
|
||||
|
||||
/* The processor map.
|
||||
|
@ -157,6 +158,36 @@ static void wait_for_other_cpus(void)
|
|||
#define wait_for_other_cpus() do {} while(0)
|
||||
#endif /* SMP */
|
||||
|
||||
void write_tables(unsigned long totalram)
|
||||
{
|
||||
unsigned long low_table_start, low_table_end;
|
||||
unsigned long rom_table_start, rom_table_end;
|
||||
|
||||
rom_table_start = 0xf0000;
|
||||
rom_table_end = 0xf0000;
|
||||
/* Start low addr at 16 bytes instead of 0 because of a buglet
|
||||
* in the generic linux bunzip code, as it tests for the a20 line.
|
||||
*/
|
||||
low_table_start = 0;
|
||||
low_table_end = 16;
|
||||
|
||||
post_code(0x9a);
|
||||
check_pirq_routing_table();
|
||||
/* This table must be betweeen 0xf0000 & 0x100000 */
|
||||
rom_table_end = copy_pirq_routing_table(rom_table_end);
|
||||
|
||||
/* copy the smp block to address 0 */
|
||||
post_code(0x96);
|
||||
/* The smp table must be in 0-1K, 639K-640K, or 960K-1M */
|
||||
low_table_end = write_smp_table(low_table_end, processor_map);
|
||||
|
||||
/* The linuxbios table must be in 0-1K or 960K-1M */
|
||||
write_linuxbios_table(
|
||||
processor_map, totalram,
|
||||
low_table_start, low_table_end,
|
||||
rom_table_start, rom_table_end);
|
||||
}
|
||||
|
||||
void hardwaremain(int boot_complete)
|
||||
{
|
||||
/* Processor ID of the BOOT cpu (i.e. the one running this code) */
|
||||
|
@ -266,10 +297,7 @@ void hardwaremain(int boot_complete)
|
|||
|
||||
pci_zero_irq_settings();
|
||||
|
||||
check_pirq_routing_table();
|
||||
copy_pirq_routing_table();
|
||||
|
||||
post_code(0x9a);
|
||||
|
||||
/* to do: intel_serial_on(); */
|
||||
|
||||
|
@ -285,9 +313,11 @@ void hardwaremain(int boot_complete)
|
|||
/* make certain we are the only cpu running in linuxBIOS */
|
||||
wait_for_other_cpus();
|
||||
|
||||
/* copy the smp block to address 0 */
|
||||
post_code(0x96);
|
||||
write_smp_table((void *)16, processor_map);
|
||||
/* Now that we have collected all of our information
|
||||
* write our configuration tables.
|
||||
*/
|
||||
write_tables(totalram);
|
||||
|
||||
|
||||
#ifdef LINUXBIOS
|
||||
printk_info("Jumping to linuxbiosmain()...\n");
|
||||
|
|
|
@ -53,11 +53,16 @@ void check_pirq_routing_table(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#define RTABLE_DEST 0xf0000
|
||||
|
||||
void copy_pirq_routing_table(void)
|
||||
unsigned long copy_pirq_routing_table(unsigned long addr)
|
||||
{
|
||||
/* Align the table to be 16 byte aligned. */
|
||||
addr += 15;
|
||||
addr &= ~15;
|
||||
|
||||
/* This table must be betweeen 0xf0000 & 0x100000 */
|
||||
printk_info("Copying IRQ routing tables...");
|
||||
memcpy((char *) RTABLE_DEST, &intel_irq_routing_table, intel_irq_routing_table.size);
|
||||
memcpy((void *)addr, &intel_irq_routing_table, intel_irq_routing_table.size);
|
||||
printk_info("done.\n");
|
||||
|
||||
return addr + intel_irq_routing_table.size;
|
||||
}
|
||||
|
|
|
@ -22,9 +22,15 @@ unsigned char smp_compute_checksum(void *v, int len)
|
|||
return checksum;
|
||||
}
|
||||
|
||||
void smp_write_floating_table(void *v)
|
||||
void *smp_write_floating_table(unsigned long addr)
|
||||
{
|
||||
struct intel_mp_floating *mf;
|
||||
void *v;
|
||||
|
||||
/* 16 byte align the table address */
|
||||
addr += 15;
|
||||
addr &= ~15;
|
||||
v = (void *)addr;
|
||||
|
||||
mf = v;
|
||||
mf->mpf_signature[0] = '_';
|
||||
|
@ -41,6 +47,7 @@ void smp_write_floating_table(void *v)
|
|||
mf->mpf_feature4 = 0;
|
||||
mf->mpf_feature5 = 0;
|
||||
mf->mpf_checksum = smp_compute_checksum(mf, mf->mpf_length*16);
|
||||
return v;
|
||||
}
|
||||
|
||||
void *smp_next_mpc_entry(struct mp_config_table *mc)
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
object uniform_boot.o
|
|
@ -390,6 +390,11 @@ typedef Elf64_Phdr Elf_phdr;
|
|||
#endif
|
||||
|
||||
extern int elf_check_arch(Elf_ehdr *ehdr);
|
||||
extern void jmp_to_elf_entry(void *entry, void *ube);
|
||||
extern int elfboot(size_t totalram);
|
||||
extern void jmp_to_elf_entry(void *entry);
|
||||
extern int elfboot(void);
|
||||
|
||||
#define FIRMWARE_TYPE "LinuxBIOS"
|
||||
#define BOOTLOADER "elfboot"
|
||||
#define BOOTLOADER_VERSION "0.99999"
|
||||
|
||||
#endif /* elf.h */
|
||||
|
|
89
src/include/boot/elf_boot.h
Normal file
89
src/include/boot/elf_boot.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
#ifndef ELF_BOOT_H
|
||||
#define ELF_BOOT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* This defines the structure of a table of parameters useful for ELF
|
||||
* bootable images. These parameters are all passed and generated
|
||||
* by the bootloader to the booted image. For simplicity and
|
||||
* consistency the Elf Note format is reused.
|
||||
*
|
||||
* All of the information must be Position Independent Data.
|
||||
* That is it must be safe to relocate the whole ELF boot parameter
|
||||
* block without changing the meaning or correctnes of the data.
|
||||
* Additionally it must be safe to permute the order of the ELF notes
|
||||
* to any possible permutation without changing the meaning or correctness
|
||||
* of the data.
|
||||
*
|
||||
*/
|
||||
|
||||
#define ELF_HEAD_SIZE (8*1024)
|
||||
#define ELF_BOOT_MAGIC 0x0E1FB007
|
||||
|
||||
typedef uint16_t Elf_Half;
|
||||
typedef uint32_t Elf_Word;
|
||||
typedef uint64_t Elf_Xword;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf_Word b_signature; /* "0x0E1FB007" */
|
||||
Elf_Word b_size;
|
||||
Elf_Half b_checksum;
|
||||
Elf_Half b_records;
|
||||
} Elf_Bhdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf_Word n_namesz; /* Length of the note's name. */
|
||||
Elf_Word n_descsz; /* Length of the note's descriptor. */
|
||||
Elf_Word n_type; /* Type of the note. */
|
||||
} Elf_Nhdr;
|
||||
|
||||
|
||||
/* For standard notes n_namesz must be zero */
|
||||
/* All of the following standard note types provide a single null
|
||||
* terminated string in the descriptor.
|
||||
*/
|
||||
#define EBN_FIRMWARE_TYPE 0x00000001
|
||||
/* On platforms that support multiple classes of firmware this field
|
||||
* specifies the class of firmware you are loaded under.
|
||||
*/
|
||||
#define EBN_BOOTLOADER_NAME 0x00000002
|
||||
/* This specifies just the name of the bootloader for easy comparison */
|
||||
#define EBN_BOOTLOADER_VERSION 0x00000003
|
||||
/* This specifies the version of the bootlader */
|
||||
#define EBN_COMMAND_LINE 0x00000004
|
||||
/* This specifies a command line that can be set by user interaction,
|
||||
* and is provided as a free form string to the loaded image.
|
||||
*/
|
||||
|
||||
|
||||
/* Standardized Elf image notes for booting... The name for all of these is ELFBoot */
|
||||
|
||||
#define ELF_NOTE_BOOT "ELFBoot"
|
||||
|
||||
#define EIN_PROGRAM_NAME 0x00000001
|
||||
/* The program in this ELF file */
|
||||
#define EIN_PROGRAM_VERSION 0x00000002
|
||||
/* The version of the program in this ELF file */
|
||||
#define EIN_PROGRAM_CHECKSUM 0x00000003
|
||||
/* ip style checksum of the memory image. */
|
||||
|
||||
|
||||
/* Linux image notes for booting... The name for all of these is Linux */
|
||||
|
||||
#define LINUX_NOTE_BOOT "Linux"
|
||||
|
||||
#define LIN_COMMAND_LINE 0x00000001
|
||||
/* The command line to pass to the loaded kernel. */
|
||||
#define LIN_ROOT_DEV 0x00000002
|
||||
/* The root dev to pass to the loaded kernel. */
|
||||
#define LIN_RAMDISK_FLAGS 0x00000003
|
||||
/* Various old ramdisk flags */
|
||||
#define LIN_INITRD_START 0x00000004
|
||||
/* Start of the ramdisk in bytes */
|
||||
#define LIN_INITRD_SIZE 0x00000005
|
||||
/* Size of the ramdisk in bytes */
|
||||
|
||||
|
||||
#endif /* ELF_BOOT_H */
|
23
src/include/boot/linuxbios_table.h
Normal file
23
src/include/boot/linuxbios_table.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef LINUXBIOS_TABLE_H
|
||||
#define LINUXBIOS_TABLE_H
|
||||
|
||||
#include <boot/linuxbios_tables.h>
|
||||
|
||||
/* This file holds function prototypes for building the linuxbios table. */
|
||||
unsigned long write_linuxbios_table(
|
||||
unsigned long *processor_map,
|
||||
unsigned long totalram,
|
||||
unsigned long low_table_start, unsigned long low_table_end,
|
||||
unsigned long rom_table_start, unsigned long rom_table_end);
|
||||
|
||||
struct lb_header *lb_table_init(unsigned long addr);
|
||||
struct lb_record *lb_first_record(struct lb_header *header);
|
||||
struct lb_record *lb_last_record(struct lb_header *header);
|
||||
struct lb_record *lb_next_record(struct lb_record *rec);
|
||||
struct lb_record *lb_new_record(struct lb_header *header);
|
||||
struct lb_memory *lb_memory(struct lb_header *header);
|
||||
void lb_memory_range(struct lb_memory *mem,
|
||||
uint32_t type, unsigned long start, unsigned long size);
|
||||
unsigned long lb_table_fini(struct lb_header *header);
|
||||
|
||||
#endif /* LINUXBIOS_TABLE_H */
|
83
src/include/boot/linuxbios_tables.h
Normal file
83
src/include/boot/linuxbios_tables.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
#ifndef LINUXBIOS_TABLES_H
|
||||
#define LINUXBIOS_TABLES_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* The linuxbios table information is for conveying information
|
||||
* from the firmware to the loaded OS image. Primarily this
|
||||
* is expected to be information that cannot be discovered by
|
||||
* other means, such as quering the hardware directly.
|
||||
*
|
||||
* All of the information should be Position Independent Data.
|
||||
* That is it should be safe to relocated any of the information
|
||||
* without it's meaning/correctnes changing. For table that
|
||||
* can reasonably be used on multiple architectures the data
|
||||
* size should be fixed. This should ease the transition between
|
||||
* 32 bit and 64 bit architectures etc.
|
||||
*
|
||||
* The completeness test for the information in this table is:
|
||||
* - Can all of the hardware be detected?
|
||||
* - Are the per motherboard constants available?
|
||||
* - Is there enough to allow a kernel to run that was written before
|
||||
* a particular motherboard is constructed? (Assuming the kernel
|
||||
* has drivers for all of the hardware but it does not have
|
||||
* assumptions on how the hardware is connected together).
|
||||
*
|
||||
* With this test it should be straight forward to determine if a
|
||||
* table entry is required or not. This should remove much of the
|
||||
* long term compatibility burden as table entries which are
|
||||
* irrelevant or have been replaced by better alternatives may be
|
||||
* dropped. Of course it is polite and expidite to include extra
|
||||
* table entries and be backwards compatible, but it is not required.
|
||||
*/
|
||||
|
||||
|
||||
struct lb_header
|
||||
{
|
||||
uint8_t signature[4]; /* LBIO */
|
||||
uint32_t header_bytes;
|
||||
uint32_t header_checksum;
|
||||
uint32_t table_bytes;
|
||||
uint32_t table_checksum;
|
||||
uint32_t table_entries;
|
||||
};
|
||||
|
||||
/* Every entry in the boot enviroment list will correspond to a boot
|
||||
* info record. Encoding both type and size. The type is obviously
|
||||
* so you can tell what it is. The size allows you to skip that
|
||||
* boot enviroment record if you don't know what it easy. This allows
|
||||
* forward compatibility with records not yet defined.
|
||||
*/
|
||||
struct lb_record {
|
||||
uint32_t tag; /* tag ID */
|
||||
uint32_t size; /* size of record (in bytes) */
|
||||
};
|
||||
|
||||
#define LB_TAG_UNUSED 0x0000
|
||||
|
||||
#define LB_TAG_MEMORY 0x0001
|
||||
|
||||
struct lb_memory_range {
|
||||
uint64_t start;
|
||||
uint64_t size;
|
||||
uint32_t type;
|
||||
#define LB_MEM_RAM 1
|
||||
#define LB_MEM_RESERVED 2
|
||||
|
||||
};
|
||||
|
||||
struct lb_memory {
|
||||
uint32_t tag;
|
||||
uint32_t size;
|
||||
struct lb_memory_range map[0];
|
||||
};
|
||||
|
||||
#define LB_TAG_HWRPB 0x0002
|
||||
struct lb_hwrpb {
|
||||
uint32_t tag;
|
||||
uint32_t size;
|
||||
uint64_t hwrpb;
|
||||
};
|
||||
|
||||
|
||||
#endif /* LINUXBIOS_TABLES_H */
|
6
src/include/ip_checksum.h
Normal file
6
src/include/ip_checksum.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef IP_CHECKSUM_H
|
||||
#define IP_CHECKSUM_H
|
||||
|
||||
unsigned long compute_ip_checksum(void *addr, unsigned long length);
|
||||
|
||||
#endif /* IP_CHECKSUM_H */
|
|
@ -16,3 +16,4 @@ object do_inflate.o
|
|||
object floppy_subr.o
|
||||
object delay.o
|
||||
object fallback_boot.o USE_FALLBACK_BOOT
|
||||
object compute_ip_checksum.o
|
20
src/lib/compute_ip_checksum.c
Normal file
20
src/lib/compute_ip_checksum.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
#include <ip_checksum.h>
|
||||
|
||||
unsigned long compute_ip_checksum(void *addr, unsigned long length)
|
||||
{
|
||||
unsigned short *ptr;
|
||||
unsigned long sum;
|
||||
unsigned long len;
|
||||
/* Assumes len is a multiple of two, and addr is 2 byte aligned. */
|
||||
/* compute an ip style checksum */
|
||||
sum = 0;
|
||||
len = length >> 1;
|
||||
ptr = addr;
|
||||
while (len--) {
|
||||
sum += *(ptr++);
|
||||
if (sum > 0xFFFF)
|
||||
sum -= 0xFFFF;
|
||||
}
|
||||
return (~sum) & 0xFFFF;
|
||||
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
#include <printk.h>
|
||||
#include <part/fallback_boot.h>
|
||||
#include <boot/elf.h>
|
||||
#include <boot/uniform_boot.h>
|
||||
#include <boot/elf_boot.h>
|
||||
#include <rom/read_bytes.h>
|
||||
#include <string.h>
|
||||
#include <subr.h>
|
||||
|
@ -57,7 +57,7 @@ static int safe_range(unsigned long start, unsigned long len)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int elfboot(size_t totalram)
|
||||
int elfboot(void)
|
||||
{
|
||||
static unsigned char header[ELF_HEAD_SIZE];
|
||||
unsigned long offset;
|
||||
|
@ -68,15 +68,14 @@ int elfboot(size_t totalram)
|
|||
int i;
|
||||
|
||||
printk_info("\n");
|
||||
printk_info("Welcome to elfboot, the open sourced starter.\n");
|
||||
printk_info("Febuary 2001, Eric Biederman.\n");
|
||||
printk_info("Version 0.9999\n");
|
||||
printk_info("Welcome to %s, the open sourced starter.\n", BOOTLOADER);
|
||||
printk_info("January 2002, Eric Biederman.\n");
|
||||
printk_info("Version %s\n", BOOTLOADER_VERSION);
|
||||
printk_info("\n");
|
||||
if (streams->init() < 0) {
|
||||
printk_err("Could not initialize driver...\n");
|
||||
goto out;
|
||||
}
|
||||
ptr = get_ube_pointer(totalram);
|
||||
|
||||
post_code(0xf8);
|
||||
/* Read in the initial ELF_HEAD_SIZE bytes */
|
||||
|
@ -228,7 +227,7 @@ int elfboot(size_t totalram)
|
|||
post_code(0xfe);
|
||||
|
||||
/* Jump to kernel */
|
||||
jmp_to_elf_entry(entry, ptr);
|
||||
jmp_to_elf_entry(entry);
|
||||
|
||||
out:
|
||||
printk_err("Bad ELF Image\n");
|
||||
|
|
|
@ -51,7 +51,7 @@ int linuxbiosmain(unsigned long base, unsigned long totalram)
|
|||
#endif /* USE_TFTP */
|
||||
|
||||
#if USE_ELF_BOOT
|
||||
return elfboot(totalram);
|
||||
return elfboot();
|
||||
#else /* !ELF_BOOT */
|
||||
printk_info("\n");
|
||||
printk_info("Welcome to start32, the open sourced starter.\n");
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include <string.h>
|
||||
#include <printk.h>
|
||||
|
||||
void smp_write_config_table(void *v, unsigned long * processor_map)
|
||||
void *smp_write_config_table(void *v, unsigned long * processor_map)
|
||||
{
|
||||
int ioapicid = 0;
|
||||
static const char sig[4] = "PCMP";
|
||||
|
@ -120,12 +120,14 @@ void smp_write_config_table(void *v, unsigned long * processor_map)
|
|||
mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
|
||||
printk_debug("Wrote the mp table end at: %p - %p\n",
|
||||
mc, smp_next_mpe_entry(mc));
|
||||
return smp_next_mpe_entry(mc);
|
||||
}
|
||||
|
||||
void write_smp_table(void *v, unsigned long *processor_map)
|
||||
unsigned long write_smp_table(unsigned long addr, unsigned long *processor_map)
|
||||
{
|
||||
smp_write_floating_table(v);
|
||||
smp_write_config_table(v, processor_map);
|
||||
void *v;
|
||||
v = smp_write_floating_table(addr);
|
||||
return (unsigned long)smp_write_config_table(v, processor_map);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -16,8 +16,8 @@ nooption USE_DEFAULT_LAYOUT
|
|||
option STACK_SIZE=0x2000
|
||||
option USE_FALLBACK_BOOT=1
|
||||
|
||||
option USE_RAMTEST=1
|
||||
dir /src/ram
|
||||
#option USE_RAMTEST=1
|
||||
#dir /src/ram
|
||||
|
||||
#/* falback */
|
||||
option ZKERNEL_START=0xffff0000
|
||||
|
|
|
@ -82,7 +82,7 @@ void cache_ram_start(void)
|
|||
|
||||
init_memory();
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
{
|
||||
unsigned long addr;
|
||||
for(addr = 0; addr < 0x20000000; addr += 0x02000000) {
|
||||
|
@ -97,6 +97,7 @@ void cache_ram_start(void)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
error |= ramcheck(0x00000000, 0x00080000, 20);
|
||||
error |= ramcheck(0x02000000, 0x02080000, 20);
|
||||
error |= ramcheck(0x04000000, 0x04080000, 20);
|
||||
|
@ -114,13 +115,14 @@ void cache_ram_start(void)
|
|||
error |= ramcheck(0x1a000000, 0x1a080000, 20);
|
||||
error |= ramcheck(0x1c000000, 0x1c080000, 20);
|
||||
error |= ramcheck(0x1e000000, 0x1e080000, 20);
|
||||
#endif
|
||||
#if 0
|
||||
error |= ramcheck(0x00000000, 0x00080000, 20);
|
||||
#endif
|
||||
#if 1
|
||||
#if 0
|
||||
display_rdram_regs(rdram_chips );
|
||||
#endif
|
||||
#if 1
|
||||
#if 0
|
||||
display_mch_regs();
|
||||
#endif
|
||||
if (error) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include <string.h>
|
||||
#include <printk.h>
|
||||
|
||||
void smp_write_config_table(void *v, unsigned long * processor_map)
|
||||
void *smp_write_config_table(void *v, unsigned long * processor_map)
|
||||
{
|
||||
int ioapicid = 0;
|
||||
static const char sig[4] = "PCMP";
|
||||
|
@ -125,12 +125,14 @@ void smp_write_config_table(void *v, unsigned long * processor_map)
|
|||
mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
|
||||
printk_debug("Wrote the mp table end at: %p - %p\n",
|
||||
mc, smp_next_mpe_entry(mc));
|
||||
return smp_next_mpe_entry(mc);
|
||||
}
|
||||
|
||||
void write_smp_table(void *v, unsigned long *processor_map)
|
||||
unsigned long write_smp_table(unsigned long addr, unsigned long *processor_map)
|
||||
{
|
||||
smp_write_floating_table(v);
|
||||
smp_write_config_table(v, processor_map);
|
||||
void *v;
|
||||
v = smp_write_floating_table(addr);
|
||||
return (unsigned long)smp_write_config_table(v, processor_map);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include <printk.h>
|
||||
#include <cpu/p6/apic.h>
|
||||
|
||||
void smp_write_config_table(void *v, unsigned long * processor_map)
|
||||
void *smp_write_config_table(void *v, unsigned long * processor_map)
|
||||
{
|
||||
static const char sig[4] = "PCMP";
|
||||
static const char oem[8] = "TYAN ";
|
||||
|
@ -145,13 +145,15 @@ void smp_write_config_table(void *v, unsigned long * processor_map)
|
|||
mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
|
||||
printk_debug("Wrote the mp table end at: %p - %p\n",
|
||||
mc, smp_next_mpe_entry(mc));
|
||||
return smp_next_mpe_entry(mc);
|
||||
}
|
||||
|
||||
void write_smp_table(void *v, unsigned long *processor_map)
|
||||
unsigned long write_smp_table(unsigned long addr, unsigned long *processor_map)
|
||||
{
|
||||
void *v;
|
||||
printk_debug("Writing the mp table\n");
|
||||
smp_write_floating_table(v);
|
||||
smp_write_config_table(v, processor_map);
|
||||
v = smp_write_floating_table(addr);
|
||||
return (unsigned long)smp_write_config_table(v, processor_map);
|
||||
}
|
||||
|
||||
|
||||
|
|
341
util/mkelfImage/COPYING
Normal file
341
util/mkelfImage/COPYING
Normal file
|
@ -0,0 +1,341 @@
|
|||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
41
util/mkelfImage/Makefile
Normal file
41
util/mkelfImage/Makefile
Normal file
|
@ -0,0 +1,41 @@
|
|||
PREFIX=/opt/lnxi
|
||||
PERLPATH=/usr/bin/perl
|
||||
VERSION="1.9"
|
||||
DATE="7 January 2002"
|
||||
|
||||
SHAREDIR=$(PREFIX)/share/mkelfImage
|
||||
BINDIR=$(PREFIX)/bin
|
||||
MANDIR=$(PREFIX)/man/man1
|
||||
|
||||
DIRS=$(SHAREDIR) $(BINDIR) $(MANDIR)
|
||||
|
||||
MANS=mkelfImage.1
|
||||
|
||||
FILES=mkelfImage $(MANS)
|
||||
|
||||
all: $(FILES)
|
||||
|
||||
clean:
|
||||
rm -f $(FILES)
|
||||
|
||||
install: $(DIRS) $(FILES)
|
||||
mkdir -p $(SHAREDIR) $(BINDIR) $(MANDIR)
|
||||
cp -fr elf32-i386/ $(SHAREDIR)
|
||||
find $(SHAREDIR) -type d | xargs chmod a+x
|
||||
find $(SHAREDIR) -type f | xargs chmod 444
|
||||
cp -f mkelfImage $(BINDIR)
|
||||
cp -f $(MANS) $(MANDIR)
|
||||
|
||||
$(DIRS):
|
||||
mkdir -p $@
|
||||
|
||||
%.1 : %.pl Makefile
|
||||
pod2man --date=$(DATE) --release=$(VERSION) $*.pl > $@
|
||||
|
||||
mkelfImage: mkelfImage.pl Makefile
|
||||
echo 's|^$$params{MYDATA}=".";$$|$$params{MYDATA}="$(SHAREDIR)";|' > sedfile
|
||||
echo 's|^#!/usr/bin/perl|#!$(PERLPATH)|' >> sedfile
|
||||
sed -f sedfile mkelfImage.pl > $@
|
||||
chmod a+x $@
|
||||
rm -f sedfile
|
||||
|
1515
util/mkelfImage/elf32-i386/convert_params.c
Normal file
1515
util/mkelfImage/elf32-i386/convert_params.c
Normal file
File diff suppressed because it is too large
Load diff
80
util/mkelfImage/elf32-i386/elfImage.lds
Normal file
80
util/mkelfImage/elf32-i386/elfImage.lds
Normal file
|
@ -0,0 +1,80 @@
|
|||
/* This setup assumes you have at least a 16M machine
|
||||
* The problem is that with 2GB of RAM you use nearly 23M
|
||||
* of memory in the kernel page tables, and since 2.2 doesn't check
|
||||
* where the initrd is placed before allocating memory this is a
|
||||
* problem. With a 8M Ramdisk + 23M kernel that is 31M leaving
|
||||
* little room for things to grow.
|
||||
* With the limit at 112M (i.e. 0x00700000) we should be o.k.)
|
||||
*
|
||||
* If you need to change the amount of assumed memory.
|
||||
* The uppper.LENGTH needs to change so that
|
||||
* upper.LENGTH + upper.ORIGIN = MEMORY_SIZE
|
||||
* and the computation just before ramdisk placing also should
|
||||
* be corrected, to be:
|
||||
* . = MEMORY_SIZE - ((ramdisk_data_end - ramdisk_data) + 4095)
|
||||
* .ramdisk(ALIGN(4096))
|
||||
*/
|
||||
|
||||
INCLUDE mkelfImage.lds
|
||||
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
|
||||
OUTPUT_ARCH(i386)
|
||||
MEMORY
|
||||
{
|
||||
/* 0x10000 - 0x90000 A good safe area in low memory I can use */
|
||||
low (rwx) : ORIGIN = 0x010000, LENGTH = 0x0080000
|
||||
middle (rwx) : ORIGIN = 0x091000, LENGTH = 0x0001000
|
||||
upper (rwx) : ORIGIN = 0x100000, LENGTH = 0x37f00000
|
||||
}
|
||||
ENTRY(startup_32)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x10000 ;
|
||||
_text = .; /* Text and read-only data */
|
||||
.text (.): {
|
||||
*(.text)
|
||||
*(.fixup)
|
||||
*(.gnu.warning)
|
||||
} > low = 0x9090
|
||||
.rodata (.): { *(.rodata) *(.note.data)} > low
|
||||
.kstrtab (.): { *(.kstrtab) } > low
|
||||
|
||||
|
||||
. = ALIGN(16); /* Exception table */
|
||||
_etext = .; /* End of text section */
|
||||
|
||||
.data (.): { /* Data */
|
||||
*(.data)
|
||||
CONSTRUCTORS
|
||||
} > low
|
||||
|
||||
_edata = .; /* End of data section */
|
||||
__bss_start = .; /* BSS */
|
||||
.bss (.): {
|
||||
*(.bss)
|
||||
} > low
|
||||
_end = . ;
|
||||
|
||||
|
||||
. = 0x91000 ;
|
||||
.nokill (.): {
|
||||
*(.nokill)
|
||||
} > middle
|
||||
|
||||
. = 0x100000 ;
|
||||
.kernel (.): {
|
||||
*(.kernel)
|
||||
} > upper
|
||||
. = initrd_base;
|
||||
.ramdisk (ALIGN(4096)) : {
|
||||
*(.ramdisk)
|
||||
} > upper
|
||||
ramdisk_data_size = (ramdisk_data_end - ramdisk_data);
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
}
|
83
util/mkelfImage/elf32-i386/elf_boot.h
Normal file
83
util/mkelfImage/elf32-i386/elf_boot.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
#ifndef ELF_BOOT_H
|
||||
#define ELF_BOOT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* This defines the structure of a table of parameters useful for ELF
|
||||
* bootable images. These parameters are all passed and generated
|
||||
* by the bootloader to the booted image. For simplicity and
|
||||
* consistency the Elf Note format is reused.
|
||||
*
|
||||
* All of the information must be Position Independent Data.
|
||||
* That is it must be safe to relocate the whole ELF boot parameter
|
||||
* block without changing the meaning or correctnes of the data.
|
||||
* Additionally it must be safe to permute the order of the ELF notes
|
||||
* to any possible permutation without changing the meaning or correctness
|
||||
* of the data.
|
||||
*
|
||||
*/
|
||||
|
||||
#define ELF_BOOT_MAGIC 0x0E1FB007
|
||||
|
||||
typedef uint16_t Elf_Half;
|
||||
typedef uint32_t Elf_Word;
|
||||
typedef uint64_t Elf_Xword;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf_Word b_signature; /* "0x0E1FB007" */
|
||||
Elf_Word b_size;
|
||||
Elf_Half b_checksum;
|
||||
Elf_Half b_records;
|
||||
} Elf_Bhdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf_Word n_namesz; /* Length of the note's name. */
|
||||
Elf_Word n_descsz; /* Length of the note's descriptor. */
|
||||
Elf_Word n_type; /* Type of the note. */
|
||||
} Elf_Nhdr;
|
||||
|
||||
/* For standard notes n_namesz must be zero */
|
||||
/* All of the following standard note types provide a single null
|
||||
* terminated string in the descriptor.
|
||||
*/
|
||||
#define EBN_FIRMWARE_TYPE 0x00000001
|
||||
/* On platforms that support multiple classes of firmware this field
|
||||
* specifies the class of firmware you are loaded under.
|
||||
*/
|
||||
#define EBN_BOOTLOADER_NAME 0x00000002
|
||||
/* This specifies just the name of the bootloader for easy comparison */
|
||||
#define EBN_BOOTLOADER_VERSION 0x00000003
|
||||
/* This specifies the version of the bootlader */
|
||||
#define EBN_COMMAND_LINE 0x00000004
|
||||
/* This specifies a command line that can be set by user interaction,
|
||||
* and is provided as a free form string to the loaded image.
|
||||
*/
|
||||
|
||||
|
||||
/* Standardized Elf image notes for booting... The name for all of these is ELFBoot */
|
||||
|
||||
#define EIN_PROGRAM_NAME 0x00000001
|
||||
/* The program in this ELF file */
|
||||
#define EIN_PROGRAM_VERSION 0x00000002
|
||||
/* The version of the program in this ELF file */
|
||||
#define EIN_PROGRAM_CHECKSUM 0x00000003
|
||||
/* ip style checksum of the memory image. */
|
||||
|
||||
|
||||
/* Linux image notes for booting... The name for all of these is Linux */
|
||||
|
||||
#define LIN_COMMAND_LINE 0x00000001
|
||||
/* The command line to pass to the loaded kernel. */
|
||||
#define LIN_ROOT_DEV 0x00000002
|
||||
/* The root dev to pass to the loaded kernel. */
|
||||
#define LIN_RAMDISK_FLAGS 0x00000003
|
||||
/* Various old ramdisk flags */
|
||||
#define LIN_INITRD_START 0x00000004
|
||||
/* Start of the ramdisk in bytes */
|
||||
#define LIN_INITRD_SIZE 0x00000005
|
||||
/* Size of the ramdisk in bytes */
|
||||
|
||||
|
||||
#endif /* ELF_BOOT_H */
|
390
util/mkelfImage/elf32-i386/head.S
Normal file
390
util/mkelfImage/elf32-i386/head.S
Normal file
|
@ -0,0 +1,390 @@
|
|||
#
|
||||
# exec_kernel/user_space/head.S
|
||||
#
|
||||
# Copyright (C) 2000 Eric Biederman
|
||||
#
|
||||
# Parts of this code were take from the linux startup
|
||||
# code of linux-2.4.0-test9
|
||||
#
|
||||
# Other parts were taken from etherboot-5.0.5
|
||||
#
|
||||
|
||||
#define RELOC 0x10000
|
||||
#define KERN_CODE_SEG 0x10
|
||||
#define KERN_DATA_SEG 0x18
|
||||
#define REAL_CODE_SEG 0x08
|
||||
#define REAL_DATA_SEG 0x20
|
||||
|
||||
.equ CR0_PE,1
|
||||
|
||||
#define TTYS0_BASE 0x3f8
|
||||
#define TTYS0_RBR (TTYS0_BASE+0x00)
|
||||
#define TTYS0_TBR TTYS0_RBR
|
||||
#define TTYS0_LSR (TTYS0_BASE+0x05)
|
||||
|
||||
|
||||
/* uses: ax, dx */
|
||||
#define TTYS0_TX_AL \
|
||||
mov %al, %ah ; \
|
||||
9: mov $TTYS0_LSR, %dx ; \
|
||||
inb %dx, %al ; \
|
||||
test $0x20, %al ; \
|
||||
je 9b ; \
|
||||
mov $TTYS0_TBR, %dx ; \
|
||||
mov %ah, %al ; \
|
||||
outb %al, %dx
|
||||
|
||||
/* uses: ax, dx */
|
||||
#define TTYS0_TX_CHAR(byte) \
|
||||
mov byte, %al ; \
|
||||
TTYS0_TX_AL
|
||||
|
||||
.text
|
||||
.code32
|
||||
.globl startup_32
|
||||
startup_32:
|
||||
cld
|
||||
cli
|
||||
|
||||
# Save the arguments safely out of the way
|
||||
movl %eax, %ebp
|
||||
movl %ebx, %esi
|
||||
|
||||
movl stack_start, %esp
|
||||
|
||||
|
||||
# Clear eflags
|
||||
pushl $0
|
||||
popfl
|
||||
|
||||
# Clear BSS
|
||||
xorl %eax,%eax
|
||||
movl $ _edata,%edi
|
||||
movl $ _end,%ecx
|
||||
subl %edi,%ecx
|
||||
cld
|
||||
rep
|
||||
stosb
|
||||
|
||||
# Linux makes stupid assumptions about the segments
|
||||
# that are already setup, so setup a new gdt & ldt
|
||||
# and then reload the segment registers.
|
||||
|
||||
lgdt gdt_48
|
||||
lidt idt_48
|
||||
|
||||
# Load the data segment registers
|
||||
movl $ 0x18, %eax
|
||||
movl %eax, %ds
|
||||
movl %eax, %es
|
||||
movl %eax, %fs
|
||||
movl %eax, %gs
|
||||
movl %eax, %ss
|
||||
|
||||
pushl %esi # boot data pointer as second arg
|
||||
pushl %ebp # boot data type as first argument
|
||||
call convert_params
|
||||
|
||||
movl %eax, %esi # put the real mode pointer in a safe place
|
||||
addl $8, %esp # pop the arguments
|
||||
|
||||
# Setup the registers before jumping to linux
|
||||
|
||||
|
||||
# clear eflags
|
||||
pushl $0
|
||||
popfl
|
||||
|
||||
# Flag to indicate we are the bootstrap processor
|
||||
xorl %ebx, %ebx
|
||||
|
||||
# Clear the unspecified registers for good measure
|
||||
xorl %eax, %eax
|
||||
xorl %ecx, %ecx
|
||||
xorl %edx, %edx
|
||||
xorl %edi, %edi
|
||||
xorl %esp, %esp
|
||||
xorl %ebp, %ebp
|
||||
|
||||
|
||||
# Jump to the linux kernel
|
||||
ljmp $ 0x10 , $ 0x100000
|
||||
|
||||
|
||||
/* Routines to query the BIOS... */
|
||||
.globl noop
|
||||
noop:
|
||||
TTYS0_TX_CHAR($'a')
|
||||
TTYS0_TX_CHAR($'\r')
|
||||
TTYS0_TX_CHAR($'\n')
|
||||
call _prot_to_real
|
||||
.code16
|
||||
TTYS0_TX_CHAR($'b')
|
||||
TTYS0_TX_CHAR($'\r')
|
||||
TTYS0_TX_CHAR($'\n')
|
||||
data32 call _real_to_prot
|
||||
.code32
|
||||
TTYS0_TX_CHAR($'c')
|
||||
TTYS0_TX_CHAR($'\r')
|
||||
TTYS0_TX_CHAR($'\n')
|
||||
ret
|
||||
|
||||
/**************************************************************************
|
||||
E820_MEMSIZE - Get a listing of memory regions
|
||||
**************************************************************************/
|
||||
#define SMAP 0x534d4150
|
||||
.globl meme820
|
||||
meme820:
|
||||
pushl %ebp
|
||||
movl %esp, %ebp
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
movl 8(%ebp), %edi /* Address to return e820 structures at */
|
||||
subl $RELOC, %edi
|
||||
movl 12(%ebp), %esi /* Maximum number of e820 structurs to return */
|
||||
pushl %esi
|
||||
call _prot_to_real
|
||||
.code16
|
||||
xorl %ebx, %ebx
|
||||
jmpe820:
|
||||
movl $0xe820, %eax
|
||||
movl $SMAP, %edx
|
||||
movl $20, %ecx
|
||||
/* %di was setup earlier */
|
||||
int $0x15
|
||||
jc bail820
|
||||
|
||||
cmpl $SMAP, %eax
|
||||
jne bail820
|
||||
|
||||
good820:
|
||||
/* If this is useable memory, we save it by simply advancing %di by
|
||||
* sizeof(e820rec)
|
||||
*/
|
||||
decl %esi
|
||||
testl %esi,%esi
|
||||
jz bail820
|
||||
|
||||
addw $20, %di
|
||||
again820:
|
||||
cmpl $0, %ebx /* check to see if %ebx is set to EOF */
|
||||
jne jmpe820
|
||||
|
||||
bail820:
|
||||
data32 call _real_to_prot
|
||||
.code32
|
||||
popl %eax
|
||||
subl %esi, %eax /* Compute how many structure we read */
|
||||
|
||||
/* Restore everything else */
|
||||
popl %edi
|
||||
popl %esi
|
||||
popl %ebx
|
||||
movl %ebp, %esp
|
||||
popl %ebp
|
||||
ret
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
MEME801 - Determine size of extended memory
|
||||
**************************************************************************/
|
||||
.globl meme801
|
||||
meme801:
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
call _prot_to_real
|
||||
.code16
|
||||
|
||||
stc # fix to work around buggy
|
||||
xorw %cx,%cx # BIOSes which dont clear/set
|
||||
xorw %dx,%dx # carry on pass/error of
|
||||
# e801h memory size call
|
||||
# or merely pass cx,dx though
|
||||
# without changing them.
|
||||
movw $0xe801,%ax
|
||||
int $0x15
|
||||
jc e801absent
|
||||
|
||||
cmpw $0x0, %cx # Kludge to handle BIOSes
|
||||
jne e801usecxdx # which report their extended
|
||||
cmpw $0x0, %dx # memory in AX/BX rather than
|
||||
jne e801usecxdx # CX/DX. The spec I have read
|
||||
movw %ax, %cx # seems to indicate AX/BX
|
||||
movw %bx, %dx # are more reasonable anyway...
|
||||
|
||||
e801usecxdx:
|
||||
andl $0xffff, %edx # clear sign extend
|
||||
shll $6, %edx # and go from 64k to 1k chunks
|
||||
movl %edx, %eax # store extended memory size
|
||||
andl $0xffff, %ecx # clear sign extend
|
||||
addl %ecx, %eax # and add lower memory into
|
||||
|
||||
jmp e801out
|
||||
e801absent:
|
||||
xorl %eax,%eax
|
||||
|
||||
e801out:
|
||||
data32 call _real_to_prot
|
||||
.code32
|
||||
/* Restore Everything */
|
||||
popl %edi
|
||||
popl %esi
|
||||
popl %ebx
|
||||
ret
|
||||
|
||||
/**************************************************************************
|
||||
MEM88 - Determine size of extended memory
|
||||
**************************************************************************/
|
||||
.globl mem88
|
||||
mem88:
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
call _prot_to_real
|
||||
.code16
|
||||
|
||||
movb $0x88, %ah
|
||||
int $0x15
|
||||
andl $0xffff, %eax
|
||||
|
||||
data32 call _real_to_prot
|
||||
.code32
|
||||
|
||||
/* Restore Everything */
|
||||
popl %edi
|
||||
popl %esi
|
||||
popl %ebx
|
||||
ret
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
BASEMEMSIZE - Get size of the conventional (base) memory
|
||||
**************************************************************************/
|
||||
.globl basememsize
|
||||
basememsize:
|
||||
call _prot_to_real
|
||||
.code16
|
||||
int $0x12
|
||||
movw %ax,%cx
|
||||
DATA32 call _real_to_prot
|
||||
.code32
|
||||
movw %cx,%ax
|
||||
ret
|
||||
|
||||
/**************************************************************************
|
||||
_REAL_TO_PROT - Go from REAL mode to Protected Mode
|
||||
**************************************************************************/
|
||||
.globl _real_to_prot
|
||||
_real_to_prot:
|
||||
.code16
|
||||
cli
|
||||
cs
|
||||
addr32 lgdt gdt_48 - RELOC
|
||||
movl %cr0,%eax
|
||||
orl $CR0_PE,%eax
|
||||
movl %eax,%cr0 /* turn on protected mode */
|
||||
|
||||
/* flush prefetch queue, and reload %cs:%eip */
|
||||
data32 ljmp $KERN_CODE_SEG,$1f
|
||||
1:
|
||||
.code32
|
||||
/* reload other segment registers */
|
||||
movl $KERN_DATA_SEG,%eax
|
||||
movl %eax,%ds
|
||||
movl %eax,%es
|
||||
movl %eax,%ss
|
||||
addl $RELOC,%esp /* Fix up stack pointer */
|
||||
xorl %eax,%eax
|
||||
movl %eax,%fs
|
||||
movl %eax,%gs
|
||||
popl %eax /* Fix up return address */
|
||||
addl $RELOC,%eax
|
||||
pushl %eax
|
||||
|
||||
/* switch to protected mode idt */
|
||||
cs
|
||||
lidt idt_48
|
||||
ret
|
||||
|
||||
/**************************************************************************
|
||||
_PROT_TO_REAL - Go from Protected Mode to REAL Mode
|
||||
**************************************************************************/
|
||||
.globl _prot_to_real
|
||||
_prot_to_real:
|
||||
.code32
|
||||
popl %eax
|
||||
subl $RELOC,%eax /* Adjust return address */
|
||||
pushl %eax
|
||||
subl $RELOC,%esp /* Adjust stack pointer */
|
||||
ljmp $REAL_CODE_SEG,$1f- RELOC /* jump to a 16 bit segment */
|
||||
1:
|
||||
.code16
|
||||
/* clear the PE bit of CR0 */
|
||||
movl %cr0,%eax
|
||||
andl $0!CR0_PE,%eax
|
||||
movl %eax,%cr0
|
||||
|
||||
/* make intersegment jmp to flush the processor pipeline
|
||||
* and reload %cs:%eip (to clear upper 16 bits of %eip).
|
||||
*/
|
||||
data32 ljmp $(RELOC)>>4,$2f- RELOC
|
||||
2:
|
||||
/* we are in real mode now
|
||||
* set up the real mode segment registers : %ds, $ss, %es
|
||||
*/
|
||||
movw %cs,%ax
|
||||
movw %ax,%ds
|
||||
movw %ax,%es
|
||||
movw %ax,%ss
|
||||
movw %ax,%fs
|
||||
movw %ax,%gs
|
||||
|
||||
/* Switch to the real mode idt */
|
||||
cs
|
||||
addr32 lidt idt_real - RELOC
|
||||
|
||||
sti
|
||||
data32 ret /* There is a 32 bit return address on the stack */
|
||||
.code32
|
||||
|
||||
idt_real:
|
||||
.word 0x400 # idt limit = 256
|
||||
.word 0, 0
|
||||
idt_48:
|
||||
.word 0 # idt limit = 0
|
||||
.word 0, 0 # idt base = 0L
|
||||
gdt_48:
|
||||
.word 0x28 # gdt limit=40,
|
||||
# (5 GDT entries)
|
||||
.long gdt # gdt base
|
||||
|
||||
# Descriptor tables
|
||||
# These need to be in a seperate section so I can be
|
||||
# certain later activities dont stomp them
|
||||
.section .nokill, "awx", @progbits
|
||||
gdt:
|
||||
.word 0, 0, 0, 0 # dummy
|
||||
|
||||
/* 16 bit real mode code segment */
|
||||
.word 0xffff,(RELOC&0xffff)
|
||||
.byte (RELOC>>16),0x9b,0x00,(RELOC>>24)
|
||||
|
||||
.word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb)
|
||||
.word 0 # base address = 0
|
||||
.word 0x9A00 # code read/exec
|
||||
.word 0x00CF # granularity = 4096, 386
|
||||
# (+5th nibble of limit)
|
||||
|
||||
.word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb)
|
||||
.word 0 # base address = 0
|
||||
.word 0x9200 # data read/write
|
||||
.word 0x00CF # granularity = 4096, 386
|
||||
# (+5th nibble of limit)
|
||||
|
||||
/* 16 bit real mode data segment */
|
||||
.word 0xffff,(RELOC&0xffff)
|
||||
.byte (RELOC>>16),0x93,0x00,(RELOC>>24)
|
||||
|
||||
|
82
util/mkelfImage/elf32-i386/linuxbios_tables.h
Normal file
82
util/mkelfImage/elf32-i386/linuxbios_tables.h
Normal file
|
@ -0,0 +1,82 @@
|
|||
#ifndef LINUXBIOS_TABLES_H
|
||||
#define LINUXBIOS_TABLES_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* The linuxbios table information is for conveying information
|
||||
* from the firmware to the loaded OS image. Primarily this
|
||||
* is expected to be information that cannot be discovered by
|
||||
* other means, such as quering the hardware directly.
|
||||
*
|
||||
* All of the information should be Position Independent Data.
|
||||
* That is it should be safe to relocated any of the information
|
||||
* without it's meaning/correctnes changing. For table that
|
||||
* can reasonably be used on multiple architectures the data
|
||||
* size should be fixed. This should ease the transition between
|
||||
* 32 bit and 64 bit architectures etc.
|
||||
*
|
||||
* The completeness test for the information in this table is:
|
||||
* - Can all of the hardware be detected?
|
||||
* - Are the per motherboard constants available?
|
||||
* - Is there enough to allow a kernel to run that was written before
|
||||
* a particular motherboard is constructed? (Assuming the kernel
|
||||
* has drivers for all of the hardware but it does not have
|
||||
* assumptions on how the hardware is connected together).
|
||||
*
|
||||
* With this test it should be straight forward to determine if a
|
||||
* table entry is required or not. This should remove much of the
|
||||
* long term compatibility burden as table entries which are
|
||||
* irrelevant or have been replaced by better alternatives may be
|
||||
* dropped. Of course it is polite and expidite to include extra
|
||||
* table entries and be backwards compatible, but it is not required.
|
||||
*/
|
||||
|
||||
|
||||
struct lb_header
|
||||
{
|
||||
uint8_t signature[4]; /* LBIO */
|
||||
uint32_t header_bytes;
|
||||
uint32_t header_checksum;
|
||||
uint32_t table_bytes;
|
||||
uint32_t table_checksum;
|
||||
uint32_t table_entries;
|
||||
};
|
||||
|
||||
/* Every entry in the boot enviroment list will correspond to a boot
|
||||
* info record. Encoding both type and size. The type is obviously
|
||||
* so you can tell what it is. The size allows you to skip that
|
||||
* boot enviroment record if you don't know what it easy. This allows
|
||||
* forward compatibility with records not yet defined.
|
||||
*/
|
||||
struct lb_record {
|
||||
uint32_t tag; /* tag ID */
|
||||
uint32_t size; /* size of record (in bytes) */
|
||||
};
|
||||
|
||||
#define LB_TAG_UNUSED 0x0000
|
||||
|
||||
#define LB_TAG_MEMORY 0x0001
|
||||
|
||||
struct lb_memory_range {
|
||||
uint64_t start;
|
||||
uint64_t size;
|
||||
uint32_t type;
|
||||
#define LB_MEM_RAM 1
|
||||
#define LB_MEM_RESERVED 2
|
||||
|
||||
};
|
||||
|
||||
struct lb_memory {
|
||||
uint32_t tag;
|
||||
uint32_t size;
|
||||
struct lb_memory_range map[0];
|
||||
};
|
||||
|
||||
#define LB_TAG_HWRPB 0x0002
|
||||
struct lb_hwrpb {
|
||||
uint32_t tag;
|
||||
uint32_t size;
|
||||
uint64_t hwrpb;
|
||||
};
|
||||
|
||||
#endif /* LINUXBIOS_TABLES_H */
|
67
util/mkelfImage/elf32-i386/uniform_boot.h
Normal file
67
util/mkelfImage/elf32-i386/uniform_boot.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
#ifndef _LINUX_UNIFORM_BOOT_H
|
||||
#define _LINUX_UNIFORM_BOOT_H
|
||||
|
||||
/* The uniform boot environment information is restricted to
|
||||
* hardware information. In particular for a simple enough machine
|
||||
* all of the environment information should be able to reside in
|
||||
* a rom and not need to be moved. This information is the
|
||||
* information a trivial boot room can pass to linux to let it
|
||||
* run the hardware.
|
||||
*
|
||||
* Also all of the information should be Position Independent Data.
|
||||
* That is it should be safe to relocated any of the information
|
||||
* without it's meaning/correctnes changing. The exception is the
|
||||
* uniform_boot_header with it's two pointers arg & env.
|
||||
*
|
||||
* The addresses in the arg & env pointers must be physical
|
||||
* addresses. A physical address is an address you put in the page
|
||||
* table.
|
||||
*
|
||||
* The Command line is for user policy. Things like the default
|
||||
* root device.
|
||||
*
|
||||
*/
|
||||
|
||||
struct uniform_boot_header
|
||||
{
|
||||
unsigned long header_bytes;
|
||||
unsigned long header_checksum;
|
||||
unsigned long arg;
|
||||
unsigned long arg_bytes;
|
||||
unsigned long env;
|
||||
unsigned long env_bytes;
|
||||
};
|
||||
|
||||
/* Every entry in the boot enviroment list will correspond to a boot
|
||||
* info record. Encoding both type and size. The type is obviously
|
||||
* so you can tell what it is. The size allows you to skip that
|
||||
* boot enviroment record if you don't know what it easy. This allows
|
||||
* forward compatibility with records not yet defined.
|
||||
*/
|
||||
struct ube_record {
|
||||
unsigned long tag; /* tag ID */
|
||||
unsigned long size; /* size of record (in bytes) */
|
||||
unsigned long data[0]; /* data */
|
||||
};
|
||||
|
||||
|
||||
#define UBE_TAG_MEMORY 0x0001
|
||||
|
||||
struct ube_memory_range {
|
||||
unsigned long long start;
|
||||
unsigned long long size;
|
||||
unsigned long type;
|
||||
#define UBE_MEM_RAM 1
|
||||
#define UBE_MEM_RESERVED 2
|
||||
#define UBE_MEM_ACPI 3
|
||||
#define UBE_MEM_NVS 4
|
||||
|
||||
};
|
||||
|
||||
struct ube_memory {
|
||||
unsigned long tag;
|
||||
unsigned long size;
|
||||
struct ube_memory_range map[0];
|
||||
};
|
||||
|
||||
#endif /* _LINUX_UNIFORM_BOOT_H */
|
239
util/mkelfImage/mkelfImage.pl
Normal file
239
util/mkelfImage/mkelfImage.pl
Normal file
|
@ -0,0 +1,239 @@
|
|||
#!/usr/bin/perl -w
|
||||
#
|
||||
# This program is (C) 2000 by Eric Biederman
|
||||
#
|
||||
|
||||
use FileHandle;
|
||||
use Getopt::Long;
|
||||
use Cwd;
|
||||
|
||||
my %params;
|
||||
my $VERSION="";
|
||||
# Hardcoded parameters for now...
|
||||
$params{OBJCOPY}="objcopy";
|
||||
$params{LD}="ld";
|
||||
$params{CC}="gcc";
|
||||
$params{CFLAGS}="-O2";
|
||||
$params{MYDATA}=".";
|
||||
$params{PREFIX}=undef();
|
||||
# Parameters that get set...
|
||||
$params{RAMDISK}="";
|
||||
$params{VMLINUX}="/usr/src/linux/vmlinux";
|
||||
$params{TARGET}="elfImage";
|
||||
$params{ROOT_DEV}='((0x3<<16)| 0)';
|
||||
$params{COMMAND_LINE}='';
|
||||
$params{OUTPUT_FORMAT}='elf32-i386';
|
||||
$params{INITRD_BASE}=0x00800000; # 8MB
|
||||
|
||||
|
||||
sub compile_file
|
||||
{
|
||||
my ($params, $src, $dst) = @_;
|
||||
my ($options, $cmd);
|
||||
$options = "-DDEFAULT_ROOT_DEV='((unsigned short)$params->{ROOT_DEV})'";
|
||||
$options .= " -DDEFAULT_COMMAND_LINE='\"$params->{COMMAND_LINE}\"'";
|
||||
if (defined($params->{RAMDISK_IMAGE_START})) {
|
||||
$options .= " -DDEFAULT_RAMDISK_IMAGE_START=" .
|
||||
"'((unsigned short)$params->{RAMDISK_IMAGE_START})'";
|
||||
}
|
||||
if ($params->{RAMDISK_PROMPT_FLAG}) {
|
||||
$options .= " -DDEFAULT_RAMDISK_PROMPT_FLAG";
|
||||
}
|
||||
if ($params->{RAMDISK_LOAD_FLAG}) {
|
||||
$options .= " -DDEFAULT_RAMDISK_LOAD_FLAG";
|
||||
}
|
||||
$cmd = "$params->{CC} $params->{CFLAGS} $options -c $params->{PREFIX}/$src -o $dst";
|
||||
system($cmd);
|
||||
die "$cmd\nrc = $?" unless ($? == 0);
|
||||
return $dst;
|
||||
}
|
||||
|
||||
sub build_kernel_piggy
|
||||
{
|
||||
my ($params, $section, $src, $dst) = @_;
|
||||
my ($buffer, $elf_sig, $bootsector_sig);
|
||||
|
||||
$fd_in = new FileHandle;
|
||||
$fd_in->open("<$src") or die "Cannot open $src\n";
|
||||
$fd_in->read($buffer, 512) == 512
|
||||
or die "Error reading boot sector of $src";
|
||||
($elf_sig, undef, $bootsector_sig) = unpack('a4a506v1', $buffer);
|
||||
|
||||
if ($elf_sig eq "\x7FELF") {
|
||||
# It's an elf image
|
||||
# Assume the input file uses contiguous memory...
|
||||
system("objcopy ${src} -O binary ${dst}.obj");
|
||||
die "rc = $?" unless ($? == 0);
|
||||
}
|
||||
elsif ($bootsector_sig == 0xAA55) {
|
||||
# It's an x86 boot sector
|
||||
# Pull out the kernel...
|
||||
my ($setupsects, $flags, $syssize, $swapdev,
|
||||
$ramsize, $vidmode, $rootdev);
|
||||
(undef, $setupsects, $flags, $syssize, $swapdev, $ramsize,
|
||||
$vidmode, $rootdev) = unpack('a497Cv6', $buffer);
|
||||
my $fd_out = new FileHandle;
|
||||
$fd_out->open(">${dst}.obj") or die "Cannot open ${dst}.obj";
|
||||
$fd_in->seek(512 + (512*$setupsects), 0);
|
||||
while ($fd_in->read($buffer, 8192) > 0) {
|
||||
$fd_out->print($buffer);
|
||||
}
|
||||
$fd_in->close();
|
||||
$fd_out->close();
|
||||
}
|
||||
else {
|
||||
die "Unkown kernel file type";
|
||||
}
|
||||
|
||||
my $fd = new FileHandle;
|
||||
$fd->open("| $params->{LD} -r -o ${dst} -T /dev/fd/0 -b binary ${dst}.obj");
|
||||
$fd->print( << "EOSCRIPT");
|
||||
OUTPUT_FORMAT($params->{OUTPUT_FORMAT});
|
||||
SECTIONS {
|
||||
.$section : {
|
||||
${section}_data = . ;
|
||||
*(*)
|
||||
${section}_data_end = . ;
|
||||
}
|
||||
}
|
||||
EOSCRIPT
|
||||
$fd->close();
|
||||
die "rc = $?" unless ($? == 0);
|
||||
unlink("${dst}.obj");
|
||||
return $dst;
|
||||
}
|
||||
|
||||
sub build_ramdisk_piggy
|
||||
{
|
||||
# Assumes input file uses continguos memory...
|
||||
my ($params, $section, $src, $dst) = @_;
|
||||
my $fd = new FileHandle;
|
||||
if (defined($src) && ($src ne "")) {
|
||||
system("cp ${src} ${dst}.obj");
|
||||
}
|
||||
else {
|
||||
# Now create the dummy file
|
||||
$fd->open(">${dst}.obj") or die "${dst}.obj: $!";
|
||||
$fd->close();
|
||||
}
|
||||
$fd->open("| $params->{LD} -r -o ${dst} -T /dev/fd/0 -b binary ${dst}.obj");
|
||||
$fd->print( << "EOSCRIPT");
|
||||
OUTPUT_FORMAT($params->{OUTPUT_FORMAT});
|
||||
SECTIONS {
|
||||
.$section : {
|
||||
${section}_data = . ;
|
||||
*(*)
|
||||
${section}_data_end = . ;
|
||||
}
|
||||
}
|
||||
EOSCRIPT
|
||||
$fd->close();
|
||||
die "rc = $?" unless ($? == 0);
|
||||
unlink("${dst}.obj");
|
||||
return $dst;
|
||||
}
|
||||
|
||||
sub build_elf_image
|
||||
{
|
||||
my ($params, $dst, @srcs) = @_;
|
||||
my $lscript = "mkelfImage.lds";
|
||||
my $fd = new FileHandle;
|
||||
$fd->open(">$lscript");
|
||||
$fd->print("initrd_base = $params->{INITRD_BASE};\n");
|
||||
$fd->close();
|
||||
my $script = "$params->{PREFIX}/elfImage.lds";
|
||||
my $cmd = "$params->{LD} -o ${dst} -T $script " . join(" ", @srcs);
|
||||
system("$cmd");
|
||||
die "rc = $?" unless ($? == 0);
|
||||
unlink("${dst}.obj",$lscript);
|
||||
return $dst;
|
||||
}
|
||||
|
||||
sub build
|
||||
{
|
||||
my ($params) = @_;
|
||||
my @objects;
|
||||
my $tempdir=getcwd();
|
||||
|
||||
$params->{PREFIX} = "$params->{MYDATA}/$params->{OUTPUT_FORMAT}";
|
||||
push(@objects,build_kernel_piggy($params, "kernel",
|
||||
$params->{VMLINUX}, "$tempdir/kernel_piggy_$$.o"));
|
||||
|
||||
push(@objects, build_ramdisk_piggy($params, "ramdisk",
|
||||
$params->{RAMDISK}, "$tempdir/ramdisk_piggy_$$.o"));
|
||||
|
||||
push(@objects, compile_file($params, "convert_params.c",
|
||||
"$tempdir/convert_params_$$.o"));
|
||||
push(@objects, compile_file($params, "head.S",
|
||||
"$tempdir/head_$$.o"));
|
||||
build_elf_image($params, $params->{TARGET}, @objects);
|
||||
unlink(@objects);
|
||||
|
||||
}
|
||||
|
||||
sub main
|
||||
{
|
||||
my ($params) = @_;
|
||||
my $wantversion;
|
||||
GetOptions('command-line=s' => \$params->{COMMAND_LINE},
|
||||
'ramdisk=s' => \$params->{RAMDISK},
|
||||
'vmlinux=s' => \$params->{VMLINUX},
|
||||
'kernel=s' => \$params->{VMLINUX},
|
||||
'root-dev=s' => \$params->{ROOT_DEV},
|
||||
'output=s' => \$params->{TARGET},
|
||||
'version' => \$wantversion,
|
||||
'ramdisk-base=i' =>\$params->{INITRD_BASE},
|
||||
# FIXME figure out what the old RAMDISK_IMAGE flags are about.
|
||||
#'ramdisk-image-start=i' => \$params{RAMDISK_IMAGE_START},
|
||||
#'ramdisk-prompt-flag!' => \$params{RAMDISK_PROMPT_FLAG},
|
||||
#'ramdisk-load-flag!' => \$params{RAMDISK_LOAD_FLAG},
|
||||
);
|
||||
if (defined($wantversion) && $wantversion) {
|
||||
print "$0 $VERSION\n";
|
||||
exit(0);
|
||||
}
|
||||
build($params);
|
||||
}
|
||||
|
||||
main(\%params, @ARGV);
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
mkelfImage - make an elf network bootable image for linux
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<mkelfImage> [--command-line=I<command line>] [--kernel=I<path to vmlinux>] [--ramdisk=I<path to ramdisk>] [--output=I<file>] [--ramdisk-base=<start addr>]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<mkelfImage> is a program that makes a elf boot image for linux kernel
|
||||
images. The image should work with any i386 multiboot compliant boot loader,
|
||||
an ELF bootloader that passes no options, a loader compliant with the linuxBIOS
|
||||
elf booting spec or with the linux kexec kernel patch. A key feature
|
||||
here is that nothing relies upon BIOS, but they are made when
|
||||
necessary useful for systems running linuxbios.
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
Not all kernel parameters can be passed with the multiboot image format.
|
||||
ip configuration is not automatically passed to a node.
|
||||
The ramdisk base is hard coded to 8MB by default.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
The exec kernel patch.
|
||||
LinusBIOS.
|
||||
etherboot.
|
||||
The multiboot standard.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
mkelfImage is under the GNU Public License version 2
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Eric Biederman <ebiederman@lnxi.com>
|
||||
|
Loading…
Add table
Reference in a new issue