mirror of
				https://github.com/Tasssadar/libbootimg.git
				synced 2025-11-04 13:55:44 +08:00 
			
		
		
		
	Initial commit
This commit is contained in:
		
							
								
								
									
										20
									
								
								.travis.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								.travis.yml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
# Travis-CI Build for libbootimg
 | 
			
		||||
# see travis-ci.org for details
 | 
			
		||||
 | 
			
		||||
language: c
 | 
			
		||||
 | 
			
		||||
compiler:
 | 
			
		||||
  - gcc
 | 
			
		||||
  - clang
 | 
			
		||||
 | 
			
		||||
matrix:
 | 
			
		||||
 include:
 | 
			
		||||
   - compiler: i586-mingw32msvc-gcc
 | 
			
		||||
 | 
			
		||||
script:
 | 
			
		||||
 - make
 | 
			
		||||
 | 
			
		||||
# Only watch the master
 | 
			
		||||
branches:
 | 
			
		||||
 only:
 | 
			
		||||
   - master
 | 
			
		||||
							
								
								
									
										22
									
								
								Android.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								Android.mk
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
# bbootimg
 | 
			
		||||
LOCAL_PATH:= $(call my-dir)
 | 
			
		||||
include $(CLEAR_VARS)
 | 
			
		||||
 | 
			
		||||
LOCAL_SRC_FILES:= bbootimg.c libbootimg.c
 | 
			
		||||
LOCAL_MODULE:= bbootimg
 | 
			
		||||
LOCAL_MODULE_TAGS := eng
 | 
			
		||||
 | 
			
		||||
LOCAL_FORCE_STATIC_EXECUTABLE := true
 | 
			
		||||
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
 | 
			
		||||
LOCAL_UNSTRIPPED_PATH := $(TARGET_OUT_EXECUTABLES_UNSTRIPPED)
 | 
			
		||||
 | 
			
		||||
LOCAL_STATIC_LIBRARIES := libc
 | 
			
		||||
 | 
			
		||||
include $(BUILD_EXECUTABLE)
 | 
			
		||||
 | 
			
		||||
# libbootimg
 | 
			
		||||
include $(CLEAR_VARS)
 | 
			
		||||
LOCAL_SRC_FILES := libbootimg.c
 | 
			
		||||
LOCAL_MODULE := libbootimg
 | 
			
		||||
LOCAL_MODULE_TAGS := eng
 | 
			
		||||
include $(BUILD_STATIC_LIBRARY)
 | 
			
		||||
							
								
								
									
										18
									
								
								COPYING
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								COPYING
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
The MIT License (MIT)
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
the Software without restriction, including without limitation the rights to
 | 
			
		||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
							
								
								
									
										29
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
program=bbootimg
 | 
			
		||||
CC?=gcc
 | 
			
		||||
OPT=-O2 ${CFLAGS}
 | 
			
		||||
OBJ=bbootimg.o libbootimg.o
 | 
			
		||||
 | 
			
		||||
.PHONY: build
 | 
			
		||||
.PHONY: install
 | 
			
		||||
.PHONY: uninstall
 | 
			
		||||
.PHONY: clean
 | 
			
		||||
 | 
			
		||||
build: ${program}
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	rm -f *.o ${program}
 | 
			
		||||
 | 
			
		||||
${program}: ${OBJ}
 | 
			
		||||
	$(CC) ${OBJ} -o ${program} ${OPT}
 | 
			
		||||
 | 
			
		||||
bbootimg.o: bbootimg.c
 | 
			
		||||
	$(CC) -c ${OPT} $<
 | 
			
		||||
 | 
			
		||||
libbootimg.o: libbootimg.c
 | 
			
		||||
	$(CC) -c ${OPT} $<
 | 
			
		||||
 | 
			
		||||
install: build
 | 
			
		||||
	install -D ${program} /usr/local/bin/${program}
 | 
			
		||||
 | 
			
		||||
uninstall:
 | 
			
		||||
	rm /usr/local/bin/${program}
 | 
			
		||||
							
								
								
									
										5
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
# libbootimg
 | 
			
		||||
libbootimg is small library which can create, extract or update Android boot images. 
 | 
			
		||||
 | 
			
		||||
## bbootimg
 | 
			
		||||
This is cli frontend for libbootimg, compatible with abootimg's arguments.
 | 
			
		||||
							
								
								
									
										338
									
								
								bbootimg.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										338
									
								
								bbootimg.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,338 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include "libbootimg.h"
 | 
			
		||||
 | 
			
		||||
#define ACT_EXTRACT 1
 | 
			
		||||
#define ACT_UPDATE  2
 | 
			
		||||
#define ACT_CREATE  3
 | 
			
		||||
 | 
			
		||||
struct bbootimg_info
 | 
			
		||||
{
 | 
			
		||||
    struct bootimg img;
 | 
			
		||||
    int act;
 | 
			
		||||
    char *fname_img;
 | 
			
		||||
    char *fname_kernel;
 | 
			
		||||
    char *fname_ramdisk;
 | 
			
		||||
    char *fname_second;
 | 
			
		||||
    char *fname_cfg;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void print_help(const char *prog_name)
 | 
			
		||||
{
 | 
			
		||||
    printf(
 | 
			
		||||
    "bbootimg %s\n"
 | 
			
		||||
    "Manipulate Android Boot Images.\n"
 | 
			
		||||
    "This is abootimg-compatible implementation using libbootimg.\n"
 | 
			
		||||
    "\n"
 | 
			
		||||
    "%s [-h,--help]     - print usage\n"
 | 
			
		||||
    "\n"
 | 
			
		||||
    "%s -i <bootimg>    - print image information\n"
 | 
			
		||||
    "\n"
 | 
			
		||||
    "%s -x <bootimg> [<bootimg.cfg> [<kernel> [<ramdisk> [<secondstage>]]]]\n"
 | 
			
		||||
    "    extract objects from boot image:\n"
 | 
			
		||||
    "    - config file (bootimg.cfg)\n"
 | 
			
		||||
    "    - kernel image (zImage)\n"
 | 
			
		||||
    "    - ramdisk image (initrd.img)\n"
 | 
			
		||||
    "    - second stage image (stage2.img)\n"
 | 
			
		||||
    "\n"
 | 
			
		||||
    "%s -u <bootimg> [-c \"param=value\"] [-f <bootimg.cfg>] [-k <kernel>] [-r <ramdisk>] [-s <secondstage>]\n"
 | 
			
		||||
    "    update current boot image with objects given in command line\n"
 | 
			
		||||
    "    - header informations given in arguments (several can be provided)\n"
 | 
			
		||||
    "    - header informations given in config file\n"
 | 
			
		||||
    "    - kernel image\n"
 | 
			
		||||
    "    - ramdisk image\n"
 | 
			
		||||
    "    - second stage image\n"
 | 
			
		||||
    "\n"
 | 
			
		||||
    "%s --create <bootimg> [-c \"param=value\"] [-f <bootimg.cfg>] -k <kernel> -r <ramdisk> [-s <secondstage>]\n"
 | 
			
		||||
    "    create a new image from scratch.\n"
 | 
			
		||||
    "    arguments are the same as for -u.\n"
 | 
			
		||||
    "    kernel and ramdisk are mandatory.\n"
 | 
			
		||||
    ,libbootimg_version_str(), prog_name, prog_name, prog_name, prog_name, prog_name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int print_info(const char *path)
 | 
			
		||||
{
 | 
			
		||||
    struct bootimg img;
 | 
			
		||||
    if(libbootimg_init_load(&img, path) < 0)
 | 
			
		||||
    {
 | 
			
		||||
        fprintf(stderr, "Failed to load bootimg \"%s\"!\n", path);
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf ("\nAndroid Boot Image Info:\n\n");
 | 
			
		||||
    printf ("* file name = %s\n\n", path);
 | 
			
		||||
 | 
			
		||||
    printf ("* image size = %u bytes (%.2f MB)\n", img.size, (double)img.size/0x100000);
 | 
			
		||||
    printf ("  page size  = %u bytes\n\n", img.hdr.page_size);
 | 
			
		||||
 | 
			
		||||
    printf ("* Boot Name = \"%s\"\n\n", img.hdr.name);
 | 
			
		||||
 | 
			
		||||
    printf ("* kernel size       = %u bytes (%.2f MB)\n", img.hdr.kernel_size, (double)img.hdr.kernel_size/0x100000);
 | 
			
		||||
    printf ("  ramdisk size      = %u bytes (%.2f MB)\n", img.hdr.ramdisk_size, (double)img.hdr.ramdisk_size/0x100000);
 | 
			
		||||
    if (img.hdr.second_size)
 | 
			
		||||
        printf ("  second stage size = %u bytes (%.2f MB)\n", img.hdr.second_size, (double)img.hdr.second_size/0x100000);
 | 
			
		||||
 | 
			
		||||
    printf ("\n* load addresses:\n");
 | 
			
		||||
    printf ("  kernel:       0x%08x\n", img.hdr.kernel_addr);
 | 
			
		||||
    printf ("  ramdisk:      0x%08x\n", img.hdr.ramdisk_addr);
 | 
			
		||||
    if (img.hdr.second_size)
 | 
			
		||||
        printf ("  second stage: 0x%08x\n", img.hdr.second_addr);
 | 
			
		||||
    printf ("  tags:         0x%08x\n\n", img.hdr.tags_addr);
 | 
			
		||||
 | 
			
		||||
    if (img.hdr.cmdline[0])
 | 
			
		||||
        printf ("* cmdline = %s\n\n", img.hdr.cmdline);
 | 
			
		||||
    else
 | 
			
		||||
        printf ("* empty cmdline\n");
 | 
			
		||||
 | 
			
		||||
    printf ("* id = ");
 | 
			
		||||
    int i;
 | 
			
		||||
    for (i=0; i<8; i++)
 | 
			
		||||
        printf ("0x%08x ", img.hdr.id[i]);
 | 
			
		||||
    printf ("\n\n");
 | 
			
		||||
 | 
			
		||||
    libbootimg_destroy(&img);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int extract_bootimg(struct bbootimg_info *i)
 | 
			
		||||
{
 | 
			
		||||
    int res = libbootimg_init_load(&i->img, i->fname_img);
 | 
			
		||||
    if(res < 0)
 | 
			
		||||
    {
 | 
			
		||||
        fprintf(stderr, "Failed to load boot image (%s)!\n", strerror(-res));
 | 
			
		||||
        return -res;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const char *cfg = i->fname_cfg ? i->fname_cfg : "bootimg.cfg";
 | 
			
		||||
    printf("writing boot image config in %s\n", cfg);
 | 
			
		||||
    res = libbootimg_write_config(&i->img, cfg);
 | 
			
		||||
    if(res < 0)
 | 
			
		||||
    {
 | 
			
		||||
        fprintf(stderr, "Failed to write bootimg cfg (%s)!\n", strerror(-res));
 | 
			
		||||
        return -res;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const char *kernel = i->fname_kernel ? i->fname_kernel : "zImage";
 | 
			
		||||
    printf("extracting kernel in %s\n", kernel);
 | 
			
		||||
    res = libbootimg_dump_kernel(&i->img, kernel);
 | 
			
		||||
    if(res < 0)
 | 
			
		||||
    {
 | 
			
		||||
        fprintf(stderr, "Failed to extract kernel (%s)!\n", strerror(-res));
 | 
			
		||||
        return -res;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const char *ramdisk = i->fname_ramdisk ? i->fname_ramdisk : "initrd.img";
 | 
			
		||||
    printf("extracting kernel in %s\n", ramdisk);
 | 
			
		||||
    res = libbootimg_dump_ramdisk(&i->img, ramdisk);
 | 
			
		||||
    if(res < 0)
 | 
			
		||||
    {
 | 
			
		||||
        fprintf(stderr, "Failed to extract ramdisk (%s)!\n", strerror(-res));
 | 
			
		||||
        return -res;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(i->img.hdr.second_size > 0)
 | 
			
		||||
    {
 | 
			
		||||
        const char *second = i->fname_second ? i->fname_second : "stage2.img";
 | 
			
		||||
        printf("extracting second stage in %s\n", second);
 | 
			
		||||
        res = libbootimg_dump_second(&i->img, second);
 | 
			
		||||
        if(res < 0)
 | 
			
		||||
        {
 | 
			
		||||
            fprintf(stderr, "Failed to extract second stage (%s)!\n", strerror(-res));
 | 
			
		||||
            return -res;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    libbootimg_destroy(&i->img);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int update_bootimg(struct bbootimg_info *i)
 | 
			
		||||
{
 | 
			
		||||
    int res = -1;
 | 
			
		||||
    char *tmpname = malloc(strlen(i->fname_img)+sizeof(".new"));
 | 
			
		||||
    strcpy(tmpname, i->fname_img);
 | 
			
		||||
    strcat(tmpname, ".new");
 | 
			
		||||
 | 
			
		||||
    if(i->fname_cfg)
 | 
			
		||||
    {
 | 
			
		||||
        int line = -1;
 | 
			
		||||
        printf("reading config file %s\n", i->fname_cfg);
 | 
			
		||||
        res = libbootimg_load_config(&i->img, i->fname_cfg, &line);
 | 
			
		||||
        if(res < 0)
 | 
			
		||||
        {
 | 
			
		||||
            res = -res;
 | 
			
		||||
            fprintf(stderr, "Failed to load config (%s), error on line %d!\n", strerror(res), line);
 | 
			
		||||
            goto exit;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(i->fname_kernel)
 | 
			
		||||
    {
 | 
			
		||||
        printf("reading kernel from %s\n", i->fname_kernel);
 | 
			
		||||
        res = libbootimg_load_kernel(&i->img, i->fname_kernel);
 | 
			
		||||
        if(res < 0)
 | 
			
		||||
        {
 | 
			
		||||
            res = -res;
 | 
			
		||||
            fprintf(stderr, "Failed to load kernel (%s)!\n", strerror(res));
 | 
			
		||||
            goto exit;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(i->fname_ramdisk)
 | 
			
		||||
    {
 | 
			
		||||
        printf("reading ramdisk from %s\n", i->fname_ramdisk);
 | 
			
		||||
        res = libbootimg_load_ramdisk(&i->img, i->fname_ramdisk);
 | 
			
		||||
        if(res < 0)
 | 
			
		||||
        {
 | 
			
		||||
            res = -res;
 | 
			
		||||
            fprintf(stderr, "Failed to load ramdisk (%s)!\n", strerror(res));
 | 
			
		||||
            goto exit;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(i->fname_second)
 | 
			
		||||
    {
 | 
			
		||||
        printf("reading second stage from %s\n", i->fname_second);
 | 
			
		||||
        res = libbootimg_load_second(&i->img, i->fname_second);
 | 
			
		||||
        if(res < 0)
 | 
			
		||||
        {
 | 
			
		||||
            res = -res;
 | 
			
		||||
            fprintf(stderr, "Failed to load second stage (%s)!\n", strerror(res));
 | 
			
		||||
            goto exit;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf("Writing Boot Image %s\n", i->fname_img);
 | 
			
		||||
    res = libbootimg_write_img(&i->img, tmpname);
 | 
			
		||||
    if(res < 0)
 | 
			
		||||
    {
 | 
			
		||||
        res = -res;
 | 
			
		||||
        fprintf(stderr, "Failed to create boot image (%s)!\n", strerror(res));
 | 
			
		||||
        remove(tmpname);
 | 
			
		||||
        goto exit;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rename(tmpname, i->fname_img);
 | 
			
		||||
    remove(tmpname);
 | 
			
		||||
exit:
 | 
			
		||||
    free(tmpname);
 | 
			
		||||
    libbootimg_destroy(&i->img);
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int execute_action(struct bbootimg_info *i)
 | 
			
		||||
{
 | 
			
		||||
    switch(i->act)
 | 
			
		||||
    {
 | 
			
		||||
        case ACT_EXTRACT:
 | 
			
		||||
            return extract_bootimg(i);
 | 
			
		||||
        case ACT_UPDATE:
 | 
			
		||||
            return update_bootimg(i);
 | 
			
		||||
        case ACT_CREATE:
 | 
			
		||||
        {
 | 
			
		||||
            if(!i->fname_kernel || !i->fname_ramdisk)
 | 
			
		||||
            {
 | 
			
		||||
                fprintf(stderr, "You have to specify both ramdisk and kernel to create boot image!\n");
 | 
			
		||||
                return EINVAL;
 | 
			
		||||
            }
 | 
			
		||||
            return update_bootimg(i);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return EINVAL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int load_bootimg(struct bootimg *b, const char *path)
 | 
			
		||||
{
 | 
			
		||||
    int res = libbootimg_init_load(b, path);
 | 
			
		||||
    if(res < 0)
 | 
			
		||||
    {
 | 
			
		||||
        fprintf(stderr, "Failed to load boot image (%s)!", strerror(-res));
 | 
			
		||||
        return -res;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    struct bbootimg_info info;
 | 
			
		||||
    memset(&info, 0, sizeof(info));
 | 
			
		||||
 | 
			
		||||
    libbootimg_init_new(&info.img);
 | 
			
		||||
 | 
			
		||||
    for(i = 1; i < argc; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        if(strcmp("-h", argv[i]) == 0 || strcmp("--help", argv[i]) == 0)
 | 
			
		||||
        {
 | 
			
		||||
            print_help(argv[0]);
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(i+1 >= argc)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        if(strcmp("-i", argv[i]) == 0)
 | 
			
		||||
            return print_info(argv[i+1]);
 | 
			
		||||
 | 
			
		||||
        // actions
 | 
			
		||||
        if(strcmp("-x", argv[i]) == 0)
 | 
			
		||||
        {
 | 
			
		||||
            info.act = ACT_EXTRACT;
 | 
			
		||||
            info.fname_img = argv[++i];
 | 
			
		||||
 | 
			
		||||
            if(++i < argc)
 | 
			
		||||
                info.fname_cfg = argv[i];
 | 
			
		||||
            if(++i < argc)
 | 
			
		||||
                info.fname_kernel = argv[i];
 | 
			
		||||
            if(++i < argc)
 | 
			
		||||
                info.fname_ramdisk = argv[i];
 | 
			
		||||
            if(++i < argc)
 | 
			
		||||
                info.fname_second = argv[i];
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        else if(strcmp("-u", argv[i]) == 0)
 | 
			
		||||
        {
 | 
			
		||||
            info.act = ACT_UPDATE;
 | 
			
		||||
            info.fname_img = argv[++i];
 | 
			
		||||
            if(load_bootimg(&info.img, info.fname_img) != 0)
 | 
			
		||||
               return -1;
 | 
			
		||||
        }
 | 
			
		||||
        else if(strcmp("--create", argv[i]) == 0)
 | 
			
		||||
        {
 | 
			
		||||
            info.act = ACT_CREATE;
 | 
			
		||||
            info.fname_img = argv[++i];
 | 
			
		||||
        }
 | 
			
		||||
        // params
 | 
			
		||||
        else if(strcmp("-c", argv[i]) == 0)
 | 
			
		||||
        {
 | 
			
		||||
            if(libbootimg_load_config_line(&info.img, argv[++i]) < 0)
 | 
			
		||||
            {
 | 
			
		||||
                fprintf(stderr, "Invalid config option \"%s\"\n\n", argv[i]);
 | 
			
		||||
                goto exit_help;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if(strcmp("-f", argv[i]) == 0)
 | 
			
		||||
            info.fname_cfg = argv[++i];
 | 
			
		||||
        else if(strcmp("-k", argv[i]) == 0)
 | 
			
		||||
            info.fname_kernel = argv[++i];
 | 
			
		||||
        else if(strcmp("-r", argv[i]) == 0)
 | 
			
		||||
            info.fname_ramdisk = argv[++i];
 | 
			
		||||
        else if(strcmp("-s", argv[i]) == 0)
 | 
			
		||||
            info.fname_second = argv[++i];
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            fprintf(stderr, "Unknown argument: %s\n\n", argv[i]);
 | 
			
		||||
            goto exit_help;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return execute_action(&info);
 | 
			
		||||
exit_help:
 | 
			
		||||
    libbootimg_destroy(&info.img);
 | 
			
		||||
    print_help(argv[0]);
 | 
			
		||||
    return EINVAL;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										78
									
								
								boot_img_hdr.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								boot_img_hdr.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2008 The Android Open Source Project
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef BOOT_IMG_HDR_H
 | 
			
		||||
#define BOOT_IMG_HDR_H
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
** +-----------------+ 
 | 
			
		||||
** | 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
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#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 */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct boot_img_hdr boot_img_hdr;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										449
									
								
								libbootimg.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										449
									
								
								libbootimg.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,449 @@
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
 | 
			
		||||
#include "libbootimg.h"
 | 
			
		||||
#include "version.h"
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_PAGE_SIZE 2048
 | 
			
		||||
#define MAX_PATH_LEN 4096
 | 
			
		||||
 | 
			
		||||
static inline unsigned align_size(unsigned size, unsigned page_size)
 | 
			
		||||
{
 | 
			
		||||
    return ((size + page_size - 1)/page_size)*page_size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void libbootimg_init_new(struct bootimg *img)
 | 
			
		||||
{
 | 
			
		||||
    memset(img, 0, sizeof(struct bootimg));
 | 
			
		||||
    strcpy((char*)img->hdr.magic, BOOT_MAGIC);
 | 
			
		||||
    img->hdr.page_size = DEFAULT_PAGE_SIZE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int libbootimg_init_load(struct bootimg *img, const char *path)
 | 
			
		||||
{
 | 
			
		||||
    int res = 0;
 | 
			
		||||
    long addr;
 | 
			
		||||
 | 
			
		||||
    libbootimg_init_new(img);
 | 
			
		||||
 | 
			
		||||
    res = libbootimg_load_header(&img->hdr, path);
 | 
			
		||||
    if(res < 0)
 | 
			
		||||
    {
 | 
			
		||||
        libbootimg_destroy(img);
 | 
			
		||||
        return res;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    FILE *f = fopen(path, "r");
 | 
			
		||||
    if(!f)
 | 
			
		||||
        return -errno;
 | 
			
		||||
 | 
			
		||||
    img->kernel = malloc(img->hdr.kernel_size);
 | 
			
		||||
    img->ramdisk = malloc(img->hdr.ramdisk_size);
 | 
			
		||||
    img->second = malloc(img->hdr.second_size);
 | 
			
		||||
 | 
			
		||||
    // Read kernel
 | 
			
		||||
    addr = img->hdr.page_size;
 | 
			
		||||
    if(fseek(f, addr, SEEK_SET) < 0)
 | 
			
		||||
        goto fail;
 | 
			
		||||
 | 
			
		||||
    if(fread(img->kernel, img->hdr.kernel_size, 1, f) != 1)
 | 
			
		||||
        goto fail;
 | 
			
		||||
 | 
			
		||||
    // Read ramdisk
 | 
			
		||||
    addr += align_size(img->hdr.kernel_size, img->hdr.page_size);
 | 
			
		||||
    if(fseek(f, addr, SEEK_SET) < 0)
 | 
			
		||||
        goto fail;
 | 
			
		||||
 | 
			
		||||
    if(fread(img->ramdisk, img->hdr.ramdisk_size, 1, f) != 1)
 | 
			
		||||
        goto fail;
 | 
			
		||||
 | 
			
		||||
    // Read second
 | 
			
		||||
    if(img->hdr.second_size > 0)
 | 
			
		||||
    {
 | 
			
		||||
        addr += align_size(img->hdr.ramdisk_size, img->hdr.page_size);
 | 
			
		||||
        if(fseek(f, addr, SEEK_SET) < 0)
 | 
			
		||||
            goto fail;
 | 
			
		||||
 | 
			
		||||
        if(fread(img->second, img->hdr.second_size, 1, f) != 1)
 | 
			
		||||
            goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fseek(f, 0, SEEK_END);
 | 
			
		||||
    img->size = ftell(f);
 | 
			
		||||
 | 
			
		||||
    fclose(f);
 | 
			
		||||
    return 0;
 | 
			
		||||
fail:
 | 
			
		||||
    res = -errno;
 | 
			
		||||
    libbootimg_destroy(img);
 | 
			
		||||
    fclose(f);
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void libbootimg_destroy(struct bootimg *b)
 | 
			
		||||
{
 | 
			
		||||
    free(b->kernel);
 | 
			
		||||
    free(b->ramdisk);
 | 
			
		||||
    free(b->second);
 | 
			
		||||
 | 
			
		||||
    b->kernel = b->ramdisk = b->second = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int libbootimg_load_header(struct boot_img_hdr *hdr, const char *path)
 | 
			
		||||
{
 | 
			
		||||
    FILE *f = fopen(path, "r");
 | 
			
		||||
    if(!f)
 | 
			
		||||
        return -errno;
 | 
			
		||||
 | 
			
		||||
    int res = fread(hdr, sizeof(struct boot_img_hdr), 1, f);
 | 
			
		||||
    res = res == 1 ? 0 : -errno;
 | 
			
		||||
 | 
			
		||||
    fclose(f);
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int dump_part(uint8_t *data, unsigned len, const char *dest)
 | 
			
		||||
{
 | 
			
		||||
    int res = 0;
 | 
			
		||||
    FILE *f = fopen(dest, "w");
 | 
			
		||||
    if(!f)
 | 
			
		||||
        return -errno;
 | 
			
		||||
 | 
			
		||||
    if(fwrite(data, len, 1, f) != 1)
 | 
			
		||||
        res = -errno;
 | 
			
		||||
 | 
			
		||||
    fclose(f);
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int libbootimg_dump_kernel(struct bootimg *b, const char *dest)
 | 
			
		||||
{
 | 
			
		||||
    return dump_part(b->kernel, b->hdr.kernel_size, dest);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int libbootimg_dump_ramdisk(struct bootimg *b, const char *dest)
 | 
			
		||||
{
 | 
			
		||||
    return dump_part(b->ramdisk, b->hdr.ramdisk_size, dest);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int libbootimg_dump_second(struct bootimg *b, const char *dest)
 | 
			
		||||
{
 | 
			
		||||
    if(b->hdr.second_size == 0)
 | 
			
		||||
        return -ENOENT;
 | 
			
		||||
    return dump_part(b->second, b->hdr.second_size, dest);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int libbootimg_dump(struct bootimg *b, const char *dest_dir)
 | 
			
		||||
{
 | 
			
		||||
    char dest[MAX_PATH_LEN];
 | 
			
		||||
    int res = 0;
 | 
			
		||||
 | 
			
		||||
    snprintf(dest, sizeof(dest), "%s/zImage", dest_dir);
 | 
			
		||||
    res = libbootimg_dump_kernel(b, dest);
 | 
			
		||||
 | 
			
		||||
    if(res == 0)
 | 
			
		||||
    {
 | 
			
		||||
        snprintf(dest, sizeof(dest), "%s/initrd.img", dest_dir);
 | 
			
		||||
        res = libbootimg_dump_ramdisk(b, dest);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(res == 0 && b->hdr.second_size)
 | 
			
		||||
    {
 | 
			
		||||
        snprintf(dest, sizeof(dest), "%s/second.img", dest_dir);
 | 
			
		||||
        res = libbootimg_dump_second(b, dest);
 | 
			
		||||
    }
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int load_part(uint8_t **data, const char *src)
 | 
			
		||||
{
 | 
			
		||||
    struct stat info;
 | 
			
		||||
    if(stat(src, &info) < 0)
 | 
			
		||||
        return -errno;
 | 
			
		||||
 | 
			
		||||
    if(info.st_size > INT_MAX)
 | 
			
		||||
        return -EFBIG;
 | 
			
		||||
 | 
			
		||||
    FILE *f = fopen(src, "r");
 | 
			
		||||
    if(!f)
 | 
			
		||||
        return -errno;
 | 
			
		||||
 | 
			
		||||
    int res = info.st_size;
 | 
			
		||||
    *data = realloc(*data, info.st_size);
 | 
			
		||||
 | 
			
		||||
    if(fread(*data, info.st_size, 1, f) != 1)
 | 
			
		||||
    {
 | 
			
		||||
        res = -errno;
 | 
			
		||||
        free(*data);
 | 
			
		||||
        *data = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fclose(f);
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int libbootimg_load_kernel(struct bootimg *b, const char *src)
 | 
			
		||||
{
 | 
			
		||||
    int res = load_part(&b->kernel, src);
 | 
			
		||||
    if(res >= 0)
 | 
			
		||||
        b->hdr.kernel_size = res;
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int libbootimg_load_ramdisk(struct bootimg *b, const char *src)
 | 
			
		||||
{
 | 
			
		||||
    int res = load_part(&b->ramdisk, src);
 | 
			
		||||
    if(res >= 0)
 | 
			
		||||
        b->hdr.ramdisk_size = res;
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int libbootimg_load_second(struct bootimg *b, const char *src)
 | 
			
		||||
{
 | 
			
		||||
    int res = load_part(&b->second, src);
 | 
			
		||||
    if(res >= 0)
 | 
			
		||||
        b->hdr.second_size = res;
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 32bit FNV-1a hash algorithm
 | 
			
		||||
// http://isthe.com/chongo/tech/comp/fnv/#FNV-1a
 | 
			
		||||
static uint32_t calc_fnv_hash(void *data, unsigned len)
 | 
			
		||||
{
 | 
			
		||||
    static const uint32_t FNV_prime = 16777619U;
 | 
			
		||||
    static const uint32_t offset_basis = 2166136261U;
 | 
			
		||||
 | 
			
		||||
    uint32_t *d = (uint32_t*)data;
 | 
			
		||||
    uint32_t i, max;
 | 
			
		||||
    uint32_t hash = offset_basis;
 | 
			
		||||
 | 
			
		||||
    max = len/4;
 | 
			
		||||
 | 
			
		||||
    // 32 bit data
 | 
			
		||||
    for(i = 0; i < max; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        hash ^= d[i];
 | 
			
		||||
        hash *= FNV_prime;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // last bits
 | 
			
		||||
    for(i *= 4; i < len; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        hash ^= (uint32_t) ((uint8_t*)data)[i];
 | 
			
		||||
        hash *= FNV_prime;
 | 
			
		||||
    }
 | 
			
		||||
    return hash;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void fill_id_hashes(struct bootimg *b)
 | 
			
		||||
{
 | 
			
		||||
    b->hdr.id[0] = calc_fnv_hash(b->kernel, b->hdr.kernel_size);
 | 
			
		||||
    b->hdr.id[1] = calc_fnv_hash(b->ramdisk, b->hdr.ramdisk_size);
 | 
			
		||||
    b->hdr.id[2] = calc_fnv_hash(b->ramdisk, b->hdr.second_size);
 | 
			
		||||
 | 
			
		||||
    b->hdr.id[3] = calc_fnv_hash(&b->hdr.kernel_addr, sizeof(b->hdr.kernel_addr));
 | 
			
		||||
    b->hdr.id[4] = calc_fnv_hash(&b->hdr.ramdisk_addr, sizeof(b->hdr.ramdisk_addr));
 | 
			
		||||
    b->hdr.id[5] = calc_fnv_hash(&b->hdr.second_addr, sizeof(b->hdr.second_addr));
 | 
			
		||||
    b->hdr.id[6] = calc_fnv_hash(&b->hdr.tags_addr, sizeof(b->hdr.tags_addr));
 | 
			
		||||
    b->hdr.id[7] = calc_fnv_hash(b->hdr.cmdline, strlen((char*)b->hdr.cmdline));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int libbootimg_write_img(struct bootimg *b, const char *dest)
 | 
			
		||||
{
 | 
			
		||||
    if(b->hdr.kernel_size == 0 || b->hdr.ramdisk_size == 0 || b->hdr.page_size < sizeof(b->hdr))
 | 
			
		||||
        return -EINVAL;
 | 
			
		||||
 | 
			
		||||
    uint32_t i;
 | 
			
		||||
    int res = 0;
 | 
			
		||||
    FILE *f = fopen(dest, "w");
 | 
			
		||||
    if(!f)
 | 
			
		||||
        return -errno;
 | 
			
		||||
 | 
			
		||||
    // make sure it ends with 0
 | 
			
		||||
    b->hdr.cmdline[BOOT_ARGS_SIZE-1] = 0;
 | 
			
		||||
 | 
			
		||||
    fill_id_hashes(b);
 | 
			
		||||
 | 
			
		||||
    size_t to_write;
 | 
			
		||||
    char *blank = malloc(b->hdr.page_size);
 | 
			
		||||
    memset(blank, 0, b->hdr.page_size);
 | 
			
		||||
 | 
			
		||||
    // write header
 | 
			
		||||
    if(fwrite(&b->hdr, sizeof(b->hdr), 1, f) != 1)
 | 
			
		||||
        goto fail;
 | 
			
		||||
 | 
			
		||||
    to_write = align_size(sizeof(b->hdr), b->hdr.page_size) - sizeof(b->hdr);
 | 
			
		||||
    if(fwrite(blank, sizeof(char), to_write, f) != to_write)
 | 
			
		||||
        goto fail;
 | 
			
		||||
 | 
			
		||||
    // write kernel
 | 
			
		||||
    if(fwrite(b->kernel, b->hdr.kernel_size, 1, f) != 1)
 | 
			
		||||
        goto fail;
 | 
			
		||||
 | 
			
		||||
    to_write = align_size(b->hdr.kernel_size, b->hdr.page_size) - b->hdr.kernel_size;
 | 
			
		||||
    if(fwrite(blank, sizeof(char), to_write, f) != to_write)
 | 
			
		||||
        goto fail;
 | 
			
		||||
 | 
			
		||||
    // write ramdisk
 | 
			
		||||
    if(fwrite(b->ramdisk, b->hdr.ramdisk_size, 1, f) != 1)
 | 
			
		||||
        goto fail;
 | 
			
		||||
 | 
			
		||||
    to_write = align_size(b->hdr.ramdisk_size, b->hdr.page_size) - b->hdr.ramdisk_size;
 | 
			
		||||
    if(fwrite(blank, sizeof(char), to_write, f) != to_write)
 | 
			
		||||
        goto fail;
 | 
			
		||||
 | 
			
		||||
    // write second
 | 
			
		||||
    if(b->hdr.second_size != 0)
 | 
			
		||||
    {
 | 
			
		||||
        if(fwrite(b->second, b->hdr.second_size, 1, f) != 1)
 | 
			
		||||
            goto fail;
 | 
			
		||||
 | 
			
		||||
        to_write = align_size(b->hdr.second_size, b->hdr.page_size) - b->hdr.second_size;
 | 
			
		||||
        if(fwrite(blank, sizeof(char), to_write, f) != to_write)
 | 
			
		||||
            goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // bootimg size (abootimg compatibility)
 | 
			
		||||
    if(b->size != 0)
 | 
			
		||||
    {
 | 
			
		||||
        if((int)b->size < ftell(f))
 | 
			
		||||
        {
 | 
			
		||||
            res = -EFBIG;
 | 
			
		||||
            remove(dest);
 | 
			
		||||
            goto exit;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        to_write = (b->size - ftell(f))/b->hdr.page_size;
 | 
			
		||||
        for(i = 0; i < to_write; ++i)
 | 
			
		||||
            if(fwrite(blank, sizeof(char), b->hdr.page_size, f) != b->hdr.page_size)
 | 
			
		||||
                goto fail;
 | 
			
		||||
 | 
			
		||||
        to_write = (b->size - ftell(f))%b->hdr.page_size;
 | 
			
		||||
        if(fwrite(blank, sizeof(char), to_write, f) != to_write)
 | 
			
		||||
            goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    goto exit;
 | 
			
		||||
fail:
 | 
			
		||||
    res = -errno;
 | 
			
		||||
    remove(dest);
 | 
			
		||||
exit:
 | 
			
		||||
    fclose(f);
 | 
			
		||||
    free(blank);
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int libbootimg_write_img_and_destroy(struct bootimg *b, const char *dest)
 | 
			
		||||
{
 | 
			
		||||
    int res = libbootimg_write_img(b, dest);
 | 
			
		||||
    libbootimg_destroy(b);
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int libbootimg_load_config(struct bootimg *b, const char *src, int *error_line)
 | 
			
		||||
{
 | 
			
		||||
    FILE *f = fopen(src, "r");
 | 
			
		||||
    if(!f)
 | 
			
		||||
        return -errno;
 | 
			
		||||
 | 
			
		||||
    int res = 0;
 | 
			
		||||
    int line_num = 0;
 | 
			
		||||
    char line[1024];
 | 
			
		||||
    while(fgets(line, sizeof(line), f))
 | 
			
		||||
    {
 | 
			
		||||
        if(libbootimg_load_config_line(b, line) < 0)
 | 
			
		||||
        {
 | 
			
		||||
            res = -1;
 | 
			
		||||
            if(error_line)
 | 
			
		||||
                *error_line = line_num;
 | 
			
		||||
            goto exit;
 | 
			
		||||
        }
 | 
			
		||||
        ++line_num;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
exit:
 | 
			
		||||
    fclose(f);
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int libbootimg_load_config_line(struct bootimg *b, char *line)
 | 
			
		||||
{
 | 
			
		||||
    char *s, *e;
 | 
			
		||||
    char *name_e;
 | 
			
		||||
    char *arg_s;
 | 
			
		||||
    size_t n_to_cmp;
 | 
			
		||||
 | 
			
		||||
    for(s = line; isspace(*s); ++s);
 | 
			
		||||
 | 
			
		||||
    for(e = s+strlen(s)-1; isspace(*e); --e)
 | 
			
		||||
        *e = 0;
 | 
			
		||||
 | 
			
		||||
    if(*s == 0 || (name_e = strchr(s, '=')) == NULL)
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    arg_s = name_e+1;
 | 
			
		||||
 | 
			
		||||
    for(--name_e; isspace(*name_e); --name_e);
 | 
			
		||||
    for(++arg_s; isspace(*arg_s); ++arg_s);
 | 
			
		||||
 | 
			
		||||
    n_to_cmp = name_e-s;
 | 
			
		||||
 | 
			
		||||
    if(strncmp("bootsize", s, n_to_cmp) == 0)
 | 
			
		||||
        b->size = strtol(arg_s, NULL, 16);
 | 
			
		||||
    else if(strncmp("pagesize", s, n_to_cmp) == 0)
 | 
			
		||||
        b->hdr.page_size = strtol(arg_s, NULL, 16);
 | 
			
		||||
    else if(strncmp("kerneladdr", s, n_to_cmp) == 0)
 | 
			
		||||
        b->hdr.kernel_addr = strtol(arg_s, NULL, 16);
 | 
			
		||||
    else if(strncmp("ramdiskaddr", s, n_to_cmp) == 0)
 | 
			
		||||
        b->hdr.ramdisk_addr = strtol(arg_s, NULL, 16);
 | 
			
		||||
    else if(strncmp("secondaddr", s, n_to_cmp) == 0)
 | 
			
		||||
        b->hdr.second_addr = strtol(arg_s, NULL, 16);
 | 
			
		||||
    else if(strncmp("tagsaddr", s, n_to_cmp) == 0)
 | 
			
		||||
        b->hdr.tags_addr = strtol(arg_s, NULL, 16);
 | 
			
		||||
    else if(strncmp("name", s, n_to_cmp) == 0)
 | 
			
		||||
        strncpy((char*)b->hdr.name, arg_s, BOOT_NAME_SIZE);
 | 
			
		||||
    else if(strncmp("cmdline", s, n_to_cmp) == 0)
 | 
			
		||||
        strncpy((char*)b->hdr.cmdline, arg_s, BOOT_ARGS_SIZE);
 | 
			
		||||
    else
 | 
			
		||||
        return -1;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int libbootimg_write_config(struct bootimg *b, const char *dst)
 | 
			
		||||
{
 | 
			
		||||
    FILE *f = fopen(dst, "w");
 | 
			
		||||
    if(!f)
 | 
			
		||||
        return -errno;
 | 
			
		||||
 | 
			
		||||
    int res = fprintf(f,
 | 
			
		||||
        "bootsize = 0x%X\n"
 | 
			
		||||
        "pagesize = 0x%X\n"
 | 
			
		||||
        "kerneladdr = 0x%X\n"
 | 
			
		||||
        "ramdiskaddr = 0x%X\n"
 | 
			
		||||
        "secondaddr = 0x%X\n"
 | 
			
		||||
        "tagsaddr = 0x%X\n"
 | 
			
		||||
        "name = %s\n"
 | 
			
		||||
        "cmdline = %s\n",
 | 
			
		||||
        b->size, b->hdr.page_size, b->hdr.kernel_addr, b->hdr.ramdisk_addr,
 | 
			
		||||
        b->hdr.second_addr, b->hdr.tags_addr, b->hdr.name, b->hdr.cmdline);
 | 
			
		||||
 | 
			
		||||
    fclose(f);
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t libbootimg_version(void)
 | 
			
		||||
{
 | 
			
		||||
    return VERSION;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *libbootimg_version_str(void)
 | 
			
		||||
{
 | 
			
		||||
    return VERSION_STR;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										40
									
								
								libbootimg.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								libbootimg.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
#ifndef LIBBOOTIMG_H
 | 
			
		||||
#define LIBBOOTIMG_h
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "boot_img_hdr.h"
 | 
			
		||||
 | 
			
		||||
struct bootimg
 | 
			
		||||
{
 | 
			
		||||
    struct boot_img_hdr hdr;
 | 
			
		||||
    uint8_t *kernel;
 | 
			
		||||
    uint8_t *ramdisk;
 | 
			
		||||
    uint8_t *second;
 | 
			
		||||
    uint32_t size;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void libbootimg_init_new(struct bootimg *img);
 | 
			
		||||
int libbootimg_init_load(struct bootimg *img, const char *path);
 | 
			
		||||
void libbootimg_destroy(struct bootimg *b);
 | 
			
		||||
int libbootimg_load_header(struct boot_img_hdr *hdr, const char *path);
 | 
			
		||||
 | 
			
		||||
int libbootimg_dump_kernel(struct bootimg *b, const char *dest);
 | 
			
		||||
int libbootimg_dump_ramdisk(struct bootimg *b, const char *dest);
 | 
			
		||||
int libbootimg_dump_second(struct bootimg *b, const char *dest);
 | 
			
		||||
int libbootimg_dump(struct bootimg *b, const char *dest_dir);
 | 
			
		||||
 | 
			
		||||
int libbootimg_load_kernel(struct bootimg *b, const char *src);
 | 
			
		||||
int libbootimg_load_ramdisk(struct bootimg *b, const char *src);
 | 
			
		||||
int libbootimg_load_second(struct bootimg *b, const char *src);
 | 
			
		||||
 | 
			
		||||
int libbootimg_write_img(struct bootimg *b, const char *dest);
 | 
			
		||||
int libbootimg_write_img_and_destroy(struct bootimg *b, const char *dest);
 | 
			
		||||
 | 
			
		||||
int libbootimg_load_config(struct bootimg *b, const char *src, int *error_line);
 | 
			
		||||
int libbootimg_load_config_line(struct bootimg *b, char *line);
 | 
			
		||||
int libbootimg_write_config(struct bootimg *b, const char *dst);
 | 
			
		||||
 | 
			
		||||
uint32_t libbootimg_version(void);
 | 
			
		||||
const char *libbootimg_version_str(void);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
		Reference in New Issue
	
	Block a user