Refactor kexec loading, add support for standalone dtb.img
This commit is contained in:
		@@ -23,7 +23,8 @@ LOCAL_SRC_FILES:= \
 | 
				
			|||||||
    fstab.c \
 | 
					    fstab.c \
 | 
				
			||||||
    workers.c \
 | 
					    workers.c \
 | 
				
			||||||
    containers.c \
 | 
					    containers.c \
 | 
				
			||||||
    rom_quirks.c
 | 
					    rom_quirks.c \
 | 
				
			||||||
 | 
					    kexec.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifeq ($(ARCH_ARM_HAVE_NEON),true)
 | 
					ifeq ($(ARCH_ARM_HAVE_NEON),true)
 | 
				
			||||||
    LOCAL_SRC_FILES += col32cb16blend_neon.S
 | 
					    LOCAL_SRC_FILES += col32cb16blend_neon.S
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										114
									
								
								kexec.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								kexec.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,114 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This file is part of MultiROM.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * MultiROM is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * MultiROM is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with MultiROM.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "kexec.h"
 | 
				
			||||||
 | 
					#include "containers.h"
 | 
				
			||||||
 | 
					#include "log.h"
 | 
				
			||||||
 | 
					#include "util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// kexec --load-hardboot ./zImage --command-line="$(cat /proc/cmdline)" --mem-min=0xA0000000 --initrd=./rd.img
 | 
				
			||||||
 | 
					// --mem-min should be somewhere in System RAM (see /proc/iomem). Location just above kernel seems to work fine.
 | 
				
			||||||
 | 
					// It must not conflict with vmalloc ram. Vmalloc area seems to be allocated from top of System RAM.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void kexec_init(struct kexec *k, const char *path)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    k->args = NULL;
 | 
				
			||||||
 | 
					    kexec_add_arg(k, path);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void kexec_destroy(struct kexec *k)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    list_clear(&k->args, &free);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int kexec_load_exec(struct kexec *k)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i, len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    INFO("Loading kexec:\n");
 | 
				
			||||||
 | 
					    for(i = 0; k->args && k->args[i]; ++i)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        len = strlen(k->args[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(len < 480)
 | 
				
			||||||
 | 
					            INFO("    %s\n", k->args[i]);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            char buff[481];
 | 
				
			||||||
 | 
					            char *itr;
 | 
				
			||||||
 | 
					            const char *end = k->args[i]+len;
 | 
				
			||||||
 | 
					            int chunk = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for(itr = k->args[i]; itr < end; itr += chunk)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                chunk = imin(480, end - itr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                memcpy(buff, itr, chunk);
 | 
				
			||||||
 | 
					                buff[chunk] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                INFO("    %s\n", buff);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(run_cmd(k->args) == 0)
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ERROR("kexec call failed, re-running it to get info:\n");
 | 
				
			||||||
 | 
					        char *r = run_get_stdout(k->args);
 | 
				
			||||||
 | 
					        if(!r)
 | 
				
			||||||
 | 
					            ERROR("run_get_stdout returned NULL!\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        char *p = strtok(r, "\n\r");
 | 
				
			||||||
 | 
					        while(p)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            ERROR("  %s\n", p);
 | 
				
			||||||
 | 
					            p = strtok(NULL, "\n\r");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        free(r);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void kexec_add_arg(struct kexec *k, const char *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    list_add(strdup(arg), &k->args);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void kexec_add_arg_prefix(struct kexec *k, const char *prefix, const char *value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int len = strlen(prefix) + strlen(value) + 1;
 | 
				
			||||||
 | 
					    char *arg = malloc(len);
 | 
				
			||||||
 | 
					    snprintf(arg, len, "%s%s", prefix, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    list_add(arg, &k->args);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void kexec_add_kernel(struct kexec *k, const char *path, int hardboot)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if(hardboot)
 | 
				
			||||||
 | 
					        kexec_add_arg(k, "--load-hardboot");
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        kexec_add_arg(k, "-l");
 | 
				
			||||||
 | 
					    kexec_add_arg(k, path);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										33
									
								
								kexec.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								kexec.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This file is part of MultiROM.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * MultiROM is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * MultiROM is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with MultiROM.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef KEXEC_H
 | 
				
			||||||
 | 
					#define KEXEC_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct kexec
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    char **args;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void kexec_init(struct kexec *k, const char *path);
 | 
				
			||||||
 | 
					void kexec_destroy(struct kexec *k);
 | 
				
			||||||
 | 
					int kexec_load_exec(struct kexec *k);
 | 
				
			||||||
 | 
					void kexec_add_arg(struct kexec *k, const char *arg);
 | 
				
			||||||
 | 
					void kexec_add_arg_prefix(struct kexec *k, const char *prefix, const char *value);
 | 
				
			||||||
 | 
					void kexec_add_kernel(struct kexec *k, const char *path, int hardboot);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										152
									
								
								multirom.c
									
									
									
									
									
								
							
							
						
						
									
										152
									
								
								multirom.c
									
									
									
									
									
								
							@@ -47,6 +47,7 @@
 | 
				
			|||||||
#include "hooks.h"
 | 
					#include "hooks.h"
 | 
				
			||||||
#include "containers.h"
 | 
					#include "containers.h"
 | 
				
			||||||
#include "rom_quirks.h"
 | 
					#include "rom_quirks.h"
 | 
				
			||||||
 | 
					#include "kexec.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define REALDATA "/realdata"
 | 
					#define REALDATA "/realdata"
 | 
				
			||||||
#define BUSYBOX_BIN "busybox"
 | 
					#define BUSYBOX_BIN "busybox"
 | 
				
			||||||
@@ -1485,6 +1486,10 @@ int multirom_find_file(char *res, const char *name_part, const char *path)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int multirom_load_kexec(struct multirom_status *s, struct multirom_rom *rom)
 | 
					int multirom_load_kexec(struct multirom_status *s, struct multirom_rom *rom)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    int res = -1;
 | 
				
			||||||
 | 
					    struct kexec kexec;
 | 
				
			||||||
 | 
					    int loop_mounted = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // to find /data partition
 | 
					    // to find /data partition
 | 
				
			||||||
    if(!rom->partition && multirom_update_partitions(s) < 0)
 | 
					    if(!rom->partition && multirom_update_partitions(s) < 0)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -1492,35 +1497,20 @@ int multirom_load_kexec(struct multirom_status *s, struct multirom_rom *rom)
 | 
				
			|||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int res = -1;
 | 
					    kexec_init(&kexec, kexec_path);
 | 
				
			||||||
    // kexec --load-hardboot ./zImage --command-line="$(cat /proc/cmdline)" --mem-min=0xA0000000 --initrd=./rd.img
 | 
					    kexec_add_arg(&kexec, "--mem-min="MR_KEXEC_MEM_MIN);
 | 
				
			||||||
    // --mem-min should be somewhere in System RAM (see /proc/iomem). Location just above kernel seems to work fine.
 | 
					 | 
				
			||||||
    // It must not conflict with vmalloc ram. Vmalloc area seems to be allocated from top of System RAM.
 | 
					 | 
				
			||||||
    char *cmd[] = {
 | 
					 | 
				
			||||||
        kexec_path,                      // 0
 | 
					 | 
				
			||||||
        "--load-hardboot",               // 1
 | 
					 | 
				
			||||||
        malloc(1024),                    // 2 - path to zImage
 | 
					 | 
				
			||||||
        "--mem-min="MR_KEXEC_MEM_MIN,    // 3
 | 
					 | 
				
			||||||
        malloc(1024),                    // 4 - --initrd=<path to initrd>
 | 
					 | 
				
			||||||
        malloc(2048),                    // 5 - --command-line=<cmdline>
 | 
					 | 
				
			||||||
#ifdef MR_KEXEC_DTB
 | 
					 | 
				
			||||||
        "--dtb",                         // 6
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        NULL
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int loop_mounted = 0;
 | 
					 | 
				
			||||||
    switch(rom->type)
 | 
					    switch(rom->type)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        case ROM_ANDROID_INTERNAL:
 | 
					        case ROM_ANDROID_INTERNAL:
 | 
				
			||||||
        case ROM_ANDROID_USB_DIR:
 | 
					        case ROM_ANDROID_USB_DIR:
 | 
				
			||||||
        case ROM_ANDROID_USB_IMG:
 | 
					        case ROM_ANDROID_USB_IMG:
 | 
				
			||||||
            if(multirom_fill_kexec_android(s, rom, cmd) != 0)
 | 
					            if(multirom_fill_kexec_android(s, rom, &kexec) != 0)
 | 
				
			||||||
                goto exit;
 | 
					                goto exit;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case ROM_LINUX_INTERNAL:
 | 
					        case ROM_LINUX_INTERNAL:
 | 
				
			||||||
        case ROM_LINUX_USB:
 | 
					        case ROM_LINUX_USB:
 | 
				
			||||||
            loop_mounted = multirom_fill_kexec_linux(s, rom, cmd);
 | 
					            loop_mounted = multirom_fill_kexec_linux(s, rom, &kexec);
 | 
				
			||||||
            if(loop_mounted < 0)
 | 
					            if(loop_mounted < 0)
 | 
				
			||||||
                goto exit;
 | 
					                goto exit;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
@@ -1529,36 +1519,7 @@ int multirom_load_kexec(struct multirom_status *s, struct multirom_rom *rom)
 | 
				
			|||||||
            goto exit;
 | 
					            goto exit;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ERROR("Loading kexec: %s %s %s %s %s\n", cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]);
 | 
					    res = kexec_load_exec(&kexec);
 | 
				
			||||||
    ERROR("With cmdline: ");
 | 
					 | 
				
			||||||
    char *itr = cmd[5];
 | 
					 | 
				
			||||||
    int len;
 | 
					 | 
				
			||||||
    for(len = strlen(itr); len > 0; len = strlen(itr))
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
       if(len > 450)
 | 
					 | 
				
			||||||
           len = 450;
 | 
					 | 
				
			||||||
       char *b = strndup(itr, len);
 | 
					 | 
				
			||||||
       ERROR("  %s\n", b);
 | 
					 | 
				
			||||||
       free(b);
 | 
					 | 
				
			||||||
       itr += len;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if(run_cmd(cmd) == 0)
 | 
					 | 
				
			||||||
        res = 0;
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        ERROR("kexec call failed, re-running it to get info:\n");
 | 
					 | 
				
			||||||
        char *r = run_get_stdout(cmd);
 | 
					 | 
				
			||||||
        if(!r)
 | 
					 | 
				
			||||||
            ERROR("run_get_stdout returned NULL!\n");
 | 
					 | 
				
			||||||
        char *p = strtok(r, "\n\r");
 | 
					 | 
				
			||||||
        while(p)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            ERROR("  %s\n", p);
 | 
					 | 
				
			||||||
            p = strtok(NULL, "\n\r");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        free(r);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    char *cmd_cp[] = { busybox_path, "cp", kexec_path, "/kexec", NULL };
 | 
					    char *cmd_cp[] = { busybox_path, "cp", kexec_path, "/kexec", NULL };
 | 
				
			||||||
    run_cmd(cmd_cp);
 | 
					    run_cmd(cmd_cp);
 | 
				
			||||||
@@ -1570,13 +1531,11 @@ int multirom_load_kexec(struct multirom_status *s, struct multirom_rom *rom)
 | 
				
			|||||||
    multirom_copy_log(NULL);
 | 
					    multirom_copy_log(NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
exit:
 | 
					exit:
 | 
				
			||||||
    free(cmd[2]);
 | 
					    kexec_destroy(&kexec);
 | 
				
			||||||
    free(cmd[4]);
 | 
					 | 
				
			||||||
    free(cmd[5]);
 | 
					 | 
				
			||||||
    return res;
 | 
					    return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int multirom_fill_kexec_android(struct multirom_status *s, struct multirom_rom *rom, char **cmd)
 | 
					int multirom_fill_kexec_android(struct multirom_status *s, struct multirom_rom *rom, struct kexec *kexec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int res = -1;
 | 
					    int res = -1;
 | 
				
			||||||
    char img_path[256];
 | 
					    char img_path[256];
 | 
				
			||||||
@@ -1591,9 +1550,20 @@ int multirom_fill_kexec_android(struct multirom_status *s, struct multirom_rom *
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if(libbootimg_dump_kernel(&img, "/zImage") < 0)
 | 
					    if(libbootimg_dump_kernel(&img, "/zImage") < 0)
 | 
				
			||||||
        goto exit;
 | 
					        goto exit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(libbootimg_dump_ramdisk(&img, "/initrd.img") < 0)
 | 
					    if(libbootimg_dump_ramdisk(&img, "/initrd.img") < 0)
 | 
				
			||||||
        goto exit;
 | 
					        goto exit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    kexec_add_kernel(kexec, "/zImage", 1);
 | 
				
			||||||
 | 
					    kexec_add_arg(kexec, "--initrd=/initrd.img");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef MR_KEXEC_DTB
 | 
				
			||||||
 | 
					    if(libbootimg_dump_dtb(&img, "/dtb.img") >= 0)
 | 
				
			||||||
 | 
					        kexec_add_arg(kexec, "--dtb=/dtb.img");
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        kexec_add_arg(kexec, "--dtb");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Trampolines in ROM boot images may get out of sync, so we need to check it and
 | 
					    // Trampolines in ROM boot images may get out of sync, so we need to check it and
 | 
				
			||||||
    // update if needed. I can't do that during ZIP installation because of USB drives.
 | 
					    // update if needed. I can't do that during ZIP installation because of USB drives.
 | 
				
			||||||
    // That header.name is added by recovery.
 | 
					    // That header.name is added by recovery.
 | 
				
			||||||
@@ -1624,35 +1594,32 @@ int multirom_fill_kexec_android(struct multirom_status *s, struct multirom_rom *
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    char cmdline[1024];
 | 
					    char cmdline[1536];
 | 
				
			||||||
    if(multirom_get_bootloader_cmdline(s, cmdline, sizeof(cmdline)) == -1)
 | 
					    strcpy(cmdline, "--command-line=");
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        ERROR("Failed to get cmdline\n");
 | 
					 | 
				
			||||||
        goto exit;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    strcpy(cmd[2], "/zImage");
 | 
					 | 
				
			||||||
    strcpy(cmd[4], "--initrd=/initrd.img");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    strcpy(cmd[5], "--command-line=");
 | 
					 | 
				
			||||||
    if(img.hdr.cmdline[0] != 0)
 | 
					    if(img.hdr.cmdline[0] != 0)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        img.hdr.cmdline[BOOT_ARGS_SIZE-1] = 0;
 | 
					        img.hdr.cmdline[BOOT_ARGS_SIZE-1] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // see multirom_get_bootloader_cmdline
 | 
					        // see multirom_get_bootloader_cmdline
 | 
				
			||||||
#ifdef FLO_CMDLINE_HACK
 | 
					#ifdef FLO_CMDLINE_HACK
 | 
				
			||||||
        strcat(cmd[5], (char*)img.hdr.cmdline+26);
 | 
					        strcat(cmdline, (char*)img.hdr.cmdline+26);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
        strcat(cmd[5], (char*)img.hdr.cmdline);
 | 
					        strcat(cmdline, (char*)img.hdr.cmdline);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
        strcat(cmd[5], " ");
 | 
					        strcat(cmdline, " ");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if(cmdline[0] != 0)
 | 
					
 | 
				
			||||||
 | 
					    if(multirom_get_bootloader_cmdline(s, cmdline+strlen(cmdline), sizeof(cmdline)-strlen(cmdline)-1) == -1)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        strcat(cmd[5], cmdline);
 | 
					        ERROR("Failed to get cmdline\n");
 | 
				
			||||||
        strcat(cmd[5], " ");
 | 
					        goto exit;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    strcat(cmd[5], "mrom_kexecd=1");
 | 
					
 | 
				
			||||||
 | 
					    if(sizeof(cmdline)-strlen(cmdline)-1 >= sizeof("mrom_kexecd=1"))
 | 
				
			||||||
 | 
					        strcat(cmdline, "mrom_kexecd=1");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    kexec_add_arg(kexec, cmdline);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    res = 0;
 | 
					    res = 0;
 | 
				
			||||||
exit:
 | 
					exit:
 | 
				
			||||||
@@ -1693,7 +1660,7 @@ static char *find_boot_file(char *path, char *root_path, char *base_path)
 | 
				
			|||||||
    return strdup(res);
 | 
					    return strdup(res);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int multirom_fill_kexec_linux(struct multirom_status *s, struct multirom_rom *rom, char **cmd)
 | 
					int multirom_fill_kexec_linux(struct multirom_status *s, struct multirom_rom *rom, struct kexec *kexec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    struct rom_info *info = multirom_parse_rom_info(s, rom);
 | 
					    struct rom_info *info = multirom_parse_rom_info(s, rom);
 | 
				
			||||||
    if(!info)
 | 
					    if(!info)
 | 
				
			||||||
@@ -1754,24 +1721,49 @@ int multirom_fill_kexec_linux(struct multirom_status *s, struct multirom_rom *ro
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    char *str = find_boot_file(map_get_val(info->str_vals, "kernel_path"), root_path, rom->base_path);
 | 
					    char *str = find_boot_file(map_get_val(info->str_vals, "kernel_path"), root_path, rom->base_path);
 | 
				
			||||||
    if(!str)
 | 
					    if(str)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        kexec_add_kernel(kexec, str, 1);
 | 
				
			||||||
 | 
					        free(str);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // kernel is required
 | 
				
			||||||
        goto exit;
 | 
					        goto exit;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    cmd[2] = str;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    str = find_boot_file(map_get_val(info->str_vals, "initrd_path"), root_path, rom->base_path);
 | 
					    str = find_boot_file(map_get_val(info->str_vals, "initrd_path"), root_path, rom->base_path);
 | 
				
			||||||
    if(str)
 | 
					    if(str)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        sprintf(cmd[4], "--initrd=%s", str);
 | 
					        kexec_add_arg_prefix(kexec, "--initrd=", str);
 | 
				
			||||||
        free(str);
 | 
					        free(str);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sprintf(cmd[5], "--command-line=%s ", (char*)map_get_val(info->str_vals, "base_cmdline"));
 | 
					    char cmdline[1536];
 | 
				
			||||||
 | 
					    snprintf(cmdline, sizeof(cmdline), "--command-line=%s ", (char*)map_get_val(info->str_vals, "base_cmdline"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(root_type == 0 && (str = map_get_val(info->str_vals, "dir_cmdline")))
 | 
					    str = NULL;
 | 
				
			||||||
        strcat(cmd[5], str);
 | 
					    if(root_type == 0)
 | 
				
			||||||
    else if(root_type == 1 && (str = map_get_val(info->str_vals, "img_cmdline")))
 | 
					        str = map_get_val(info->str_vals, "dir_cmdline");
 | 
				
			||||||
        strcat(cmd[5], str);
 | 
					    else if(root_type == 1)
 | 
				
			||||||
 | 
					        str = map_get_val(info->str_vals, "img_cmdline");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(str)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if(strlen(str)+strlen(cmdline)+1 <= sizeof(cmdline))
 | 
				
			||||||
 | 
					            strcat(cmdline, str);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            ERROR("failed to fill kexec info, cmdline is too long!\n");
 | 
				
			||||||
 | 
					            goto exit;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    kexec_add_arg(kexec, cmdline);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef MR_KEXEC_DTB
 | 
				
			||||||
 | 
					    kexec_add_arg(kexec, "--dtb");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    res = loop_mounted;
 | 
					    res = loop_mounted;
 | 
				
			||||||
exit:
 | 
					exit:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,6 +23,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "fstab.h"
 | 
					#include "fstab.h"
 | 
				
			||||||
#include "containers.h"
 | 
					#include "containers.h"
 | 
				
			||||||
 | 
					#include "kexec.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum
 | 
					enum
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -139,8 +140,8 @@ int multirom_has_kexec(void);
 | 
				
			|||||||
int multirom_load_kexec(struct multirom_status *s, struct multirom_rom *rom);
 | 
					int multirom_load_kexec(struct multirom_status *s, struct multirom_rom *rom);
 | 
				
			||||||
int multirom_get_bootloader_cmdline(struct multirom_status *s, char *str, size_t size);
 | 
					int multirom_get_bootloader_cmdline(struct multirom_status *s, char *str, size_t size);
 | 
				
			||||||
int multirom_find_file(char *res, const char *name_part, const char *path);
 | 
					int multirom_find_file(char *res, const char *name_part, const char *path);
 | 
				
			||||||
int multirom_fill_kexec_linux(struct multirom_status *s, struct multirom_rom *rom, char **cmd);
 | 
					int multirom_fill_kexec_linux(struct multirom_status *s, struct multirom_rom *rom, struct kexec *kexec);
 | 
				
			||||||
int multirom_fill_kexec_android(struct multirom_status *s, struct multirom_rom *rom, char **cmd);
 | 
					int multirom_fill_kexec_android(struct multirom_status *s, struct multirom_rom *rom, struct kexec *kexec);
 | 
				
			||||||
int multirom_extract_bytes(const char *dst, FILE *src, size_t size);
 | 
					int multirom_extract_bytes(const char *dst, FILE *src, size_t size);
 | 
				
			||||||
int multirom_update_partitions(struct multirom_status *s);
 | 
					int multirom_update_partitions(struct multirom_status *s);
 | 
				
			||||||
void multirom_destroy_partition(void *part);
 | 
					void multirom_destroy_partition(void *part);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user