]> git.ozlabs.org Git - yaboot.git/blobdiff - second/yaboot.c
git-archimport-id: pnasrat@redhat.com/yaboot--devel--1.3--patch-1
[yaboot.git] / second / yaboot.c
index 7b7bcdb208e7ba4e70d54bec88b93dd9e34eef5d..2c616c3863b791076641c3d3c1edb146de746b36 100644 (file)
@@ -1,38 +1,45 @@
-/* Yaboot - secondary boot loader for Linux on ppc.
-
-   Copyright (C) 1999 Benjamin Herrenschmidt
-
-   portions based on poof
-
-   Copyright (C) 1999 Marius Vollmer
-
-   portions based on quik
-   
-   Copyright (C) 1996 Paul Mackerras.
-
-   Because this program is derived from the corresponding file in the
-   silo-0.64 distribution, it is also
-
-   Copyright (C) 1996 Pete A. Zaitcev
-                1996 Maurizio Plaza
-                1996 David S. Miller
-                1996 Miguel de Icaza
-                1996 Jakub Jelinek
-
-   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; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
+/*
+ *  Yaboot - secondary boot loader for Linux on PowerPC. 
+ *
+ *  Copyright (C) 2001, 2002 Ethan Benson
+ *
+ *  Copyright (C) 1999, 2000, 2001 Benjamin Herrenschmidt
+ *  
+ *  IBM CHRP support
+ *  
+ *  Copyright (C) 2001 Peter Bergner
+ *
+ *  portions based on poof
+ *  
+ *  Copyright (C) 1999 Marius Vollmer
+ *  
+ *  portions based on quik
+ *  
+ *  Copyright (C) 1996 Paul Mackerras.
+ *  
+ *  Because this program is derived from the corresponding file in the
+ *  silo-0.64 distribution, it is also
+ *  
+ *  Copyright (C) 1996 Pete A. Zaitcev
+ *                1996 Maurizio Plaza
+ *                1996 David S. Miller
+ *                1996 Miguel de Icaza
+ *                1996 Jakub Jelinek
+ *
+ *  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; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
 
 #include "stdarg.h"
 #include "string.h"
@@ -428,7 +435,7 @@ bail:
      if (opened)
          file.fs->close(&file);
     
-     if (result != 1 && conf_file)
+     if (conf_file)
          free(conf_file);
        
      return result;
@@ -542,8 +549,9 @@ void check_password(char *str)
 {
      int i;
 
+     prom_printf("\n%s", str);
      for (i = 0; i < 3; i++) {
-         prom_printf ("\n%sassword: ", str);
+         prom_printf ("\nPassword: ");
          passwdbuff[0] = 0;
          cmdedit ((void (*)(void)) 0, 1);
          prom_printf ("\n");
@@ -558,11 +566,15 @@ void check_password(char *str)
          if (!strcmp (password, passwdbuff))
               return;
 #endif /* USE_MD5_PASSWORDS */
-         if (i < 2)
-              prom_printf ("Password incorrect. Please try again...");
+         if (i < 2) {
+              prom_sleep(1);
+              prom_printf ("Incorrect password.  Try again.");
+         }
      }
-     prom_printf ("Seems like you don't know the access password.  Go away!\n");
-     prom_sleep(3);
+     prom_printf(" ___________________\n< Permission denied >\n -------------------\n"
+                "        \\   ^__^\n         \\  (oo)\\_______\n            (__)\\       )\\/\\\n"
+                "                ||----w |\n                ||     ||\n");
+     prom_sleep(4);
      prom_interpret("reset-all");
 }
 
@@ -694,15 +706,18 @@ int get_params(struct boot_param_t* params)
                    restricted = 1;
               if (label) {
                    if (params->args && password && restricted)
-                        check_password ("To specify image arguments you must enter the p");
+                        check_password ("To specify arguments for this image "
+                                        "you must enter the password.");
                    else if (password && !restricted)
-                        check_password ("P");
+                        check_password ("This image is restricted.");
               }
               params->args = make_params(label, params->args);
          }
      }
 
      if (!strcmp (imagename, "help")) {
+          /* FIXME: defdevice shouldn't need to be reset all over the place */
+         if(!defdevice) defdevice = boot.dev;
          prom_printf(
               "\nPress the tab key for a list of defined images.\n"
               "The label marked with a \"*\" is is the default image, "
@@ -723,13 +738,13 @@ int get_params(struct boot_param_t* params)
 
      if (!strcmp (imagename, "halt")) {
          if (password)
-              check_password ("P");
+              check_password ("Restricted command.");
          prom_pause();
          return 0;
      }
      if (!strcmp (imagename, "bye")) {
          if (password) {
-              check_password ("P");
+              check_password ("Restricted command.");
               return 1;
          }
          return 1; 
@@ -738,7 +753,7 @@ int get_params(struct boot_param_t* params)
      if (imagename[0] == '$') {
          /* forth command string */
          if (password)
-              check_password ("P");
+              check_password ("OpenFirmware commands are restricted.");
          prom_interpret(imagename+1);
          return 0;
      }
@@ -746,7 +761,7 @@ int get_params(struct boot_param_t* params)
      strncpy(imagepath, imagename, 1024);
 
      if (!label && password)
-         check_password ("To boot a custom image you must enter the p");
+         check_password ("To boot a custom image you must enter the password.");
 
      if (!parse_device_path(imagepath, defdevice, defpart,
                            "/vmlinux", &params->kernel)) {
@@ -948,7 +963,7 @@ yaboot_text_ui(void)
                    prom_perror(result, params.rd.file);
               }
               else {
-#define INITRD_CHUNKSIZE 0x400000
+#define INITRD_CHUNKSIZE 0x100000
                    initrd_base = prom_claim(loadinfo.base+loadinfo.memsize, INITRD_CHUNKSIZE, 0);
                    if (initrd_base == (void *)-1) {
                         prom_printf("Claim failed for initrd memory\n");
@@ -964,6 +979,7 @@ yaboot_text_ui(void)
                              initrd_more = prom_claim(initrd_want, INITRD_CHUNKSIZE, 0);
                              if (initrd_more != initrd_want) {
                                   prom_printf("Claim failed for initrd memory at %p rc=%p\n",initrd_want,initrd_more);
+                                  prom_pause();
                                   break;
                              }
                              initrd_read = file.fs->read(&file, INITRD_CHUNKSIZE, initrd_more);
@@ -1066,7 +1082,7 @@ load_elf32(struct boot_file_t *file, loadinfo_t *loadinfo)
      /* Read the rest of the Elf header... */
      if ((*(file->fs->read))(file, size, &e->e_version) < size) {
          prom_printf("\nCan't read Elf32 image header\n");
-         return 0;
+         goto bail;
      }
 
      DEBUG_F("Elf32 header:\n");
@@ -1085,24 +1101,24 @@ load_elf32(struct boot_file_t *file, loadinfo_t *loadinfo)
 
      if (e->e_phnum > MAX_HEADERS) {
          prom_printf ("Can only load kernels with one program header\n");
-         return 0;
+         goto bail;
      }
 
      ph = (Elf32_Phdr *)malloc(sizeof(Elf32_Phdr) * e->e_phnum);
      if (!ph) {
          prom_printf ("Malloc error\n");
-         return 0;
+         goto bail;
      }
 
      /* Now, we read the section header */
      if ((*(file->fs->seek))(file, e->e_phoff) != FILE_ERR_OK) {
          prom_printf ("seek error\n");
-         return 0;
+         goto bail;
      }
      if ((*(file->fs->read))(file, sizeof(Elf32_Phdr) * e->e_phnum, ph) !=
         sizeof(Elf32_Phdr) * e->e_phnum) {
          prom_printf ("read error\n");
-         return 0;
+         goto bail;
      }
 
      /* Scan through the program header
@@ -1129,7 +1145,7 @@ load_elf32(struct boot_file_t *file, loadinfo_t *loadinfo)
 
      if (loadinfo->memsize == 0) {
          prom_printf("Can't find a loadable segment !\n");
-         return 0;
+         goto bail;
      }
 
      /* leave some room (1Mb) for boot infos */
@@ -1146,7 +1162,7 @@ load_elf32(struct boot_file_t *file, loadinfo_t *loadinfo)
           loadaddr = KERNELADDR;
      } else {
           flat_vmlinux = 0;
-          loadaddr = e->e_entry;
+          loadaddr = loadinfo->load_loc;
      }
 
      /* On some systems, loadaddr may already be claimed, so try some
@@ -1158,7 +1174,7 @@ load_elf32(struct boot_file_t *file, loadinfo_t *loadinfo)
      }
      if (loadinfo->base == (void *)-1) {
          prom_printf("Claim error, can't allocate kernel memory\n");
-         return 0;
+         goto bail;
      } 
 
      DEBUG_F("After ELF parsing, load base: %p, mem_sz: 0x%08lx\n",
@@ -1177,13 +1193,13 @@ load_elf32(struct boot_file_t *file, loadinfo_t *loadinfo)
          if ((*(file->fs->seek))(file, p->p_offset) != FILE_ERR_OK) {
               prom_printf ("Seek error\n");
               prom_release(loadinfo->base, loadinfo->memsize);
-              return 0;
+              goto bail;
          }
          offset = p->p_vaddr - loadinfo->load_loc;
          if ((*(file->fs->read))(file, p->p_filesz, loadinfo->base+offset) != p->p_filesz) {
               prom_printf ("Read failed\n");
               prom_release(loadinfo->base, loadinfo->memsize);
-              return 0;
+              goto bail;
          }
      }
 
@@ -1191,6 +1207,11 @@ load_elf32(struct boot_file_t *file, loadinfo_t *loadinfo)
     
      /* Return success at loading the Elf32 kernel */
      return 1;
+
+bail:
+     if (ph)
+       free(ph);
+     return 0;
 }
 
 static int
@@ -1205,7 +1226,7 @@ load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo)
      /* Read the rest of the Elf header... */
      if ((*(file->fs->read))(file, size, &e->e_version) < size) {
          prom_printf("\nCan't read Elf64 image header\n");
-         return 0;
+         goto bail;
      }
 
      DEBUG_F("Elf64 header:\n");
@@ -1224,24 +1245,24 @@ load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo)
 
      if (e->e_phnum > MAX_HEADERS) {
          prom_printf ("Can only load kernels with one program header\n");
-         return 0;
+         goto bail;
      }
 
      ph = (Elf64_Phdr *)malloc(sizeof(Elf64_Phdr) * e->e_phnum);
      if (!ph) {
          prom_printf ("Malloc error\n");
-         return 0;
+         goto bail;
      }
 
      /* Now, we read the section header */
      if ((*(file->fs->seek))(file, e->e_phoff) != FILE_ERR_OK) {
          prom_printf ("Seek error\n");
-         return 0;
+         goto bail;
      }
      if ((*(file->fs->read))(file, sizeof(Elf64_Phdr) * e->e_phnum, ph) !=
         sizeof(Elf64_Phdr) * e->e_phnum) {
          prom_printf ("Read error\n");
-         return 0;
+         goto bail;
      }
 
      /* Scan through the program header
@@ -1268,7 +1289,7 @@ load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo)
 
      if (loadinfo->memsize == 0) {
          prom_printf("Can't find a loadable segment !\n");
-         return 0;
+         goto bail;
      }
 
      /* leave some room (1Mb) for boot infos */
@@ -1297,7 +1318,7 @@ load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo)
      }
      if (loadinfo->base == (void *)-1) {
          prom_printf("Claim error, can't allocate kernel memory\n");
-         return 0;
+         goto bail;
      } 
 
      DEBUG_F("After ELF parsing, load base: %p, mem_sz: 0x%08lx\n",
@@ -1316,13 +1337,13 @@ load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo)
          if ((*(file->fs->seek))(file, p->p_offset) != FILE_ERR_OK) {
               prom_printf ("Seek error\n");
               prom_release(loadinfo->base, loadinfo->memsize);
-              return 0;
+              goto bail;
          }
          offset = p->p_vaddr - loadinfo->load_loc;
          if ((*(file->fs->read))(file, p->p_filesz, loadinfo->base+offset) != p->p_filesz) {
               prom_printf ("Read failed\n");
               prom_release(loadinfo->base, loadinfo->memsize);
-              return 0;
+              goto bail;
          }
      }
 
@@ -1330,6 +1351,11 @@ load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo)
     
      /* Return success at loading the Elf64 kernel */
      return 1;
+
+bail:
+     if (ph)
+       free(ph);
+     return 0;
 }
 
 static int
@@ -1506,11 +1532,13 @@ yaboot_main(void)
               if ((ptype != NULL) && (strcmp(ptype, "Apple_Bootstrap")))
                    prom_printf("\nWARNING: Bootstrap partition type is wrong: \"%s\"\n"
                                "         type should be: \"Apple_Bootstrap\"\n\n", ptype);
+              if (ptype)
+                   free(ptype);
          }
      }
 
      yaboot_text_ui();
-       
+
      prom_printf("Bye.\n");
      return 0;
 }