diff --git a/arch/arm/dts/am335x-phytec-phycard-som-mlo.dts b/arch/arm/dts/am335x-phytec-phycard-som-mlo.dts index 17d9152..f9ed627 100644 --- a/arch/arm/dts/am335x-phytec-phycard-som-mlo.dts +++ b/arch/arm/dts/am335x-phytec-phycard-som-mlo.dts @@ -9,6 +9,7 @@ #include "am33xx.dtsi" #include "am335x-phytec-phycard-som.dtsi" +#include "am33xx-strip.dtsi" / { model = "Phytec phyCARD AM335x"; diff --git a/arch/arm/dts/am335x-phytec-phycore-som-mlo.dts b/arch/arm/dts/am335x-phytec-phycore-som-mlo.dts index b08a59e..f70835f 100644 --- a/arch/arm/dts/am335x-phytec-phycore-som-mlo.dts +++ b/arch/arm/dts/am335x-phytec-phycore-som-mlo.dts @@ -9,6 +9,7 @@ #include "am33xx.dtsi" #include "am335x-phytec-phycore-som.dtsi" +#include "am33xx-strip.dtsi" / { model = "Phytec phyCORE AM335x"; diff --git a/arch/arm/dts/am335x-phytec-phyflex-som-mlo.dts b/arch/arm/dts/am335x-phytec-phyflex-som-mlo.dts index 5294ff5..736d7ef 100644 --- a/arch/arm/dts/am335x-phytec-phyflex-som-mlo.dts +++ b/arch/arm/dts/am335x-phytec-phyflex-som-mlo.dts @@ -9,6 +9,7 @@ #include "am33xx.dtsi" #include "am335x-phytec-phyflex-som.dtsi" +#include "am33xx-strip.dtsi" / { model = "Phytec phyFLEX AM335x"; diff --git a/arch/arm/dts/am33xx-strip.dtsi b/arch/arm/dts/am33xx-strip.dtsi new file mode 100644 index 0000000..3dc9a57 --- /dev/null +++ b/arch/arm/dts/am33xx-strip.dtsi @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2015 PHYTEC Messtechnik GmbH, + * Author: Wadim Egorov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/ { + aliases { + /delete-property/ i2c1; + /delete-property/ i2c2; + /delete-property/ mmc0; + /delete-property/ mmc1; + /delete-property/ mmc2; + /delete-property/ d_can0; + /delete-property/ d_can1; + }; +}; + +/delete-node/ &i2c1; +/delete-node/ &i2c2; +/delete-node/ &mmc2; +/delete-node/ &mmc3; +/delete-node/ &hwspinlock; +/delete-node/ &wdt2; +/delete-node/ &dcan0; +/delete-node/ &dcan1; +/delete-node/ &mailbox; +/delete-node/ &timer1; +/delete-node/ &timer2; +/delete-node/ &timer3; +/delete-node/ &timer4; +/delete-node/ &timer5; +/delete-node/ &timer6; +/delete-node/ &timer7; +/delete-node/ &spi1; +/delete-node/ &epwmss0; +/delete-node/ &epwmss1; +/delete-node/ &epwmss2; +/delete-node/ &lcdc; +/delete-node/ &tscadc; +/delete-node/ &sham; +/delete-node/ &aes; +/delete-node/ &mcasp0; +/delete-node/ &mcasp1; +/delete-node/ &rng; diff --git a/arch/arm/mach-omap/Kconfig b/arch/arm/mach-omap/Kconfig index 444ddf8..bc00d5b 100644 --- a/arch/arm/mach-omap/Kconfig +++ b/arch/arm/mach-omap/Kconfig @@ -110,6 +110,15 @@ default 0x80e80000 if MACH_OMAP343xSDP default 0x80e80000 if MACH_BEAGLE +config AM33XX_NET_BOOT + bool "enable AM335x network boot" + select ENVIRONMENT_VARIABLES + select NET_DHCP + select FS_TFTP + select DRIVER_NET_CPSW + default n + depends on ARCH_AM33XX && NET + config OMAP4_USBBOOT bool "enable booting from USB" default n diff --git a/arch/arm/mach-omap/am33xx_generic.c b/arch/arm/mach-omap/am33xx_generic.c index ee30351..7ce32f0 100644 --- a/arch/arm/mach-omap/am33xx_generic.c +++ b/arch/arm/mach-omap/am33xx_generic.c @@ -145,6 +145,9 @@ case 0x44: src = BOOTSOURCE_USB; break; + case 0x46: + src = BOOTSOURCE_NET; + break; default: src = BOOTSOURCE_UNKNOWN; } diff --git a/arch/arm/mach-omap/xload.c b/arch/arm/mach-omap/xload.c index 7c8c350..85c9120 100644 --- a/arch/arm/mach-omap/xload.c +++ b/arch/arm/mach-omap/xload.c @@ -13,6 +13,10 @@ #include #include #include +#include +#include +#include +#include struct omap_barebox_part *barebox_part; @@ -224,6 +228,45 @@ return buf; } +static void *am33xx_net_boot(void) +{ + void *buf = NULL; + int err; + int len; + struct dhcp_req_param dhcp_param; + const char *bootfile; + + am33xx_register_ethaddr(0, 0); + + memset(&dhcp_param, 0, sizeof(struct dhcp_req_param)); + dhcp_param.vendor_id = "am335x barebox-mlo"; + err = dhcp(20, &dhcp_param); + if (err) { + printf("dhcp failed\n"); + return NULL; + } + + err = mount(ip_to_string(net_get_serverip()), "tftp", "/", NULL); + if (err < 0) { + printf("Unable to mount.\n"); + return NULL; + } + + bootfile = getenv("bootfile"); + if (!bootfile) { + printf("bootfile not found.\n"); + return NULL; + } + + buf = read_file(bootfile, &len); + if (!buf) + printf("could not read %s.\n", bootfile); + + umount("/"); + + return buf; +} + /* * Replaces the default shell in xload configuration */ @@ -264,6 +307,14 @@ func = omap_serial_boot(); break; } + case BOOTSOURCE_NET: + if (IS_ENABLED(CONFIG_AM33XX_NET_BOOT)) { + printf("booting from NET\n"); + func = am33xx_net_boot(); + break; + } else { + printf("booting from network not enabled\n"); + } default: printf("unknown boot source. Fall back to nand\n"); func = omap_xload_boot_nand(barebox_part->nand_offset, diff --git a/commands/Kconfig b/commands/Kconfig index 25c77a8..bb6674e 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -1183,6 +1183,7 @@ config CMD_DHCP bool + select NET_DHCP prompt "dhcp" help DHCP client to obtain IP or boot params diff --git a/commands/Makefile b/commands/Makefile index b902f58..3698347 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -111,3 +111,4 @@ obj-$(CONFIG_CMD_NV) += nv.o obj-$(CONFIG_CMD_DEFAULTENV) += defaultenv.o obj-$(CONFIG_CMD_STATE) += state.o +obj-$(CONFIG_CMD_DHCP) += dhcp.o diff --git a/commands/dhcp.c b/commands/dhcp.c new file mode 100644 index 0000000..eb98bfc --- /dev/null +++ b/commands/dhcp.c @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2015 PHYTEC Messtechnik GmbH, + * Author: Wadim Egorov + * + * Based on work of Sascha Hauer . + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +static int do_dhcp(int argc, char *argv[]) +{ + int ret, opt; + int retries = DHCP_DEFAULT_RETRY; + struct dhcp_req_param dhcp_param; + + memset(&dhcp_param, 0, sizeof(struct dhcp_req_param)); + getenv_uint("global.dhcp.retries", &retries); + + while ((opt = getopt(argc, argv, "H:v:c:u:U:r:")) > 0) { + switch (opt) { + case 'H': + dhcp_param.hostname = optarg; + break; + case 'v': + dhcp_param.vendor_id = optarg; + break; + case 'c': + dhcp_param.client_id = optarg; + break; + case 'u': + dhcp_param.client_uuid = optarg; + break; + case 'U': + dhcp_param.user_class = optarg; + break; + case 'r': + retries = simple_strtoul(optarg, NULL, 10); + break; + } + } + + if (!retries) { + printf("retries is set to zero, set it to %d\n", DHCP_DEFAULT_RETRY); + retries = DHCP_DEFAULT_RETRY; + } + + ret = dhcp(retries, &dhcp_param); + + return ret; +} + +BAREBOX_CMD_HELP_START(dhcp) +BAREBOX_CMD_HELP_TEXT("Options:") +BAREBOX_CMD_HELP_OPT("-H HOSTNAME", "hostname to send to the DHCP server") +BAREBOX_CMD_HELP_OPT("-v ID\t", "DHCP Vendor ID (code 60) submitted in DHCP requests") +BAREBOX_CMD_HELP_OPT("-c ID\t", "DHCP Client ID (code 61) submitted in DHCP requests") +BAREBOX_CMD_HELP_OPT("-u UUID\t", "DHCP Client UUID (code 97) submitted in DHCP requests") +BAREBOX_CMD_HELP_OPT("-U CLASS", "DHCP User class (code 77) submitted in DHCP requests") +BAREBOX_CMD_HELP_OPT("-r RETRY", "retry limit (default 20)"); +BAREBOX_CMD_HELP_END + +BAREBOX_CMD_START(dhcp) + .cmd = do_dhcp, + BAREBOX_CMD_DESC("DHCP client to obtain IP or boot params") + BAREBOX_CMD_OPTS("[-HvcuUr]") + BAREBOX_CMD_GROUP(CMD_GRP_NET) + BAREBOX_CMD_HELP(cmd_dhcp_help) + BAREBOX_CMD_COMPLETE(empty_complete) +BAREBOX_CMD_END diff --git a/common/bootsource.c b/common/bootsource.c index 7f3d51f..707b079 100644 --- a/common/bootsource.c +++ b/common/bootsource.c @@ -35,6 +35,7 @@ [BOOTSOURCE_ONENAND] = "onenand", [BOOTSOURCE_HD] = "harddisk", [BOOTSOURCE_USB] = "usb", + [BOOTSOURCE_NET] = "net", }; static enum bootsource bootsource = BOOTSOURCE_UNKNOWN; diff --git a/include/bootsource.h b/include/bootsource.h index 4bca9b9..c6d3b3a 100644 --- a/include/bootsource.h +++ b/include/bootsource.h @@ -15,6 +15,7 @@ BOOTSOURCE_ONENAND, BOOTSOURCE_HD, BOOTSOURCE_USB, + BOOTSOURCE_NET, }; #define BOOTSOURCE_INSTANCE_UNKNOWN -1 diff --git a/include/dhcp.h b/include/dhcp.h new file mode 100644 index 0000000..0796b30 --- /dev/null +++ b/include/dhcp.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2015 PHYTEC Messtechnik GmbH, + * Author: Wadim Egorov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __DHCP_H__ +#define __DHCP_H__ + +#define DHCP_DEFAULT_RETRY 20 + +struct dhcp_req_param { + char *hostname; + char *vendor_id; + char *client_id; + char *user_class; + char *client_uuid; +}; + +int dhcp(int retries, struct dhcp_req_param *param); + +#endif diff --git a/net/Kconfig b/net/Kconfig index 918d776..a890492 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -22,4 +22,8 @@ default y bool +config NET_DHCP + bool + prompt "dhcp support" + endif diff --git a/net/Makefile b/net/Makefile index 907dc28..58bf143 100644 --- a/net/Makefile +++ b/net/Makefile @@ -1,7 +1,7 @@ obj-$(CONFIG_NET) += eth.o obj-$(CONFIG_NET) += net.o obj-$(CONFIG_NET_NFS) += nfs.o -obj-$(CONFIG_CMD_DHCP) += dhcp.o +obj-$(CONFIG_NET_DHCP) += dhcp.o obj-$(CONFIG_CMD_PING) += ping.o obj-$(CONFIG_NET_RESOLV)+= dns.o obj-$(CONFIG_NET_NETCONSOLE) += netconsole.o diff --git a/net/dhcp.c b/net/dhcp.c index 19a8462..e1625ec 100644 --- a/net/dhcp.c +++ b/net/dhcp.c @@ -21,8 +21,7 @@ #include #include #include - -#define DHCP_DEFAULT_RETRY 20 +#include #define OPT_SIZE 312 /* Minimum DHCP Options size per RFC2131 - results in 576 byte pkt */ @@ -142,7 +141,8 @@ IPaddr_t ip; ip = net_read_ip(popt); - setenv_ip(opt->barebox_var_name, ip); + if (IS_ENABLED(CONFIG_ENVIRONMENT_VARIABLES)) + setenv_ip(opt->barebox_var_name, ip); } static void env_str_handle(struct dhcp_opt *opt, unsigned char *popt, int optlen) @@ -158,10 +158,9 @@ if (opt->copy_only_if_valid && !strlen(tmp)) return; - - if (opt->barebox_var_name) + if (opt->barebox_var_name && IS_ENABLED(EVIRONMENT_VARIABLES)) setenv(opt->barebox_var_name, tmp); - if (opt->barebox_dhcp_global) + if (opt->barebox_dhcp_global && IS_ENABLED(CONFIG_GLOBALVAR)) dhcp_set_barebox_global(opt->barebox_dhcp_global, tmp); } @@ -263,10 +262,10 @@ int str_len; char* str = param->data; - if (!str && param->barebox_var_name) + if (!str && param->barebox_var_name && IS_ENABLED(CONFIG_ENVIRONMENT_VARIABLES)) str = (char*)getenv(param->barebox_var_name); - if (!str && param->barebox_dhcp_global) + if (!str && param->barebox_dhcp_global && IS_ENABLED(CONFIG_GLOBALVAR)) str = (char*)dhcp_get_barebox_global(param->barebox_dhcp_global); if (!str) @@ -391,8 +390,10 @@ net_set_serverip(tmp_ip); if (strlen(bp->bp_file) > 0) { - setenv("bootfile", bp->bp_file); - dhcp_set_barebox_global("bootfile", bp->bp_file); + if (IS_ENABLED(CONFIG_ENVIRONMENT_VARIABLES)) + setenv("bootfile", bp->bp_file); + if (IS_ENABLED(CONFIG_GLOBALVAR)) + dhcp_set_barebox_global("bootfile", bp->bp_file); } debug("bootfile: %s\n", bp->bp_file); @@ -651,87 +652,27 @@ if (!opt->barebox_var_name || opt->copy_only_if_valid) continue; - setenv(opt->barebox_var_name,""); - if (opt->barebox_dhcp_global) - dhcp_set_barebox_global(opt->barebox_dhcp_global,""); + if (IS_ENABLED(CONFIG_ENVIRONMENT_VARIABLES)) + setenv(opt->barebox_var_name, ""); + if (opt->barebox_dhcp_global && IS_ENABLED(CONFIG_GLOBALVAR)) + dhcp_set_barebox_global(opt->barebox_dhcp_global, ""); } } -static void dhcp_global_add(const char *var) +int dhcp(int retries, struct dhcp_req_param *param) { - char * var_global = asprintf("dhcp.%s", var); - - if (!var_global) - return; - - globalvar_add_simple(var_global, NULL); - free(var_global); -} - -static int dhcp_global_init(void) -{ - struct dhcp_opt *opt; - struct dhcp_param *param; - int i; - - for (i = 0; i < ARRAY_SIZE(dhcp_options); i++) { - opt = &dhcp_options[i]; - - if (!opt->barebox_dhcp_global) - continue; - - dhcp_global_add(opt->barebox_dhcp_global); - } - - for (i = 0; i < ARRAY_SIZE(dhcp_params); i++) { - param = &dhcp_params[i]; - - if (!param->barebox_dhcp_global) - continue; - - dhcp_global_add(param->barebox_dhcp_global); - } - - return 0; -} -late_initcall(dhcp_global_init); - -static int do_dhcp(int argc, char *argv[]) -{ - int ret, opt; - int retries = DHCP_DEFAULT_RETRY; + int ret = 0; dhcp_reset_env(); - getenv_uint("global.dhcp.retries", &retries); + dhcp_set_param_data(DHCP_HOSTNAME, param->hostname); + dhcp_set_param_data(DHCP_VENDOR_ID, param->vendor_id); + dhcp_set_param_data(DHCP_CLIENT_ID, param->client_id); + dhcp_set_param_data(DHCP_USER_CLASS, param->user_class); + dhcp_set_param_data(DHCP_CLIENT_UUID, param->client_uuid); - while((opt = getopt(argc, argv, "H:v:c:u:U:r:")) > 0) { - switch(opt) { - case 'H': - dhcp_set_param_data(DHCP_HOSTNAME, optarg); - break; - case 'v': - dhcp_set_param_data(DHCP_VENDOR_ID, optarg); - break; - case 'c': - dhcp_set_param_data(DHCP_CLIENT_ID, optarg); - break; - case 'u': - dhcp_set_param_data(DHCP_CLIENT_UUID, optarg); - break; - case 'U': - dhcp_set_param_data(DHCP_USER_CLASS, optarg); - break; - case 'r': - retries = simple_strtoul(optarg, NULL, 10); - break; - } - } - - if (!retries) { - printf("retries is set to zero, set it to %d\n", DHCP_DEFAULT_RETRY); + if (!retries) retries = DHCP_DEFAULT_RETRY; - } dhcp_con = net_udp_new(0xffffffff, PORT_BOOTPS, dhcp_handler, NULL); if (IS_ERR(dhcp_con)) { @@ -781,29 +722,50 @@ net_unregister(dhcp_con); out: if (ret) - printf("dhcp failed: %s\n", strerror(-ret)); + debug("dhcp failed: %s\n", strerror(-ret)); return ret; } -BAREBOX_CMD_HELP_START(dhcp) -BAREBOX_CMD_HELP_TEXT("Options:") -BAREBOX_CMD_HELP_OPT ("-H HOSTNAME", "hostname to send to the DHCP server") -BAREBOX_CMD_HELP_OPT ("-v ID\t", "DHCP Vendor ID (code 60) submitted in DHCP requests") -BAREBOX_CMD_HELP_OPT ("-c ID\t", "DHCP Client ID (code 61) submitted in DHCP requests") -BAREBOX_CMD_HELP_OPT ("-u UUID\t", "DHCP Client UUID (code 97) submitted in DHCP requests") -BAREBOX_CMD_HELP_OPT ("-U CLASS", "DHCP User class (code 77) submitted in DHCP requests") -BAREBOX_CMD_HELP_OPT ("-r RETRY", "retry limit (default 20)"); -BAREBOX_CMD_HELP_END +#ifdef CONFIG_GLOBALVAR +static void dhcp_global_add(const char *var) +{ + char *var_global = asprintf("dhcp.%s", var); -BAREBOX_CMD_START(dhcp) - .cmd = do_dhcp, - BAREBOX_CMD_DESC("DHCP client to obtain IP or boot params") - BAREBOX_CMD_OPTS("[-HvcuUr]") - BAREBOX_CMD_GROUP(CMD_GRP_NET) - BAREBOX_CMD_HELP(cmd_dhcp_help) - BAREBOX_CMD_COMPLETE(empty_complete) -BAREBOX_CMD_END + if (!var_global) + return; + + globalvar_add_simple(var_global, NULL); + free(var_global); +} + +static int dhcp_global_init(void) +{ + struct dhcp_opt *opt; + struct dhcp_param *param; + int i; + + for (i = 0; i < ARRAY_SIZE(dhcp_options); i++) { + opt = &dhcp_options[i]; + + if (!opt->barebox_dhcp_global) + continue; + + dhcp_global_add(opt->barebox_dhcp_global); + } + + for (i = 0; i < ARRAY_SIZE(dhcp_params); i++) { + param = &dhcp_params[i]; + + if (!param->barebox_dhcp_global) + continue; + + dhcp_global_add(param->barebox_dhcp_global); + } + + return 0; +} +late_initcall(dhcp_global_init); BAREBOX_MAGICVAR_NAMED(global_dhcp_bootfile, global.dhcp.bootfile, "bootfile returned from DHCP request"); BAREBOX_MAGICVAR_NAMED(global_dhcp_rootpath, global.dhcp.rootpath, "rootpath returned from DHCP request"); @@ -814,3 +776,4 @@ BAREBOX_MAGICVAR_NAMED(global_dhcp_tftp_server_name, global.dhcp.tftp_server_name, "TFTP server Name returned from DHCP request"); BAREBOX_MAGICVAR_NAMED(global_dhcp_oftree_file, global.dhcp.oftree_file, "OF tree returned from DHCP request (option 224)"); BAREBOX_MAGICVAR_NAMED(global_dhcp_retries, global.dhcp.retries, "retry limit"); +#endif