+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2003 Eric W. Biederman <ebiederm@xmission.com>
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
+ */
+
#include <console/console.h>
#include <part/fallback_boot.h>
#include <boot/elf.h>
#include <boot/elf_boot.h>
-#include <boot/linuxbios_tables.h>
+#include <boot/coreboot_tables.h>
#include <ip_checksum.h>
#include <stream/read_bytes.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
-/* Maximum physical address we can use for the linuxBIOS bounce buffer.
+/* Maximum physical address we can use for the coreboot bounce buffer.
*/
#ifndef MAX_ADDR
#define MAX_ADDR -1UL
memcpy(n_desc, buff, 2);
}
if (checksum != cb->ip_checksum) {
- printk_err("Image checksum: %04x != computed checksum: %04x\n",
+ printk_err("Image checksum: %04x != computed checksum: %04lx\n",
cb->ip_checksum, checksum);
}
return checksum == cb->ip_checksum;
* a machine, and implementing general relocation is hard.
*
* The solution:
- * - Allocate a buffer twice the size of the linuxBIOS image.
- * - Anything that would overwrite linuxBIOS copy into the lower half of
+ * - Allocate a buffer twice the size of the coreboot image.
+ * - Anything that would overwrite coreboot copy into the lower half of
* the buffer.
- * - After loading an ELF image copy linuxBIOS to the upper half of the
+ * - After loading an ELF image copy coreboot to the upper half of the
* buffer.
* - Then jump to the loaded image.
*
* Benefits:
* - Nearly arbitrary standalone executables can be loaded.
- * - LinuxBIOS is preserved, so it can be returned to.
+ * - Coreboot is preserved, so it can be returned to.
* - The implementation is still relatively simple,
* and much simpler then the general case implemented in kexec.
*
unsigned long buffer;
int i;
lb_size = (unsigned long)(&_eram_seg - &_ram_seg);
- /* Double linuxBIOS size so I have somewhere to place a copy to return to */
+ /* Double coreboot size so I have somewhere to place a copy to return to */
lb_size = lb_size + lb_size;
mem_entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
buffer = 0;
unsigned long tbuffer;
if (mem->map[i].type != LB_MEM_RAM)
continue;
- if (mem->map[i].start > MAX_ADDR)
+ if (unpack_lb64(mem->map[i].start) > MAX_ADDR)
continue;
- if (mem->map[i].size < lb_size)
+ if (unpack_lb64(mem->map[i].size) < lb_size)
continue;
- mstart = mem->map[i].start;
+ mstart = unpack_lb64(mem->map[i].start);
msize = MAX_ADDR - mstart +1;
- if (msize > mem->map[i].size)
- msize = mem->map[i].size;
+ if (msize > unpack_lb64(mem->map[i].size))
+ msize = unpack_lb64(mem->map[i].size);
mend = mstart + msize;
tbuffer = mend - lb_size;
if (tbuffer < buffer)
{
struct verify_callback *cb_chain;
unsigned char *note, *end;
- char *program, *version;
+ unsigned char *program, *version;
cb_chain = 0;
note = header + offset;
uint64_t mstart, mend;
uint32_t mtype;
mtype = mem->map[i].type;
- mstart = mem->map[i].start;
- mend = mstart + mem->map[i].size;
+ mstart = unpack_lb64(mem->map[i].start);
+ mend = mstart + unpack_lb64(mem->map[i].size);
if ((mtype == LB_MEM_RAM) && (start < mend) && (end > mstart)) {
break;
}
+ if ((mtype == LB_MEM_TABLE) && (start < mend) && (end > mstart)) {
+ printk_err("Payload is overwriting Coreboot tables.\n");
+ break;
+ }
}
if (i == mem_entries) {
printk_err("No matching ram area found for range:\n");
uint64_t mstart, mend;
uint32_t mtype;
mtype = mem->map[i].type;
- mstart = mem->map[i].start;
- mend = mstart + mem->map[i].size;
+ mstart = unpack_lb64(mem->map[i].start);
+ mend = mstart + unpack_lb64(mem->map[i].size);
printk_err(" [0x%016lx, 0x%016lx) %s\n",
(unsigned long)mstart,
(unsigned long)mend,
static void relocate_segment(unsigned long buffer, struct segment *seg)
{
- /* Modify all segments that want to load onto linuxBIOS
+ /* Modify all segments that want to load onto coreboot
* to load onto the bounce buffer instead.
*/
unsigned long lb_start = (unsigned long)&_ram_seg;
start = seg->s_addr;
middle = start + seg->s_filesz;
end = start + seg->s_memsz;
- /* I don't conflict with linuxBIOS so get out of here */
+ /* I don't conflict with coreboot so get out of here */
if ((end <= lb_start) || (start >= lb_end))
return;
start, middle, end);
/* Slice off a piece at the beginning
- * that doesn't conflict with linuxBIOS.
+ * that doesn't conflict with coreboot.
*/
if (start < lb_start) {
struct segment *new;
}
/* Slice off a piece at the end
- * that doesn't conflict with linuxBIOS
+ * that doesn't conflict with coreboot
*/
if (end > lb_end) {
unsigned long len = lb_end - start;
seg->phdr_next->phdr_prev = new;
seg->phdr_next = new;
- /* compute the new value of end */
- end = start + len;
-
printk_spew(" late: [0x%016lx, 0x%016lx, 0x%016lx)\n",
new->s_addr,
new->s_addr + new->s_filesz,
end = dest + ptr->s_memsz;
middle = dest + ptr->s_filesz;
start_offset = ptr->s_offset;
+ /* Ignore s_offset if I have a pure bss segment */
+ if (ptr->s_filesz == 0) {
+ start_offset = offset;
+ }
printk_spew("[ 0x%016lx, %016lx, 0x%016lx) <- %016lx\n",
(unsigned long)dest,
skip_bytes = start_offset - offset;
if (skip_bytes &&
((result = stream_skip(skip_bytes)) != skip_bytes)) {
- printk_err("ERROR: Skip of %ld bytes skiped %ld bytes\n",
+ printk_err("ERROR: Skip of %ld bytes skipped %ld bytes\n",
skip_bytes, result);
goto out;
}
/* Zero the extra bytes between middle & end */
if (middle < end) {
printk_debug("Clearing Segment: addr: 0x%016lx memsz: 0x%016lx\n",
- (unsigned long)middle, end - middle);
+ (unsigned long)middle, (unsigned long)(end - middle));
/* Zero the extra bytes */
memset(middle, 0, end - middle);
struct verify_callback *cb_chain;
unsigned long bounce_buffer;
- /* Find a bounce buffer so I can load to linuxBIOS's current location */
+ /* Find a bounce buffer so I can load to coreboot's current location */
bounce_buffer = get_bounce_buffer(mem);
if (!bounce_buffer) {
printk_err("Could not find a bounce buffer...\n");
/* Reset to booting from this image as late as possible */
boot_successful();
- printk_debug("Jumping to boot code at 0x%x\n", entry);
+ printk_debug("Jumping to boot code at %p\n", entry);
post_code(0xfe);
/* Jump to kernel */
int i, result;
result = 0;
- printk_info("\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");
+ printk_debug("\nelfboot: Attempting to load payload.\n");
post_code(0xf8);
if (stream_init() < 0) {
for(i = 0; i < ELF_HEAD_SIZE - (sizeof(Elf_ehdr) + sizeof(Elf_phdr)); i+=16) {
ehdr = (Elf_ehdr *)(&header[i]);
if (memcmp(ehdr->e_ident, ELFMAG, 4) != 0) {
- printk_spew("NO header at %d\n", i);
+ printk_debug("No header at %d\n", i);
continue;
}
- printk_debug("Found ELF candiate at offset %d\n", i);
+ printk_debug("Found ELF candidate at offset %d\n", i);
/* Sanity check the elf header */
if ((ehdr->e_type == ET_EXEC) &&
elf_check_arch(ehdr) &&
}
ehdr = 0;
}
- printk_spew("header_offset is %d\n", header_offset);
+ printk_debug("header_offset is %d\n", header_offset);
if (header_offset == -1) {
goto out;
}
- printk_spew("Try to load at offset 0x%x\n", header_offset);
+ printk_debug("Try to load at offset 0x%x\n", header_offset);
result = elfload(mem,
header + header_offset , ELF_HEAD_SIZE - header_offset);
out:
/* Shutdown the stream device */
stream_fini();
- printk_err("Cannot Load ELF Image\n");
+ printk_err("Can not load ELF Image.\n");
post_code(0xff);
}