Logo Search packages:      
Sourcecode: m68k-vme-tftplilo version File versions  Download package

main.c

/*
 *  VME Linux/m68k TFTP Loader
 *
 *  (c) Copyright 1998 by Nick Holgate
 *
 *  This file is subject to the terms and conditions of the GNU General
 *  Public License.  See the file COPYING for more details.
 */

/*--------------------------------------------------------------------------*/

#define GLOBAL                            /* force declaration of global variables  */

#include "defs.h"

/*--------------------------------------------------------------------------*/
/* Read a line from the console with optional timeout.
 *
 * Returns input length.
 */

int
read_line
(     unsigned long     timeout
)
{     int                     c;
    int                       length    = 0;

      while (1)
      {
            if ((c = get_char(timeout)) == -1)
            {
                  /* timeout */
                  break;
            }

            switch (c)
            {
                case '\r':
                case '\n':
                {
                        input_buffer[length] = '\0';
                      put_char('\n');
                        return length;
                  }

                case '\b':
                case 0x7f:
                {
                        if (length)
                        {
                            length--;
                              put_str("\b \b");
                        }
                        break;
                  }

                  case 0x1b:
                  {
                        while (length)
                        {
                            length--;
                              put_str("\b \b");
                        }
                        break;
                  }

                case '\t':
                {
                      put_str("help\n");
                      strcpy(input_buffer, "help");
                      return 4;
                  }

                default:
                {
                  if ((c >= ' ')
                        &&    (c <= '~')
                        &&    (length < sizeof(input_buffer) - 1))
                        {
                            input_buffer[length++] = c;
                            put_char(c);
                        }
                        break;
                  }
            }
      }

    put_str(" ** timeout **\n");

      /* timeout */
      input_buffer[0] = '\0';
      return -1;
}

/*--------------------------------------------------------------------------*/

void
list_records
(     CRATE *crate
)
{     BOOT  *boot;
      int         labellen;
      int         aliaslen;
      int         len;

      put_str("\nBoot configurations:\n");

      labellen = 0;
      aliaslen = 0;
      for (boot = crate->boot_list; boot; boot = boot->next)
      {
            if ((len = strlen(boot->label)) > labellen)
            {
                  labellen = len;
            }

            if (boot->alias)
            {
                  if ((len = strlen(boot->alias)) > aliaslen)
                  {
                        aliaslen = len;
                  }
            }
      }

      for (boot = crate->boot_list; boot; boot = boot->next)
      {
            printf("  %c%-*s  ",
                  (boot == crate->boot_dflt) ? '*' : ' ',
                  labellen,
                  boot->label
            );

            if (aliaslen)
            {
                  printf("%-*s  ",
                        aliaslen,
                        boot->alias ? boot->alias : "");
            }

            if (boot->description)
            {
                  put_char(' ');
                  put_estr(boot->description);
            }
            else if (boot->restricted)
            {
                  put_str("(restricted)");
            }

            put_char('\n');
      }
}

/*--------------------------------------------------------------------------*/

BOOT *
get_boot_record
(     CRATE       *crate,
      const char  **more
)
{     char  name[64];
      char  *p;
      BOOT  *boot;

      while (1)
      {
            put_str("Boot: ");
            read_line(crate->timeout);

            /* timeout or no input */
            if (input_buffer[0] == '\0')
            {
                  /* nasty hack to show this was a default
                   * selection if boot fails.
                   */
                  crate->prompt = FALSE;

                  *more         = "";
                  return crate->boot_dflt;
            }

            /* extract boot configuration name */
            p = extract(name, input_buffer, sizeof(name), '\0');

            if (equal_strings(name, "help")
            ||    equal_strings(name, "?"   ))
            {
                  list_records(crate);
                  put_char('\n');
                  continue;
            }

            if ((boot = find_boot_config(crate->boot_list, name)) == NULL)
            {
                  printf("\nNo such boot configuration '%s'.\n\n", name);
                  continue;
            }

            /* return pointer to any extra command line parameters
             * following the image name
             */
            trim_white(p);
            *more = p;

            /* all done */
            return boot;
      }
}

/*--------------------------------------------------------------------------*/

void
start_loader
(     void
)
{     BOOT                    *boot;
      const char              *more;
      CRATE                   crate;
      int                           count;

      /* the kernel start code is to be placed at the bottom of
       * the area we have reserved for the stack
       */
      startcode_entry = (void (*)(void))(detected_mem_size - STACK_SIZE);

      /* allocate largest free memory chunk */
      config_data = xmalloc(count = maxfree());

      /* build configuration file name */
      input_buffer[0] = '\0';
      substip(input_buffer, config_filename(), sizeof(input_buffer));

      printf("Loading configuration data from '%s' ...\n", input_buffer);

      /* read configuration file */
      if ((count = tftp_read(input_buffer, count, config_data)) == FAILURE)
      {
            panic("Can't TFTP configuration data.");
      }

      /* preprocess config data */
      count = prescan(config_data, count);

      /* release unused memory */
      config_data     = move_up(config_data, count);
      config_data_end = config_data + count;

      /* parse configuration */
      parse_config(&crate);

      /* display message */
      print_display_section(crate.display);

      if (crate.prompt)
      {
            list_records(&crate);
      }

      printf("\nLILO ");

      /* if not interactive and a delay was specified */
      if (!crate.prompt && crate.delay)
      {
            count = put_str("<press a key for prompt> ");

            /* wait a while for a key press */
            if (get_char(crate.delay) != -1)
            {
                  /* key pressed, go interactive */
                  crate.prompt = TRUE;
            }

            erase(count);
      }

      while (1)
      {
            /* if interactive */
            if (crate.prompt)
            {
                  /* ask for boot configuration */
                  boot = get_boot_record(&crate, &more);
            }
            else
            {
                  /* use default boot configuration */
                  boot = crate.boot_dflt;
                  more = "";
            }

            /* check for restricted boot configuration */
            if (*more && boot->restricted)
            {
                  printf(
            "Restricted boot configuration, extra command line options ignored.\n\n");
                  more = "";
            }

            /* go for it */
            boot_linux(boot, more, !crate.prompt);

            printf("\nCouldn't boot the %s configuration '%s'.\n\n",
                        crate.prompt ? "specified" : "default",
                        boot->label);

            /* force prompt */
            crate.prompt = TRUE;
      }
}

/*--------------------------------------------------------------------------*/

void
Main
(     CALLREGS    *regs
)
{
      /* enable instruction cache */
      enable_icache();

      cpu_type = get_cpu_type();
      fpu_type = get_fpu_type();

      /* do board specific initialisations */
      loader_init(regs);

      /* detect memory size */
      detected_mem_size = 0;
      while (ram_probe(detected_mem_size))
      {
            detected_mem_size += (256 * 1024);
      }

      /* initialise heap */
      malloc_init((void *)free_mem_start,
                  detected_mem_size -  STACK_SIZE - free_mem_start);

      /* move stack pointer to end of detected memory
       * and execute: start_loader(void);
       */
      asm volatile (    "movel      %0,%%sp\n"        /* switch stack                           */
                              "jmp  (%1)\n"                 /* jump to function                       */
                              : /* no outputs */
                              : "r" (detected_mem_size), "a" (&start_loader)
                              : "sp", "memory"
      );
}

/*-----------------------------< end of file >------------------------------*/

Generated by  Doxygen 1.6.0   Back to index