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
This commit is contained in:
parent
7370229e8d
commit
08190ef7de
@ -387,7 +387,7 @@ probe_disks(int devidx, int load_type, int load_unit, int load_slice,
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -67,6 +67,41 @@ valid_sig(struct api_signature *sig)
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user