svn commit: r296564 - in head/sys/boot/uboot: common lib

Stanislav Galabov sgalabov at FreeBSD.org
Wed Mar 9 11:45:50 UTC 2016


Author: sgalabov
Date: Wed Mar  9 11:45:48 2016
New Revision: 296564
URL: https://svnweb.freebsd.org/changeset/base/296564

Log:
  Improve U-Boot API detection
  
  Until now, ubldr has been trying to locate the U-Boot API using a hint
  address (U-Boot's current stack pointer), aligning it to 1MiB and going
  over a 3MiB (or 1MiB in case of MIPS) memory region searching for a
  valid API signature.
  
  This change introduces an alternative way of doing this, namely the
  following:
  - both U-Boot's bootelf and go commands actually pass argc and argv to
    the entry point (e.g., ubldr's start function, but they should also
    be passed over to main() transparently)
  - so, instead of trying to go and look for a valid API signature, we
    look at the parameters passed to main()
  - if there's an option '-a' with argument, which is a valid hexadecimal
    unsigned  long number (x), we try to verify whether we have a valid
    API signature at address x. If so - we use it. If not - we fallback
    to the original way of locating the API signature.
  
  The U-Boot change, which causes the API structure address to be
  exported as an environment variable, was committed to mainline U-Boot
  as commit 22aa61f707574dd569296f521fcfc46a05f51c48
  
  Reviewed by:	andrew, adrian
  Approved by:	adrian (mentor)
  Sponsored by:	Smartcom - Bulgaria AD
  Differential Revision:	https://reviews.freebsd.org/D5492

Modified:
  head/sys/boot/uboot/common/main.c
  head/sys/boot/uboot/lib/glue.c
  head/sys/boot/uboot/lib/glue.h

Modified: head/sys/boot/uboot/common/main.c
==============================================================================
--- head/sys/boot/uboot/common/main.c	Wed Mar  9 11:16:15 2016	(r296563)
+++ head/sys/boot/uboot/common/main.c	Wed Mar  9 11:45:48 2016	(r296564)
@@ -387,7 +387,7 @@ probe_disks(int devidx, int load_type, i
 }
 
 int
-main(void)
+main(int argc, char **argv)
 {
 	struct api_signature *sig = NULL;
 	int load_type, load_unit, load_slice, load_partition;
@@ -395,12 +395,15 @@ main(void)
 	const char *ldev;
 
 	/*
+	 * We first check if a command line argument was passed to us containing
+	 * API's signature address. If it wasn't then we try to search for the
+	 * API signature via the usual hinted address.
 	 * If we can't find the magic signature and related info, exit with a
 	 * unique error code that U-Boot reports as "## Application terminated,
 	 * rc = 0xnnbadab1". Hopefully 'badab1' looks enough like "bad api" to
 	 * provide a clue. It's better than 0xffffffff anyway.
 	 */
-	if (!api_search_sig(&sig))
+	if (!api_parse_cmdline_sig(argc, argv, &sig) && !api_search_sig(&sig))
 		return (0x01badab1);
 
 	syscall_ptr = sig->syscall;

Modified: head/sys/boot/uboot/lib/glue.c
==============================================================================
--- head/sys/boot/uboot/lib/glue.c	Wed Mar  9 11:16:15 2016	(r296563)
+++ head/sys/boot/uboot/lib/glue.c	Wed Mar  9 11:45:48 2016	(r296564)
@@ -68,6 +68,41 @@ valid_sig(struct api_signature *sig)
 }
 
 /*
+ * Checks to see if API signature's address was given to us as a command line
+ * argument by U-Boot.
+ *
+ * returns 1/0 depending on found/not found result
+ */
+int
+api_parse_cmdline_sig(int argc, char **argv, struct api_signature **sig)
+{
+	unsigned long api_address;
+	int c;
+
+	api_address = 0;
+	opterr = 0;
+	optreset = 1;
+	optind = 1;
+
+	while ((c = getopt (argc, argv, "a:")) != -1)
+		switch (c) {
+		case 'a':
+			api_address = strtoul(optarg, NULL, 16);
+			break;
+		default:
+			break;
+		}
+
+	if (api_address != 0) {
+		*sig = (struct api_signature *)api_address;
+		if (valid_sig(*sig))
+			return (1);
+	}
+
+	return (0);
+}
+
+/*
  * Searches for the U-Boot API signature
  *
  * returns 1/0 depending on found/not found result

Modified: head/sys/boot/uboot/lib/glue.h
==============================================================================
--- head/sys/boot/uboot/lib/glue.h	Wed Mar  9 11:16:15 2016	(r296563)
+++ head/sys/boot/uboot/lib/glue.h	Wed Mar  9 11:45:48 2016	(r296564)
@@ -58,6 +58,7 @@
 int syscall(int, int *, ...);
 void *syscall_ptr;
 
+int api_parse_cmdline_sig(int argc, char **argv, struct api_signature **sig);
 int api_search_sig(struct api_signature **sig);
 
 #define	UB_MAX_MR	16		/* max mem regions number */


More information about the svn-src-all mailing list