summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--2ndbootloader.lds37
-rw-r--r--Android.mk52
-rw-r--r--bootimg.h96
-rw-r--r--bootstub.c59
-rw-r--r--bootstub.h13
5 files changed, 239 insertions, 18 deletions
diff --git a/2ndbootloader.lds b/2ndbootloader.lds
new file mode 100644
index 0000000..547692d
--- /dev/null
+++ b/2ndbootloader.lds
@@ -0,0 +1,37 @@
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x10F00000; /* bootstub entry in DRAM */
+ .text.head : {
+ _head = . ;
+ *(.text.head)
+ _ehead = . ;
+ }
+ .text : {
+ _text = .; /* Text */
+ *(.text)
+ *(.text.*)
+ _etext = . ;
+ }
+ .rodata : {
+ _rodata = . ;
+ *(.rodata) /* read-only data */
+ *(.rodata.*)
+ _erodata = . ;
+ }
+ .data : {
+ _data = . ;
+ *(.data)
+ *(.data.*)
+ _edata = . ;
+ }
+ .bss : {
+ _bss = . ;
+ *(.bss)
+ *(.bss.*)
+ *(COMMON)
+ _end = . ;
+ }
+}
diff --git a/Android.mk b/Android.mk
index 73f89d6..a8ab4d8 100644
--- a/Android.mk
+++ b/Android.mk
@@ -53,3 +53,55 @@ CHECK_BOOTSTUB_SIZE : $(bootstub_bin)
$(bootstub_full) : CHECK_BOOTSTUB_SIZE
@echo "Generating bootstub: $@"
$(hide) cat $(bootstub_bin) /dev/zero | dd bs=$(BOOTSTUB_SIZE) count=1 > $@
+
+# build specific bootstub for GPT/AOSP image support
+include $(CLEAR_VARS)
+
+# First compile 2ndbootloader.bin
+
+LOCAL_CC := gcc
+LOCAL_SRC_FILES := bootstub.c head.S e820_bios.S sfi.c ssp-uart.c imr_toc.c spi-uart.c
+ANDROID_TOOLCHAIN_FLAGS := -m32 -ffreestanding
+LOCAL_CFLAGS := $(ANDROID_TOOLCHAIN_FLAGS) -Wall -O1 -DCMDLINE_SIZE=${CMDLINE_SIZE} -DBUILD_RAMDUMP
+LOCAL_MODULE := 2ndbootloader.bin
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_FORCE_STATIC_EXECUTABLE := true
+
+head.o : PRIVATE_CFLAGS := -D__ASSEMBLY__
+
+include $(BUILD_SYSTEM)/binary.mk
+
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_GLOBAL_CFLAGS := $(LOCAL_CFLAGS)
+$(LOCAL_BUILT_MODULE) : PRIVATE_ELF_FILE := $(intermediates)/$(PRIVATE_MODULE).elf
+$(LOCAL_BUILT_MODULE) : PRIVATE_LINK_SCRIPT := $(LOCAL_PATH)/2ndbootloader.lds
+$(LOCAL_BUILT_MODULE) : BOOTSTUB_OBJS := $(patsubst %.c, %.o , $(LOCAL_SRC_FILES))
+$(LOCAL_BUILT_MODULE) : BOOTSTUB_OBJS := $(patsubst %.S, %.o , $(BOOTSTUB_OBJS))
+$(LOCAL_BUILT_MODULE) : BOOTSTUB_OBJS := $(addprefix $(intermediates)/, $(BOOTSTUB_OBJS))
+
+$(LOCAL_BUILT_MODULE): $(all_objects)
+ @$(mkdir -p $(dir $@)
+ @echo "Generating bootstub $@"
+ $(hide) $(TARGET_LD) \
+ -m elf_i386 \
+ -T $(PRIVATE_LINK_SCRIPT) \
+ $(BOOTSTUB_OBJS) \
+ -o $(PRIVATE_ELF_FILE)
+ $(hide) $(TARGET_OBJCOPY) -O binary -R .note -R .comment -S $(PRIVATE_ELF_FILE) $@
+
+# Then assemble the final bootstub file
+
+bootstub_aosp_bin := $(PRODUCT_OUT)/2ndbootloader.bin
+bootstub_aosp_full := $(PRODUCT_OUT)/2ndbootloader
+
+CHECK_BOOTSTUB_AOSP_SIZE : $(bootstub_aosp_bin)
+ $(hide) ACTUAL_SIZE=`$(call get-file-size,$(bootstub_aosp_bin))`; \
+ if [ "$$ACTUAL_SIZE" -gt "$(BOOTSTUB_SIZE)" ]; then \
+ echo "$(bootstub_aosp_bin): $$ACTUAL_SIZE exceeds size limit of $(BOOTSTUB_SIZE) bytes, aborting."; \
+ exit 1; \
+ fi
+
+$(bootstub_aosp_full) : CHECK_BOOTSTUB_AOSP_SIZE
+ @echo "Generating bootstub $@"
+ $(hide) cat $(bootstub_aosp_bin) /dev/zero | dd bs=$(BOOTSTUB_SIZE) count=1 > $@
diff --git a/bootimg.h b/bootimg.h
new file mode 100644
index 0000000..4c5d00c
--- /dev/null
+++ b/bootimg.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _BOOT_IMAGE_H_
+#define _BOOT_IMAGE_H_
+
+typedef struct boot_img_hdr boot_img_hdr;
+
+#define BOOT_MAGIC "ANDROID!"
+#define BOOT_MAGIC_SIZE 8
+#define BOOT_NAME_SIZE 16
+#define BOOT_ARGS_SIZE 512
+
+struct boot_img_hdr
+{
+ unsigned char magic[BOOT_MAGIC_SIZE];
+
+ unsigned kernel_size; /* size in bytes */
+ unsigned kernel_addr; /* physical load addr */
+
+ unsigned ramdisk_size; /* size in bytes */
+ unsigned ramdisk_addr; /* physical load addr */
+
+ unsigned second_size; /* size in bytes */
+ unsigned second_addr; /* physical load addr */
+
+ unsigned tags_addr; /* physical addr for kernel tags */
+ unsigned page_size; /* flash page size we assume */
+ unsigned unused[2]; /* future expansion: should be 0 */
+
+ unsigned char name[BOOT_NAME_SIZE]; /* asciiz product name */
+ unsigned char cmdline[BOOT_ARGS_SIZE];
+
+ unsigned id[8]; /* timestamp / checksum / sha1 / etc */
+};
+
+/*
+** +-----------------+
+** | boot header | 1 page
+** +-----------------+
+** | kernel | n pages
+** +-----------------+
+** | ramdisk | m pages
+** +-----------------+
+** | second stage | o pages
+** +-----------------+
+**
+** n = (kernel_size + page_size - 1) / page_size
+** m = (ramdisk_size + page_size - 1) / page_size
+** o = (second_size + page_size - 1) / page_size
+**
+** 0. all entities are page_size aligned in flash
+** 1. kernel and ramdisk are required (size != 0)
+** 2. second is optional (second_size == 0 -> no second)
+** 3. load each element (kernel, ramdisk, second) at
+** the specified physical address (kernel_addr, etc)
+** 4. prepare tags at tag_addr. kernel_args[] is
+** appended to the kernel commandline in the tags.
+** 5. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr
+** 6. if second_size != 0: jump to second_addr
+** else: jump to kernel_addr
+*/
+
+boot_img_hdr *mkbootimg(void *kernel, unsigned kernel_size,
+ void *ramdisk, unsigned ramdisk_size,
+ void *second, unsigned second_size,
+ unsigned page_size,
+ unsigned *bootimg_size);
+
+void bootimg_set_cmdline(boot_img_hdr *hdr, const char *cmdline);
+#endif
diff --git a/bootstub.c b/bootstub.c
index e89acce..74b87f9 100644
--- a/bootstub.c
+++ b/bootstub.c
@@ -26,6 +26,7 @@
#include "ssp-uart.h"
#include "mb.h"
#include "sfi.h"
+#include "bootimg.h"
#include <stdint.h>
#include <stddef.h>
@@ -129,6 +130,11 @@ int strncmp(const char *cs, const char *ct, size_t count)
return 0;
}
+static inline int is_image_aosp(unsigned char *magic)
+{
+ return !strncmp((char *)magic, (char *)BOOT_MAGIC, sizeof(BOOT_MAGIC)-1);
+}
+
static void setup_boot_params(struct boot_params *bp, struct setup_header *sh)
{
bp->screen_info.orig_video_mode = 0;
@@ -143,25 +149,43 @@ static void setup_boot_params(struct boot_params *bp, struct setup_header *sh)
static u32 bzImage_setup(struct boot_params *bp, struct setup_header *sh)
{
void *cmdline = (void *)BOOT_CMDLINE_OFFSET;
+ struct boot_img_hdr *aosp = (struct boot_img_hdr *)AOSP_HEADER_ADDRESS;
size_t cmdline_len;
- u8 *initramfs, *ptr = (u8*)BZIMAGE_OFFSET;
+ u8 *initramfs, *ptr;
+
+ if (is_image_aosp(aosp->magic)) {
+ ptr = (u8*)aosp->kernel_addr;
+ cmdline_len = strnlen((const char *)aosp->cmdline, sizeof(aosp->cmdline));
+ /*
+ * Copy the command line to be after bootparams so that it won't be
+ * overwritten by the kernel executable.
+ */
+ memset(cmdline, 0, sizeof(aosp->cmdline));
+ memcpy(cmdline, (const void *)aosp->cmdline, cmdline_len);
- cmdline_len = strnlen((const char *)CMDLINE_OFFSET, CMDLINE_SIZE);
+ bp->hdr.ramdisk_size = aosp->ramdisk_size;
- /*
- * Copy the command line to be after bootparams so that it won't be
- * overwritten by the kernel executable.
- */
- memset(cmdline, 0, CMDLINE_SIZE);
- memcpy(cmdline, (const void *)CMDLINE_OFFSET, cmdline_len);
+ initramfs = (u8 *)aosp->ramdisk_addr;
+ } else {
+ ptr = (u8*)BZIMAGE_OFFSET;
+ cmdline_len = strnlen((const char *)CMDLINE_OFFSET, CMDLINE_SIZE);
+ /*
+ * Copy the command line to be after bootparams so that it won't be
+ * overwritten by the kernel executable.
+ */
+ memset(cmdline, 0, CMDLINE_SIZE);
+ memcpy(cmdline, (const void *)CMDLINE_OFFSET, cmdline_len);
+
+ bp->hdr.ramdisk_size = *(u32 *)INITRD_SIZE_OFFSET;
+
+ initramfs = (u8 *)BZIMAGE_OFFSET + *(u32 *)BZIMAGE_SIZE_OFFSET;
+ }
bp->hdr.cmd_line_ptr = BOOT_CMDLINE_OFFSET;
bp->hdr.cmdline_size = cmdline_len;
- bp->hdr.ramdisk_size = *(u32 *)INITRD_SIZE_OFFSET;
bp->hdr.ramdisk_image = (bp->alt_mem_k*1024 - bp->hdr.ramdisk_size) & 0xFFFFF000;
- initramfs = (u8 *)BZIMAGE_OFFSET + *(u32 *)BZIMAGE_SIZE_OFFSET;
if (*initramfs) {
bs_printk("Relocating initramfs to high memory ...\n");
memcpy((u8*)bp->hdr.ramdisk_image, initramfs, bp->hdr.ramdisk_size);
@@ -449,15 +473,24 @@ static void sec_plat_svcs_setup(void)
int bootstub(void)
{
u32 jmp;
+ struct boot_img_hdr *aosp = (struct boot_img_hdr *)AOSP_HEADER_ADDRESS;
struct boot_params *bp = (struct boot_params *)BOOT_PARAMS_OFFSET;
- struct setup_header *sh = (struct setup_header *)SETUP_HEADER_OFFSET;
+ struct setup_header *sh;
u32 imr_size;
int nr_entries;
- setup_idt();
+ if (is_image_aosp(aosp->magic)) {
+ sh = (struct setup_header *)((unsigned int)aosp->kernel_addr + 0x1F1);
+ /* disable the bs_printk through SPI/UART */
+ *(int *)SPI_UART_SUPPRESSION = 1;
+ *(int *)SPI_TYPE = SPI_2;
+ } else
+ sh = (struct setup_header *)SETUP_HEADER_OFFSET;
+
+ setup_idt();
setup_gdt();
setup_spi();
- bs_printk("Bootstub Version: 1.3 ...\n");
+ bs_printk("Bootstub Version: 1.4 ...\n");
memset(bp, 0, sizeof (struct boot_params));
diff --git a/bootstub.h b/bootstub.h
index 0d4845a..a109c09 100644
--- a/bootstub.h
+++ b/bootstub.h
@@ -19,25 +19,28 @@
#define MID_CPU_CHIP_ANNIEDALE 6
#define MID_CPU_CHIP_OTHER 0xFF
-#define CMDLINE_OFFSET 0x1100000
+#define BASE_ADDRESS 0x01100000
+
+#define CMDLINE_OFFSET BASE_ADDRESS
#define BZIMAGE_SIZE_OFFSET (CMDLINE_OFFSET + CMDLINE_SIZE)
#define INITRD_SIZE_OFFSET (BZIMAGE_SIZE_OFFSET + 4)
#define SPI_UART_SUPPRESSION (INITRD_SIZE_OFFSET + 4)
+#define AOSP_HEADER_ADDRESS 0x10007800
+
#define SPI_TYPE (SPI_UART_SUPPRESSION + 4) /*0:SPI0 1:SPI1*/
#define SPI_0 0
#define SPI_1 1
#define SPI_2 2
-
#define FLAGS_RESERVED_0 (SPI_TYPE + 4)
#define FLAGS_RESERVED_1 (FLAGS_RESERVED_0 + 4)
#define VXE_FW_SIZE_OFFSET (FLAGS_RESERVED_1 + 4)
#define SEC_PLAT_SVCS_SIZE_OFFSET (VXE_FW_SIZE_OFFSET + 4)
#define XEN_SIZE_OFFSET (SEC_PLAT_SVCS_SIZE_OFFSET + 4)
-#define BOOTSTUB_OFFSET 0x1101000
-#define STACK_OFFSET BOOTSTUB_OFFSET
-#define BZIMAGE_OFFSET 0x1103000
+#define BOOTSTUB_OFFSET (BASE_ADDRESS + 0x1000)
+#define STACK_OFFSET 0x10f00000
+#define BZIMAGE_OFFSET (BASE_ADDRESS + 0x3000)
#define SETUP_HEADER_OFFSET (BZIMAGE_OFFSET + 0x1F1)
#define SETUP_HEADER_SIZE (0x0202 + *(unsigned char*)(0x0201+BZIMAGE_OFFSET))