From patchwork Thu Feb 27 20:26:15 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 324928 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 5606B2C038C for ; Fri, 28 Feb 2014 07:32:01 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 47CC04B671; Thu, 27 Feb 2014 21:31:57 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id PZ4xRbVjuGM8; Thu, 27 Feb 2014 21:31:56 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 15BCA4B677; Thu, 27 Feb 2014 21:28:53 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 7267B4B663 for ; Thu, 27 Feb 2014 21:28:47 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id RLMz9Kbys-6W for ; Thu, 27 Feb 2014 21:28:43 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-yk0-f201.google.com (mail-yk0-f201.google.com [209.85.160.201]) by theia.denx.de (Postfix) with ESMTPS id 75D514B5D6 for ; Thu, 27 Feb 2014 21:28:16 +0100 (CET) Received: by mail-yk0-f201.google.com with SMTP id 142so1180930ykq.0 for ; Thu, 27 Feb 2014 12:28:15 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=3DBhN/4bM5mu8UAzmqvp8nQwi9h9i76Ty5R1x6seAgI=; b=SeK8PjHQyaXfOAlF4vaKyMh6oCBVdvcxth3zdK7mqKNySa7UiqATCuj+XQf2Dsb8Es rrgzKPMwnOPeAUzXgcFPk7iw3gYBPuapyLK/XfLNPr1ONydZUrmrDlPOVsQK807HCv5V iwctgTpM5T0VbW+v0chH9sc27X2GiS0kK/6eq7Ia7SCQkBlIkTDeNWQF1ldN73AWbECW 1+By1FL5MnEpOv63qyH9kJLALPFSFBHeZonuKDL3m5gT3WRLcgDhuPZmEELymLtiqq7f DyPVEsvxxfxgklAthkmB5WCBPmHFyd6LfMSt4Ydm5QJ1MeGCAy3iEm835SY/bz1cr2Md 8sow== X-Gm-Message-State: ALoCoQlm/TrkSP2rGnl99OXo7Z9VTLgj5ySv48LoMHoZp6Rgq7XXR4CTOiQSLDtl3r/v37Uxst18Sm4wRBc3JN3XnqDQ0zUrRMAedKNzCdg9aADeZtIwOhAGZ/agn5TrKzRH8NVV/T05+blBc++Y9w419yfk1kr2RYO116XroMP5N4EWCwgv5+RIAL+2FImPt2qPowhLOGHn X-Received: by 10.236.85.100 with SMTP id t64mr4777151yhe.29.1393532895309; Thu, 27 Feb 2014 12:28:15 -0800 (PST) Received: from corp2gmr1-1.hot.corp.google.com (corp2gmr1-1.hot.corp.google.com [172.24.189.92]) by gmr-mx.google.com with ESMTPS id o7si951328yhj.3.2014.02.27.12.28.15 for (version=TLSv1.1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 27 Feb 2014 12:28:15 -0800 (PST) Received: from kaki.bld.corp.google.com (kaki.bld.corp.google.com [172.29.216.32]) by corp2gmr1-1.hot.corp.google.com (Postfix) with ESMTP id 2A5E531C1CD; Thu, 27 Feb 2014 12:28:15 -0800 (PST) Received: by kaki.bld.corp.google.com (Postfix, from userid 121222) id 0A8B822178A; Thu, 27 Feb 2014 13:28:15 -0700 (MST) From: Simon Glass To: U-Boot Mailing List Date: Thu, 27 Feb 2014 13:26:15 -0700 Message-Id: <1393532785-9020-22-git-send-email-sjg@chromium.org> X-Mailer: git-send-email 1.9.0.279.gdc9e3eb In-Reply-To: <1393532785-9020-1-git-send-email-sjg@chromium.org> References: <1393532785-9020-1-git-send-email-sjg@chromium.org> Cc: u-boot-review@google.com Subject: [U-Boot] [PATCH v2 21/31] sandbox: Add os_jump_to_image() to run another executable X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de For some tests it is useful to be able to run U-Boot again but pass on the same memory contents. Add a function to achieve this. Reviewed-by: Simon Glass Signed-off-by: Simon Glass --- Changes in v2: None arch/sandbox/cpu/os.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/os.h | 19 +++++++++++ 2 files changed, 108 insertions(+) diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index 2e2fc58..460ed88 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -438,3 +438,92 @@ int os_read_ram_buf(const char *fname) return 0; } + +static int make_exec(char *fname, const void *data, int size) +{ + int fd; + + strcpy(fname, "/tmp/u-boot.jump.XXXXXX"); + fd = mkstemp(fname); + if (fd < 0) + return -ENOENT; + if (write(fd, data, size) < 0) + return -EIO; + close(fd); + if (chmod(fname, 0777)) + return -ENOEXEC; + + return 0; +} + +static int add_args(char ***argvp, const char *add_args[], int count) +{ + char **argv; + int argc; + + for (argv = *argvp, argc = 0; (*argvp)[argc]; argc++) + ; + + argv = malloc((argc + count + 1) * sizeof(char *)); + if (!argv) { + printf("Out of memory for %d argv\n", count); + return -ENOMEM; + } + memcpy(argv, *argvp, argc * sizeof(char *)); + memcpy(argv + argc, add_args, count * sizeof(char *)); + argv[argc + count] = NULL; + + *argvp = argv; + return 0; +} + +int os_jump_to_image(const void *dest, int size) +{ + struct sandbox_state *state = state_get_current(); + char fname[30], mem_fname[30]; + int fd, err; + const char *extra_args[4]; + char **argv = state->argv; +#ifdef DEBUG + int argc, i; +#endif + + err = make_exec(fname, dest, size); + if (err) + return err; + + strcpy(mem_fname, "/tmp/u-boot.mem.XXXXXX"); + fd = mkstemp(mem_fname); + if (fd < 0) + return -ENOENT; + close(fd); + err = os_write_ram_buf(mem_fname); + if (err) + return err; + + os_fd_restore(); + + extra_args[0] = "-j"; + extra_args[1] = fname; + extra_args[2] = "-m"; + extra_args[3] = mem_fname; + err = add_args(&argv, extra_args, + sizeof(extra_args) / sizeof(extra_args[0])); + if (err) + return err; + +#ifdef DEBUG + for (i = 0; argv[i]; i++) + printf("%d %s\n", i, argv[i]); +#endif + + if (state_uninit()) + os_exit(2); + + err = execv(fname, argv); + free(argv); + if (err) + return err; + + return unlink(fname); +} diff --git a/include/os.h b/include/os.h index d6d6e57..ac8c8bb 100644 --- a/include/os.h +++ b/include/os.h @@ -245,4 +245,23 @@ int os_write_ram_buf(const char *fname); */ int os_read_ram_buf(const char *fname); +/** + * Jump to a new executable image + * + * This uses exec() to run a new executable image, after putting it in a + * temporary file. The same arguments and environment are passed to this + * new image, with the addition of: + * + * -j Specifies the filename the image was written to. The + * calling image may want to delete this at some point. + * -m Specifies the file containing the sandbox memory + * (ram_buf) from this image, so that the new image can + * have access to this. It also means that the original + * memory filename passed to U-Boot will be left intact. + * + * @param dest Buffer containing executable image + * @param size Size of buffer + */ +int os_jump_to_image(const void *dest, int size); + #endif