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 */
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to