diff options
-rw-r--r-- | util/cbfstool/cbfs-payload-linux.c | 5 | ||||
-rw-r--r-- | util/cbfstool/linux.h | 6 | ||||
-rw-r--r-- | util/cbfstool/linux_trampoline.c | 44 | ||||
-rw-r--r-- | util/cbfstool/linux_trampoline.h | 40 |
4 files changed, 79 insertions, 16 deletions
diff --git a/util/cbfstool/cbfs-payload-linux.c b/util/cbfstool/cbfs-payload-linux.c index 33a5e1afb1..9e9a8741d0 100644 --- a/util/cbfstool/cbfs-payload-linux.c +++ b/util/cbfstool/cbfs-payload-linux.c @@ -302,9 +302,8 @@ int parse_bzImage_to_payload(const struct buffer *input, PAYLOAD_SEGMENT_CODE, kernel_base); /* trampoline */ - uint64_t entrypoint = 0x40000; /*TODO: any better place? */ bzp_output_segment(&bzp, &bzp.trampoline, - PAYLOAD_SEGMENT_CODE, entrypoint); + PAYLOAD_SEGMENT_CODE, TRAMPOLINE_ENTRY_LOC); /* cmdline */ bzp_output_segment(&bzp, &bzp.cmdline, @@ -315,7 +314,7 @@ int parse_bzImage_to_payload(const struct buffer *input, PAYLOAD_SEGMENT_DATA, initrd_base); /* Terminating entry segment. */ - bzp_output_segment(&bzp, NULL, PAYLOAD_SEGMENT_ENTRY, entrypoint); + bzp_output_segment(&bzp, NULL, PAYLOAD_SEGMENT_ENTRY, TRAMPOLINE_ENTRY_LOC); /* Set size of buffer taking into account potential compression. */ buffer_set_size(&bzp.output, bzp.offset); diff --git a/util/cbfstool/linux.h b/util/cbfstool/linux.h index 20837e3707..ae747e6c5e 100644 --- a/util/cbfstool/linux.h +++ b/util/cbfstool/linux.h @@ -26,17 +26,13 @@ */ #include <stdint.h> +#include "linux_trampoline.h" typedef uint8_t u8; typedef uint16_t u16; typedef uint32_t u32; typedef uint64_t u64; -#define LINUX_PARAM_LOC 0x90000 -#define COMMAND_LINE_LOC 0x91000 -#define GDT_LOC 0x92000 -#define STACK_LOC 0x93000 - #define E820MAX 32 /* number of entries in E820MAP */ struct e820entry { unsigned long long addr; /* start of memory segment */ diff --git a/util/cbfstool/linux_trampoline.c b/util/cbfstool/linux_trampoline.c index 368d63a807..649bb64b0e 100644 --- a/util/cbfstool/linux_trampoline.c +++ b/util/cbfstool/linux_trampoline.c @@ -24,12 +24,13 @@ */ .code32 .data + +#include "linux_trampoline.h" #define HEADER_SIG 0x4f49424c // LBIO little endian #define CB_TAG_FORWARD 0x11 #define CB_TAG_MEMORY 0x1 #define CB_TAG_FRAMEBUFFER 0x12 -#define LINUX_PARAM_LOC 0x90000 #define E820_NR_OFFSET 0x1e8 #define LINUX_ENTRY_OFFSET 0x214 #define E820_OFFSET 0x2d0 @@ -101,6 +102,30 @@ add 4(%ebx), %ebx dec %ecx jnz .tableScan +/* Setup basic code and data segment selectors for Linux +** +** Flat code segment descriptor: +** selector: 0x10 +** base : 0x00000000 +** limit : 0xFFFFFFFF +** type : code, execute, read +** +** Flat data segment descriptor: +** selector: 0x18 +** base : 0x00000000 +** limit : 0xFFFFFFFF +** type : data, read/write +** +** Use TRAMPOLINE_ENTRY_LOC as a scratchpad. +*/ +mov $TRAMPOLINE_ENTRY_LOC, %eax +sgdt (%eax) +mov 2(%eax), %ebx +movl $0x0000ffff, 16(%ebx) +movl $0x00cf9b00, 20(%ebx) +movl $0x0000ffff, 24(%ebx) +movl $0x00cf9300, 28(%ebx) + /* finally: jump to kernel */ mov $LINUX_PARAM_LOC, %esi jmp *(LINUX_PARAM_LOC + LINUX_ENTRY_OFFSET) @@ -128,13 +153,16 @@ trampoline_size: const unsigned char trampoline[] = { 0xfc, 0x31, 0xd2, 0xb9, 0x00, 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x01, 0x00, 0x01, 0xcb, 0x8b, 0x01, 0x3d, 0x4c, 0x42, 0x49, 0x4f, 0x74, 0x07, 0x83, 0xc1, 0x10, 0x39, 0xcb, 0x75, 0xe9, 0x39, -0xcb, 0x74, 0x60, 0x8b, 0x59, 0x04, 0x01, 0xcb, 0x8b, 0x49, 0x14, 0x83, 0x3b, 0x11, 0x75, 0x05, -0x8b, 0x4b, 0x08, 0xeb, 0xd3, 0x83, 0x3b, 0x01, 0x75, 0x33, 0x8b, 0x43, 0x04, 0x83, 0xe8, 0x08, -0xc1, 0xe8, 0x02, 0x3d, 0xa0, 0x00, 0x00, 0x00, 0x7e, 0x05, 0xb8, 0xa0, 0x00, 0x00, 0x00, 0x89, -0xc6, 0xbf, 0x05, 0x00, 0x00, 0x00, 0xf7, 0xf7, 0xa3, 0xe8, 0x01, 0x09, 0x00, 0x89, 0xf0, 0x91, -0x8d, 0x73, 0x08, 0xbf, 0xd0, 0x02, 0x09, 0x00, 0xf3, 0xa5, 0x91, 0xeb, 0x05, 0x83, 0x3b, 0x12, -0x75, 0x00, 0x03, 0x5b, 0x04, 0x49, 0x75, 0xb3, 0xbe, 0x00, 0x00, 0x09, 0x00, 0xff, 0x25, 0x14, -0x02, 0x09, 0x00, 0xf4, 0xeb, 0xfd +0xcb, 0x0f, 0x84, 0x85, 0x00, 0x00, 0x00, 0x8b, 0x59, 0x04, 0x01, 0xcb, 0x8b, 0x49, 0x14, 0x83, +0x3b, 0x11, 0x75, 0x05, 0x8b, 0x4b, 0x08, 0xeb, 0xcf, 0x83, 0x3b, 0x01, 0x75, 0x33, 0x8b, 0x43, +0x04, 0x83, 0xe8, 0x08, 0xc1, 0xe8, 0x02, 0x3d, 0xa0, 0x00, 0x00, 0x00, 0x7e, 0x05, 0xb8, 0xa0, +0x00, 0x00, 0x00, 0x89, 0xc6, 0xbf, 0x05, 0x00, 0x00, 0x00, 0xf7, 0xf7, 0xa3, 0xe8, 0x01, 0x09, +0x00, 0x89, 0xf0, 0x91, 0x8d, 0x73, 0x08, 0xbf, 0xd0, 0x02, 0x09, 0x00, 0xf3, 0xa5, 0x91, 0xeb, +0x05, 0x83, 0x3b, 0x12, 0x75, 0x00, 0x03, 0x5b, 0x04, 0x49, 0x75, 0xb3, 0xb8, 0x00, 0x00, 0x04, +0x00, 0x0f, 0x01, 0x00, 0x8b, 0x58, 0x02, 0xc7, 0x43, 0x10, 0xff, 0xff, 0x00, 0x00, 0xc7, 0x43, +0x14, 0x00, 0x9b, 0xcf, 0x00, 0xc7, 0x43, 0x18, 0xff, 0xff, 0x00, 0x00, 0xc7, 0x43, 0x1c, 0x00, +0x93, 0xcf, 0x00, 0xbe, 0x00, 0x00, 0x09, 0x00, 0xff, 0x25, 0x14, 0x02, 0x09, 0x00, 0xf4, 0xeb, +0xfd }; const void * const trampoline_start = &trampoline; diff --git a/util/cbfstool/linux_trampoline.h b/util/cbfstool/linux_trampoline.h new file mode 100644 index 0000000000..ed5b824825 --- /dev/null +++ b/util/cbfstool/linux_trampoline.h @@ -0,0 +1,40 @@ +/* + * This file is part of coreboot.. + * + * Based on work by Patrick Georgi <patrick@georgi-clan.de> + * Copyright 2014 Curt Brune <curt@cumulusnetworks.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 + */ + +/* + * This file contains #define constants used by both the Linux + * trampoline C-code and assembly language code. As such it can only + * contain preprocessor macros. Do not inlucde C language + * declarations in this file. + */ + +#ifndef LINUX_TRAMPOLINE_H__ +#define LINUX_TRAMPOLINE_H__ + +/* + * Trampoline entry point + * TODO: any better place? + */ +#define TRAMPOLINE_ENTRY_LOC 0x40000 + +#define LINUX_PARAM_LOC 0x90000 +#define COMMAND_LINE_LOC 0x91000 + +#endif /* LINUX_TRAMPOLINE_H__ */ |