[syslinux] enhanced config.c32 module

Kim Mik kimmik999999 at yahoo.co.uk
Mon Mar 30 17:16:32 PDT 2009


For UBCD, we have a lot of config files.

Isolinux will load /boot/isolinux/isolinux.cfg, which will load /ubcd/menus/syslinux/main.cfg
Syslinux will load /boot/syslinux/syslinux.cfg, which will load /ubcd/menus/syslinux/main.cfg

The /ubcd/menus/syslinux/main.cfg loads several other config files when you select the appropriate menu.
From all those menus you can go back to  /ubcd/menus/syslinux/main.cfg.

The  /ubcd/menus/syslinux/main.cfg needs to be different for isolinux and syslinux:
- 'localboot -1' doesn't work with syslinux
- The contents for the config files for booting certain linux distro's differ when you run them from CD (isolinux)
  or from USB/HDD (syslinux)

To make this work, I did need to put the specific main.cfg (adapted for isolinux and syslinux in respectively,
/boot/isolinux or /boot/syslinux, but this is quite ugly because all other config files are in /ubcd/menus/syslinux/ 
(19 config files).


With a lot of help of Erwan Velu, I have now a com32 module that loads a config file depending on the running
syslinux variant. It is based on the config.c32 module.

  Usage: config <filename>
         config ext=<filename> iso=<filename> pxe=<filename> sys=<filename>


It supports the current style of loading a new config file:

  config another.cfg


And it support the "bootloader variant dependend" loading of a config:

  config iso=file1.cfg sys=file2.cfg

  This will load file1..cfg file, when this command is run from isolinux.
  It will load file2.cfg, when run from syslinux.


Now I can use it in UBCD a different config file for the "main.cfg" file (/ubcd/menus/mainiso.cfg or /ubcd/menus/mainsys.cfg):

/boot/isolinux/isolinux.cfg:
==================================
DEFAULT main 
 
LABEL main 
KERNEL /boot/syslinux/menu.c32 
APPEND /ubcd/menus/syslinux/mainiso.cfg
==================================

/boot/syslinux/syslinux.cfg:
==================================
DEFAULT main 
 
LABEL main 
KERNEL /boot/syslinux/menu.c32 
APPEND /ubcd/menus/syslinux/mainsys.cfg
==================================


In a entry (e.g..: in '/boot/menus/syslinux/bios.cfg') that does need to go back to the 'main.cfg' file
(/ubcd/menus/mainiso.cfg or /ubcd/menus/mainsys.cfg), I can use now:

========================================================================
LABEL - 
MENU LABEL .. 
KERNEL /boot/syslinux/config.c32 
APPEND iso=/ubcd/menus/syslinux/mainiso.cfg sys=/ubcd/menus/syslinux/mainsys.cfg
========================================================================


Gert Hulselmans




Probably it won't be that usefull for other people, but just in case someone else needs this functionality:


/* ----------------------------------------------------------------------- *
 *
 *   Copyright 2009 H. Peter Anvin - All Rights Reserved
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 *   Boston MA 02110-1301, USA; either version 2 of the License, or
 *   (at your option) any later version; incorporated herein by reference.
 *
 * ----------------------------------------------------------------------- */

/*
 * config.c
 *
 * Loads a new configuration file
 *
 * Usage: config <filename>
 *        config ext=<filename> iso=<filename> pxe=<filename> sys=<filename>
 *
 * Examples:
 *
 * - The following will load the config file 'another.cfg':
 *
 *     config another.cfg
 *
 * - The following will load 'file1.cfg' when you run it from isolinux,
 *   and it will load 'file2.cfg' when you run it from syslinux.
 *
 *     config iso=file1.cfg sys=file2.cfg
 *
 */

#include <stdio.h>
#include <console.h>
#include <string.h>
#include <stdbool.h>
#include <syslinux/boot.h>
#include "syslinux/config.h"

char bootlinux[255];
char extlinux[255];
char isolinux[255];
char pxelinux[255];
char syslinux[255];
bool extlinux_param;
bool isolinux_param;
bool pxelinux_param;
bool syslinux_param;
const struct syslinux_version *sv;

/*
 * Detect which variant of syslinux is running.
 */
int detect_syslinux()
{
  sv = syslinux_version();
  switch (sv->filesystem) {
    case SYSLINUX_FS_EXTLINUX:
    strncpy(bootlinux,extlinux,sizeof(bootlinux));
    extlinux_param=true;
      break;
    case SYSLINUX_FS_ISOLINUX:
    strncpy(bootlinux,isolinux,sizeof(bootlinux));
    isolinux_param=true;
      break;
    case SYSLINUX_FS_PXELINUX:
    strncpy(bootlinux,pxelinux,sizeof(bootlinux));
    pxelinux_param=true;
      break;
    case SYSLINUX_FS_SYSLINUX:
    strncpy(bootlinux,syslinux,sizeof(bootlinux));
    syslinux_param=true;
      break;
    case SYSLINUX_FS_UNKNOWN:
    default:
      return 1;
  }
return 0;
}

/*
 * Detect which parameters are passed to our module and store them.
 */
void detect_parameters(const int argc, const char *argv[])
{
  for (int i = 1; i < argc; i++) {
    if (strncmp(argv[i], "ext=", 4) == 0) {
        strncpy(extlinux, argv[i] + 4, sizeof(extlinux));
    } else if (strncmp(argv[i], "iso=", 4) == 0) {
        strncpy(isolinux, argv[i] + 4, sizeof(isolinux));
    } else if (strncmp(argv[i], "pxe=", 4) == 0) {
        strncpy(pxelinux, argv[i] + 4, sizeof(pxelinux));
    } else if (strncmp(argv[i], "sys=", 4) == 0) {
        strncpy(syslinux, argv[i] + 4, sizeof(syslinux));
    } else if (argc == 2) {
        strncpy(extlinux, argv[1], sizeof(extlinux));
        strncpy(isolinux, argv[1], sizeof(isolinux));
        strncpy(pxelinux, argv[1], sizeof(pxelinux));
        strncpy(syslinux, argv[1], sizeof(syslinux));
    }
  }
}

void init_structs() {
  memset(bootlinux,0,sizeof(bootlinux));
  memset(extlinux,0,sizeof(extlinux));
  memset(isolinux,0,sizeof(isolinux));
  memset(pxelinux,0,sizeof(pxelinux));
  memset(syslinux,0,sizeof(syslinux));

  extlinux_param=false;
  pxelinux_param=false;
  isolinux_param=false;
  syslinux_param=false;
}

void show_usage() {
  fprintf(stderr, "Usage: config <filename>\n");
  fprintf(stderr, "       config ext=<filename> iso=<filename> pxe=<filename> sys=<filename> \n");
}

int main(int argc, const char *argv[])
{
  openconsole(&dev_null_r, &dev_stdcon_w);

  if (argc < 2) {
    fprintf(stderr, "No config file specified.\n\n");
    show_usage();
    return 1;
  }

  init_structs();
  detect_parameters(argc,argv);
  if (detect_syslinux() == 1) {
    fprintf(stderr, "No valid bootloader found..\n\n");
    show_usage();
    return 1;
  }

  if (strlen(bootlinux) > 0 ) {
    syslinux_run_kernel_image(bootlinux, "", 0, IMAGE_TYPE_CONFIG);
    fprintf(stderr, "config: failed to load '%s' (missing file?).\n\n", bootlinux);
    show_usage();
    return 1;
  } else if (extlinux_param | isolinux_param | pxelinux_param | syslinux_param) {
    fprintf(stderr, "No config file specified for the current bootloader.\n\n");
    show_usage();
    return 1;
  }

  return 0;
}



      




More information about the Syslinux mailing list