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