mkbootimg.c revision fc2f7cb69e3f15a616330a69f0675675c68112f3
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* tools/mkbootimg/mkbootimg.c 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Copyright 2007, The Android Open Source Project 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License"); 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** you may not use this file except in compliance with the License. 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** You may obtain a copy of the License at 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** http://www.apache.org/licenses/LICENSE-2.0 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Unless required by applicable law or agreed to in writing, software 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS, 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** See the License for the specific language governing permissions and 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** limitations under the License. 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/ 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h> 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "mincrypt/sha.h" 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "bootimg.h" 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void *load_file(const char *fn, unsigned *_sz) 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *data; 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int sz; 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project data = 0; 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open(fn, O_RDONLY); 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd < 0) return 0; 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sz = lseek(fd, 0, SEEK_END); 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(sz < 0) goto oops; 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(lseek(fd, 0, SEEK_SET) != 0) goto oops; 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project data = (char*) malloc(sz); 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(data == 0) goto oops; 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(read(fd, data, sz) != sz) goto oops; 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(_sz) *_sz = sz; 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return data; 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectoops: 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(data != 0) free(data); 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usage(void) 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"usage: mkbootimg\n" 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " --kernel <filename>\n" 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " --ramdisk <filename>\n" 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " [ --second <2ndbootloader-filename> ]\n" 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " [ --cmdline <kernel-commandline> ]\n" 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " [ --board <boardname> ]\n" 662a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetland " [ --base <address> ]\n" 67fc2f7cb69e3f15a616330a69f0675675c68112f3Ying Wang " [ --pagesize <pagesize> ]\n" 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -o|--output <filename>\n" 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ); 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 758417d698cff733f3c5de08f2fa96b67bf4a9f795Brian Swetlandstatic unsigned char padding[4096] = { 0, }; 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint write_padding(int fd, unsigned pagesize, unsigned itemsize) 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned pagemask = pagesize - 1; 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned count; 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((itemsize & pagemask) == 0) { 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project count = pagesize - (itemsize & pagemask); 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(write(fd, padding, count) != count) { 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint main(int argc, char **argv) 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project boot_img_hdr hdr; 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *kernel_fn = 0; 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project void *kernel_data = 0; 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *ramdisk_fn = 0; 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project void *ramdisk_data = 0; 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *second_fn = 0; 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project void *second_data = 0; 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *cmdline = ""; 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *bootimg = 0; 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *board = ""; 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned pagesize = 2048; 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_CTX ctx; 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint8_t* sha; 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argc--; 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argv++; 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memset(&hdr, 0, sizeof(hdr)); 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1182a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetland /* default load addresses */ 1192a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetland hdr.kernel_addr = 0x10008000; 1202a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetland hdr.ramdisk_addr = 0x11000000; 1212a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetland hdr.second_addr = 0x10F00000; 1222a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetland hdr.tags_addr = 0x10000100; 1232a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetland 1242a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetland hdr.page_size = pagesize; 1252a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetland 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(argc > 0){ 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *arg = argv[0]; 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *val = argv[1]; 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(argc < 2) { 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return usage(); 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argc -= 2; 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argv += 2; 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!strcmp(arg, "--output") || !strcmp(arg, "-o")) { 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project bootimg = val; 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strcmp(arg, "--kernel")) { 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project kernel_fn = val; 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strcmp(arg, "--ramdisk")) { 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ramdisk_fn = val; 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strcmp(arg, "--second")) { 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project second_fn = val; 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strcmp(arg, "--cmdline")) { 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdline = val; 1442a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetland } else if(!strcmp(arg, "--base")) { 1452a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetland unsigned base = strtoul(val, 0, 16); 1462a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetland hdr.kernel_addr = base + 0x00008000; 1472a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetland hdr.ramdisk_addr = base + 0x01000000; 1482a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetland hdr.second_addr = base + 0x00F00000; 1492a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetland hdr.tags_addr = base + 0x00000100; 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strcmp(arg, "--board")) { 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project board = val; 1528417d698cff733f3c5de08f2fa96b67bf4a9f795Brian Swetland } else if(!strcmp(arg,"--pagesize")) { 1538417d698cff733f3c5de08f2fa96b67bf4a9f795Brian Swetland pagesize = strtoul(val, 0, 10); 1548417d698cff733f3c5de08f2fa96b67bf4a9f795Brian Swetland if ((pagesize != 2048) && (pagesize != 4096)) { 1558417d698cff733f3c5de08f2fa96b67bf4a9f795Brian Swetland fprintf(stderr,"error: unsupported page size %d\n", pagesize); 1568417d698cff733f3c5de08f2fa96b67bf4a9f795Brian Swetland return -1; 1578417d698cff733f3c5de08f2fa96b67bf4a9f795Brian Swetland } 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return usage(); 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(bootimg == 0) { 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"error: no output filename specified\n"); 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return usage(); 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(kernel_fn == 0) { 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"error: no kernel image specified\n"); 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return usage(); 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ramdisk_fn == 0) { 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"error: no ramdisk image specified\n"); 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return usage(); 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(strlen(board) >= BOOT_NAME_SIZE) { 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"error: board name too large\n"); 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return usage(); 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy(hdr.name, board); 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(hdr.magic, BOOT_MAGIC, BOOT_MAGIC_SIZE); 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(strlen(cmdline) > (BOOT_ARGS_SIZE - 1)) { 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"error: kernel commandline too large\n"); 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy((char*)hdr.cmdline, cmdline); 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project kernel_data = load_file(kernel_fn, &hdr.kernel_size); 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(kernel_data == 0) { 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"error: could not load kernel '%s'\n", kernel_fn); 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!strcmp(ramdisk_fn,"NONE")) { 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ramdisk_data = 0; 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project hdr.ramdisk_size = 0; 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ramdisk_data = load_file(ramdisk_fn, &hdr.ramdisk_size); 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ramdisk_data == 0) { 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"error: could not load ramdisk '%s'\n", ramdisk_fn); 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(second_fn) { 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project second_data = load_file(second_fn, &hdr.second_size); 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(second_data == 0) { 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"error: could not load secondstage '%s'\n", second_fn); 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* put a hash of the contents in the header so boot images can be 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * differentiated based on their first 2k. 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_init(&ctx); 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_update(&ctx, kernel_data, hdr.kernel_size); 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_update(&ctx, &hdr.kernel_size, sizeof(hdr.kernel_size)); 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_update(&ctx, ramdisk_data, hdr.ramdisk_size); 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_update(&ctx, &hdr.ramdisk_size, sizeof(hdr.ramdisk_size)); 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_update(&ctx, second_data, hdr.second_size); 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_update(&ctx, &hdr.second_size, sizeof(hdr.second_size)); 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sha = SHA_final(&ctx); 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(hdr.id, sha, 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_DIGEST_SIZE > sizeof(hdr.id) ? sizeof(hdr.id) : SHA_DIGEST_SIZE); 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open(bootimg, O_CREAT | O_TRUNC | O_WRONLY, 0644); 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd < 0) { 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"error: could not create '%s'\n", bootimg); 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(write(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) goto fail; 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(write_padding(fd, pagesize, sizeof(hdr))) goto fail; 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(write(fd, kernel_data, hdr.kernel_size) != hdr.kernel_size) goto fail; 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(write_padding(fd, pagesize, hdr.kernel_size)) goto fail; 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(write(fd, ramdisk_data, hdr.ramdisk_size) != hdr.ramdisk_size) goto fail; 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(write_padding(fd, pagesize, hdr.ramdisk_size)) goto fail; 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(second_data) { 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(write(fd, second_data, hdr.second_size) != hdr.second_size) goto fail; 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(write_padding(fd, pagesize, hdr.ramdisk_size)) goto fail; 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfail: 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unlink(bootimg); 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"error: failed writing '%s': %s\n", bootimg, 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strerror(errno)); 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 261