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 7581ce3a79ff0d828f8eafc1395851ae535dd151d4Ithamar R. Ademastatic unsigned char padding[16384] = { 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; 112dd7fafb34bf86b8fb41043e568bf0dd1005a49ddDoug Zongker unsigned base = 0x10000000; 113dd7fafb34bf86b8fb41043e568bf0dd1005a49ddDoug Zongker unsigned kernel_offset = 0x00008000; 114dd7fafb34bf86b8fb41043e568bf0dd1005a49ddDoug Zongker unsigned ramdisk_offset = 0x01000000; 115dd7fafb34bf86b8fb41043e568bf0dd1005a49ddDoug Zongker unsigned second_offset = 0x00f00000; 116dd7fafb34bf86b8fb41043e568bf0dd1005a49ddDoug Zongker unsigned tags_offset = 0x00000100; 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argc--; 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argv++; 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memset(&hdr, 0, sizeof(hdr)); 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(argc > 0){ 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *arg = argv[0]; 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *val = argv[1]; 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(argc < 2) { 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return usage(); 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argc -= 2; 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argv += 2; 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!strcmp(arg, "--output") || !strcmp(arg, "-o")) { 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project bootimg = val; 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strcmp(arg, "--kernel")) { 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project kernel_fn = val; 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strcmp(arg, "--ramdisk")) { 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ramdisk_fn = val; 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strcmp(arg, "--second")) { 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project second_fn = val; 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strcmp(arg, "--cmdline")) { 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdline = val; 1412a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetland } else if(!strcmp(arg, "--base")) { 142dd7fafb34bf86b8fb41043e568bf0dd1005a49ddDoug Zongker base = strtoul(val, 0, 16); 143dd7fafb34bf86b8fb41043e568bf0dd1005a49ddDoug Zongker } else if(!strcmp(arg, "--kernel_offset")) { 144dd7fafb34bf86b8fb41043e568bf0dd1005a49ddDoug Zongker kernel_offset = strtoul(val, 0, 16); 145dd7fafb34bf86b8fb41043e568bf0dd1005a49ddDoug Zongker } else if(!strcmp(arg, "--ramdisk_offset")) { 146dd7fafb34bf86b8fb41043e568bf0dd1005a49ddDoug Zongker ramdisk_offset = strtoul(val, 0, 16); 147dd7fafb34bf86b8fb41043e568bf0dd1005a49ddDoug Zongker } else if(!strcmp(arg, "--second_offset")) { 148dd7fafb34bf86b8fb41043e568bf0dd1005a49ddDoug Zongker second_offset = strtoul(val, 0, 16); 149dd7fafb34bf86b8fb41043e568bf0dd1005a49ddDoug Zongker } else if(!strcmp(arg, "--tags_offset")) { 150dd7fafb34bf86b8fb41043e568bf0dd1005a49ddDoug Zongker tags_offset = strtoul(val, 0, 16); 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strcmp(arg, "--board")) { 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project board = val; 1538417d698cff733f3c5de08f2fa96b67bf4a9f795Brian Swetland } else if(!strcmp(arg,"--pagesize")) { 1548417d698cff733f3c5de08f2fa96b67bf4a9f795Brian Swetland pagesize = strtoul(val, 0, 10); 15581ce3a79ff0d828f8eafc1395851ae535dd151d4Ithamar R. Adema if ((pagesize != 2048) && (pagesize != 4096) 15681ce3a79ff0d828f8eafc1395851ae535dd151d4Ithamar R. Adema && (pagesize != 8192) && (pagesize != 16384)) { 1578417d698cff733f3c5de08f2fa96b67bf4a9f795Brian Swetland fprintf(stderr,"error: unsupported page size %d\n", pagesize); 1588417d698cff733f3c5de08f2fa96b67bf4a9f795Brian Swetland return -1; 1598417d698cff733f3c5de08f2fa96b67bf4a9f795Brian Swetland } 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return usage(); 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 16465e461c478b000246ef81c3ca5fdd2dbb819d7adMaarten Hooft hdr.page_size = pagesize; 16565e461c478b000246ef81c3ca5fdd2dbb819d7adMaarten Hooft 166dd7fafb34bf86b8fb41043e568bf0dd1005a49ddDoug Zongker hdr.kernel_addr = base + kernel_offset; 167dd7fafb34bf86b8fb41043e568bf0dd1005a49ddDoug Zongker hdr.ramdisk_addr = base + ramdisk_offset; 168dd7fafb34bf86b8fb41043e568bf0dd1005a49ddDoug Zongker hdr.second_addr = base + second_offset; 169dd7fafb34bf86b8fb41043e568bf0dd1005a49ddDoug Zongker hdr.tags_addr = base + tags_offset; 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(bootimg == 0) { 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"error: no output filename specified\n"); 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return usage(); 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(kernel_fn == 0) { 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"error: no kernel image specified\n"); 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return usage(); 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ramdisk_fn == 0) { 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"error: no ramdisk image specified\n"); 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return usage(); 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(strlen(board) >= BOOT_NAME_SIZE) { 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"error: board name too large\n"); 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return usage(); 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy(hdr.name, board); 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(hdr.magic, BOOT_MAGIC, BOOT_MAGIC_SIZE); 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(strlen(cmdline) > (BOOT_ARGS_SIZE - 1)) { 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"error: kernel commandline too large\n"); 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy((char*)hdr.cmdline, cmdline); 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project kernel_data = load_file(kernel_fn, &hdr.kernel_size); 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(kernel_data == 0) { 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"error: could not load kernel '%s'\n", kernel_fn); 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!strcmp(ramdisk_fn,"NONE")) { 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ramdisk_data = 0; 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project hdr.ramdisk_size = 0; 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ramdisk_data = load_file(ramdisk_fn, &hdr.ramdisk_size); 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ramdisk_data == 0) { 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"error: could not load ramdisk '%s'\n", ramdisk_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 if(second_fn) { 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project second_data = load_file(second_fn, &hdr.second_size); 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(second_data == 0) { 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"error: could not load secondstage '%s'\n", second_fn); 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* put a hash of the contents in the header so boot images can be 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * differentiated based on their first 2k. 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_init(&ctx); 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_update(&ctx, kernel_data, hdr.kernel_size); 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_update(&ctx, &hdr.kernel_size, sizeof(hdr.kernel_size)); 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_update(&ctx, ramdisk_data, hdr.ramdisk_size); 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_update(&ctx, &hdr.ramdisk_size, sizeof(hdr.ramdisk_size)); 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_update(&ctx, second_data, hdr.second_size); 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_update(&ctx, &hdr.second_size, sizeof(hdr.second_size)); 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sha = SHA_final(&ctx); 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(hdr.id, sha, 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_DIGEST_SIZE > sizeof(hdr.id) ? sizeof(hdr.id) : SHA_DIGEST_SIZE); 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open(bootimg, O_CREAT | O_TRUNC | O_WRONLY, 0644); 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd < 0) { 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"error: could not create '%s'\n", bootimg); 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(write(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) goto fail; 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(write_padding(fd, pagesize, sizeof(hdr))) goto fail; 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(write(fd, kernel_data, hdr.kernel_size) != hdr.kernel_size) goto fail; 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(write_padding(fd, pagesize, hdr.kernel_size)) goto fail; 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(write(fd, ramdisk_data, hdr.ramdisk_size) != hdr.ramdisk_size) goto fail; 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(write_padding(fd, pagesize, hdr.ramdisk_size)) goto fail; 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(second_data) { 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(write(fd, second_data, hdr.second_size) != hdr.second_size) goto fail; 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(write_padding(fd, pagesize, hdr.ramdisk_size)) goto fail; 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfail: 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unlink(bootimg); 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"error: failed writing '%s': %s\n", bootimg, 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strerror(errno)); 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 269