mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-18 10:35:55 +00:00
ARM: Parse command line delivered by U-Boot:
- in atags - in DT blob (by using 'fdt chosen' U-Boot command) The command line must start with guard's string 'FreeBSD:' and can contain list of comma separated kenv strings. Also, boot modifier strings from boot.h are recognised and parsed into boothowto. The command line must be passed from U-Boot by setting of bootargs variable: 'setenv bootargs FreeBSD:boot_single=1,vfs.root.mountfrom=ufs:/dev/ada0s1a' followed by 'fdt chosen' (only for DT based boot)
This commit is contained in:
parent
f5c06c61e4
commit
e64c374375
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=297286
@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/bus.h>
|
||||
#include <sys/cons.h>
|
||||
#include <sys/cpu.h>
|
||||
#include <sys/ctype.h>
|
||||
#include <sys/efi.h>
|
||||
#include <sys/exec.h>
|
||||
#include <sys/imgact.h>
|
||||
@ -74,6 +75,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/pcpu.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/boot.h>
|
||||
#include <sys/rwlock.h>
|
||||
#include <sys/sched.h>
|
||||
#include <sys/signalvar.h>
|
||||
@ -232,6 +234,7 @@ static struct pv_addr kernelstack;
|
||||
#if defined(LINUX_BOOT_ABI)
|
||||
#define LBABI_MAX_BANKS 10
|
||||
|
||||
#define CMDLINE_GUARD "FreeBSD:"
|
||||
uint32_t board_id;
|
||||
struct arm_lbabi_tag *atag_list;
|
||||
char linux_command_line[LBABI_MAX_COMMAND_LINE + 1];
|
||||
@ -1029,6 +1032,53 @@ pcpu0_init(void)
|
||||
}
|
||||
|
||||
#if defined(LINUX_BOOT_ABI)
|
||||
|
||||
/* Convert the U-Boot command line into FreeBSD kenv and boot options. */
|
||||
static void
|
||||
cmdline_set_env(char *cmdline, const char *guard)
|
||||
{
|
||||
char *cmdline_next, *env;
|
||||
size_t size, guard_len;
|
||||
int i;
|
||||
|
||||
size = strlen(cmdline);
|
||||
/* Skip leading spaces. */
|
||||
for (; isspace(*cmdline) && (size > 0); cmdline++)
|
||||
size--;
|
||||
|
||||
/* Test and remove guard. */
|
||||
if (guard != NULL && guard[0] != '\0') {
|
||||
guard_len = strlen(guard);
|
||||
if (strncasecmp(cmdline, guard, guard_len) != 0){
|
||||
init_static_kenv(cmdline, 0);
|
||||
return;
|
||||
|
||||
cmdline += guard_len;
|
||||
size -= guard_len;
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip leading spaces. */
|
||||
for (; isspace(*cmdline) && (size > 0); cmdline++)
|
||||
size--;
|
||||
|
||||
/* Replace ',' with '\0'. */
|
||||
/* TODO: implement escaping for ',' character. */
|
||||
cmdline_next = cmdline;
|
||||
while(strsep(&cmdline_next, ",") != NULL)
|
||||
;
|
||||
init_static_kenv(cmdline, 0);
|
||||
/* Parse boothowto. */
|
||||
for (i = 0; howto_names[i].ev != NULL; i++) {
|
||||
env = kern_getenv(howto_names[i].ev);
|
||||
if (env != NULL) {
|
||||
if (strtoul(env, NULL, 10) != 0)
|
||||
boothowto |= howto_names[i].mask;
|
||||
freeenv(env);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vm_offset_t
|
||||
linux_parse_boot_param(struct arm_boot_params *abp)
|
||||
{
|
||||
@ -1036,6 +1086,7 @@ linux_parse_boot_param(struct arm_boot_params *abp)
|
||||
uint32_t revision;
|
||||
uint64_t serial;
|
||||
int size;
|
||||
vm_offset_t lastaddr;
|
||||
#ifdef FDT
|
||||
struct fdt_header *dtb_ptr;
|
||||
uint32_t dtb_size;
|
||||
@ -1057,9 +1108,6 @@ linux_parse_boot_param(struct arm_boot_params *abp)
|
||||
return (fake_preload_metadata(abp, dtb_ptr, dtb_size));
|
||||
}
|
||||
#endif
|
||||
/* Old, ATAG based boot must have board type set. */
|
||||
if (abp->abp_r1 == 0)
|
||||
return (0);
|
||||
|
||||
board_id = abp->abp_r1;
|
||||
walker = (struct arm_lbabi_tag *)abp->abp_r2;
|
||||
@ -1089,10 +1137,9 @@ linux_parse_boot_param(struct arm_boot_params *abp)
|
||||
board_set_revision(revision);
|
||||
break;
|
||||
case ATAG_CMDLINE:
|
||||
/* XXX open question: Parse this for boothowto? */
|
||||
size = ATAG_SIZE(walker) -
|
||||
sizeof(struct arm_lbabi_header);
|
||||
size = min(size, sizeof(linux_command_line) - 1);
|
||||
size = min(size, LBABI_MAX_COMMAND_LINE);
|
||||
strncpy(linux_command_line, walker->u.tag_cmd.command,
|
||||
size);
|
||||
linux_command_line[size] = '\0';
|
||||
@ -1107,9 +1154,9 @@ linux_parse_boot_param(struct arm_boot_params *abp)
|
||||
bcopy(atag_list, atags,
|
||||
(char *)walker - (char *)atag_list + ATAG_SIZE(walker));
|
||||
|
||||
init_static_kenv(NULL, 0);
|
||||
|
||||
return fake_preload_metadata(abp, NULL, 0);
|
||||
lastaddr = fake_preload_metadata(abp, NULL, 0);
|
||||
cmdline_set_env(linux_command_line, CMDLINE_GUARD);
|
||||
return lastaddr;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1785,6 +1832,12 @@ initarm(struct arm_boot_params *abp)
|
||||
if (OF_init((void *)dtbp) != 0)
|
||||
panic("OF_init failed with the found device tree");
|
||||
|
||||
#if defined(LINUX_BOOT_ABI)
|
||||
if (fdt_get_chosen_bootargs(linux_command_line,
|
||||
LBABI_MAX_COMMAND_LINE) == 0)
|
||||
cmdline_set_env(linux_command_line, CMDLINE_GUARD);
|
||||
#endif
|
||||
|
||||
#ifdef EFI
|
||||
efihdr = (struct efi_map_header *)preload_search_info(kmdp,
|
||||
MODINFO_METADATA | MODINFOMD_EFI_MAP);
|
||||
|
@ -722,3 +722,16 @@ fdt_get_unit(device_t dev)
|
||||
|
||||
return (strtol(name,NULL,0));
|
||||
}
|
||||
|
||||
int
|
||||
fdt_get_chosen_bootargs(char *bootargs, size_t max_size)
|
||||
{
|
||||
phandle_t chosen;
|
||||
|
||||
chosen = OF_finddevice("/chosen");
|
||||
if (chosen == -1)
|
||||
return (ENXIO);
|
||||
if (OF_getprop(chosen, "bootargs", bootargs, max_size) == -1)
|
||||
return (ENXIO);
|
||||
return (0);
|
||||
}
|
@ -100,5 +100,6 @@ int fdt_parent_addr_cells(phandle_t);
|
||||
int fdt_reg_to_rl(phandle_t, struct resource_list *);
|
||||
int fdt_pm(phandle_t);
|
||||
int fdt_get_unit(device_t);
|
||||
int fdt_get_chosen_bootargs(char *bootargs, size_t max_size);
|
||||
|
||||
#endif /* _FDT_COMMON_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user