diff options
-rw-r--r-- | 2ndbootloader.lds | 37 | ||||
-rw-r--r-- | Android.mk | 52 | ||||
-rw-r--r-- | bootimg.h | 96 | ||||
-rw-r--r-- | bootstub.c | 59 | ||||
-rw-r--r-- | bootstub.h | 13 |
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 = . ; + } +} @@ -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 @@ -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)); @@ -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)) |