[SLOF] [PATCH v2 07/11] libnet: Wire up pxelinux.cfg network booting
Alexey Kardashevskiy
aik at ozlabs.ru
Thu May 24 19:01:39 AEST 2018
On 19/5/18 1:45 am, Thomas Huth wrote:
> In case the normal network loading failed, try to load a pxelinux.cfg
> config file. If that succeeds, load the kernel and initrd with the
> information that could be found in this file.
>
> Signed-off-by: Thomas Huth <thuth at redhat.com>
> ---
> include/helpers.h | 2 ++
> lib/libnet/netload.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> slof/helpers.c | 15 ++++++++++---
> 3 files changed, 73 insertions(+), 3 deletions(-)
>
> diff --git a/include/helpers.h b/include/helpers.h
> index 04ee771..9dfe3ae 100644
> --- a/include/helpers.h
> +++ b/include/helpers.h
> @@ -36,6 +36,8 @@ extern void SLOF_pci_config_write16(long offset, long value);
> extern void SLOF_pci_config_write8(long offset, long value);
> extern void *SLOF_translate_my_address(void *addr);
> extern int write_mm_log(char *data, unsigned int len, unsigned short type);
> +extern void SLOF_set_chosen_int(const char *s, long val);
> +extern void SLOF_set_chosen_bytes(const char *s, const char *addr, size_t size);
> extern void SLOF_encode_bootp_response(void *addr, size_t size);
> extern void SLOF_encode_dhcp_response(void *addr, size_t size);
>
> diff --git a/lib/libnet/netload.c b/lib/libnet/netload.c
> index ba1008c..2a2a7c5 100644
> --- a/lib/libnet/netload.c
> +++ b/lib/libnet/netload.c
> @@ -26,6 +26,7 @@
> #include <helpers.h>
> #include "args.h"
> #include "netapps.h"
> +#include "pxelinux.h"
>
> #define IP_INIT_DEFAULT 5
> #define IP_INIT_NONE 0
> @@ -425,6 +426,60 @@ static int tftp_load(filename_ip_t *fnip, void *buffer, int len)
> return rc;
> }
>
> +#define CFG_BUF_SIZE 2048
> +#define MAX_LKIA_ENTRIES 16
> +static int net_pxelinux_cfg_load(filename_ip_t *fnip, char *loadbase,
> + int maxloadlen, uint8_t *mac)
The name confused me, there is already pxelinux_load_cfg().
net_pxelinux_load() may be?
> +{
> + static char cfgbuf[CFG_BUF_SIZE];
This belongs to pxelinux_load_parse_cfg(). And why static?
> + struct lkia entries[MAX_LKIA_ENTRIES];
> + int def, num_entries, rc, ilen;
> +
> + num_entries = pxelinux_load_parse_cfg(fnip, mac, NULL, cfgbuf,
> + CFG_BUF_SIZE, entries,
> + MAX_LKIA_ENTRIES, &def);
> + if (num_entries <= 0)
> + return -1;
> +
> + /* Load kernel */
> + strncpy(fnip->filename, entries[def].kernel,
> + sizeof(fnip->filename) - 1);
> + fnip->filename[sizeof(fnip->filename) - 1] = 0;
> + rc = tftp_load(fnip, loadbase, maxloadlen);
> + if (rc < 0)
> + return rc;
> +
> + /* Load ramdisk */
> + if (entries[def].initrd) {
> + loadbase += rc;
> + maxloadlen -= rc;
> + if (maxloadlen <= 0) {
> + puts(" Not enough space for loading the initrd!");
> + return -1;
> + }
> + strncpy(fnip->filename, entries[def].initrd,
> + sizeof(fnip->filename) - 1);
> + ilen = tftp_load(fnip, loadbase, maxloadlen);
> + if (ilen < 0)
> + return ilen;
> + /* The ELF loader will move the kernel to some spot in low mem
> + * later, thus move the initrd to the end of the RAM instead */
> + memmove(loadbase + maxloadlen - ilen, loadbase, ilen);
> + /* Encode the initrd information in the device tree */
> + SLOF_set_chosen_int("linux,initrd-start",
> + (long)loadbase + maxloadlen - ilen);
> + SLOF_set_chosen_int("linux,initrd-end",
> + (long)loadbase + maxloadlen);
> + }
> +
> + if (entries[def].append) {
> + SLOF_set_chosen_bytes("bootargs", entries[def].append,
> + strlen(entries[def].append) + 1);
> + }
> +
> + return rc;
> +}
> +
> static void encode_response(char *pkt_buffer, size_t size, int ip_init)
> {
> switch(ip_init) {
> @@ -689,6 +744,10 @@ int netload(char *buffer, int len, char *args_fs, int alen)
> /* Do the TFTP load and print error message if necessary */
> rc = tftp_load(&fn_ip, buffer, len);
>
> + if (rc <= 0 && !obp_tftp_args.filename[0]) {
> + rc = net_pxelinux_cfg_load(&fn_ip, buffer, len, own_mac);
> + }
> +
> if (obp_tftp_args.ip_init == IP_INIT_DHCP)
> dhcp_send_release(fn_ip.fd);
>
> diff --git a/slof/helpers.c b/slof/helpers.c
> index a8d575c..bd0742e 100644
> --- a/slof/helpers.c
> +++ b/slof/helpers.c
> @@ -181,7 +181,16 @@ int write_mm_log(char *data, unsigned int len, unsigned short type)
> return forth_eval_pop("write-mm-log");
> }
>
> -static void SLOF_encode_response(void *addr, size_t size,char *s)
> +void SLOF_set_chosen_int(const char *s, long val)
> +{
> + forth_push(val);
> + forth_eval("encode-int");
> + forth_push((unsigned long)s);
> + forth_push(strlen(s));
> + forth_eval("set-chosen");
> +}
> +
> +void SLOF_set_chosen_bytes(const char *s, const char *addr, size_t size)
> {
> forth_push((unsigned long)addr);
> forth_push(size);
> @@ -193,10 +202,10 @@ static void SLOF_encode_response(void *addr, size_t size,char *s)
>
> void SLOF_encode_bootp_response(void *addr, size_t size)
> {
> - SLOF_encode_response(addr, size, "bootp-response");
> + SLOF_set_chosen_bytes("bootp-response", addr, size);
> }
>
> void SLOF_encode_dhcp_response(void *addr, size_t size)
> {
> - SLOF_encode_response(addr, size, "dhcp-response");
> + SLOF_set_chosen_bytes("dhcp-response", addr, size);
> }
>
--
Alexey
More information about the SLOF
mailing list