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