pupa-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Initrd support & ext2fs bugfix


From: Jeroen Dekkers
Subject: Initrd support & ext2fs bugfix
Date: Fri, 16 Jan 2004 21:12:13 +0100
User-agent: Mutt/1.5.4i

Hi,

This patch fixes some small error in ext2fs code which I overlooked
the previous time.  It also implements support for linux initrd and
added some code to check whether pupa_file_read() fails.

I've also got confirmation about the copyright assignment and Marco
just told me he did too.  I've put the FSF in the copyright of these
files, is it okay to change the copyright of all files to the FSF?


Thanks,
Jeroen Dekkers

2004-01-16  Jeroen Dekkers  <address@hidden>

        * fs/ext2.c (pupa_ext2_read_file): Correct the value of BLOCKEND
        when it is EXT2_BLOCK_SIZE (data).
        (pupa_ext2_close): Return PUPA_ERR_NONE.

        * include/pupa/i386/pc/linux.h (PUPA_LINUX_INITRD_MAX_ADDRESS):
        Correct value.
        (struct linux_kernel_header): Add kernel_version and
        initrd_addr_max.
        * loader/i386/pc/linux.c (pupa_rescue_cmd_linux): Check whether
        pupa_file_read fails.
        (pupa_rescue_cmd_initrd): Implement.

Index: fs/ext2.c
===================================================================
RCS file: /cvsroot/pupa/pupa/fs/ext2.c,v
retrieving revision 1.3
diff -u -p -r1.3 ext2.c
--- fs/ext2.c   3 Dec 2003 19:17:25 -0000       1.3
+++ fs/ext2.c   16 Jan 2004 19:34:24 -0000
@@ -1,6 +1,7 @@
 /* ext2.c - Second Extended filesystem */
 /*
  *  PUPA  --  Preliminary Universal Programming Architecture for GRUB
+ *  Copyright (C) 2004  Free Software Foundation, Inc.
  *  Copyright (C) 2003  Marco Gerards <address@hidden>.
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -264,7 +265,13 @@ pupa_ext2_read_file (struct pupa_ext2_da
 
       /* Last block.  */
       if (i == blockcnt - 1)
-       blockend = (len + pos) % EXT2_BLOCK_SIZE (data);
+       {
+         blockend = (len + pos) % EXT2_BLOCK_SIZE (data);
+         
+         /* The last portion is exactly EXT2_BLOCK_SIZE (data).  */
+         if (!blockend)
+           blockend = EXT2_BLOCK_SIZE (data);
+       }
 
       /* First block.  */
       if (i == pos / EXT2_BLOCK_SIZE (data))
@@ -278,7 +285,7 @@ pupa_ext2_read_file (struct pupa_ext2_da
       if (blknr)
        {
          pupa_disk_read (data->disk, blknr, skipfirst,
-                               blockend, buf);
+                         blockend, buf);
          if (pupa_errno)
            return -1;
        }
@@ -604,7 +611,7 @@ pupa_ext2_close (pupa_file_t file)
   pupa_dl_unref (my_mod);
 #endif
 
-  return pupa_errno;
+  return PUPA_ERR_NONE;
 }
 
 /* Read LEN bytes data from FILE into BUF.  */
Index: include/pupa/i386/pc/linux.h
===================================================================
RCS file: /cvsroot/pupa/pupa/include/pupa/i386/pc/linux.h,v
retrieving revision 1.1
diff -u -p -r1.1 linux.h
--- include/pupa/i386/pc/linux.h        17 Jan 2003 02:52:05 -0000      1.1
+++ include/pupa/i386/pc/linux.h        16 Jan 2004 19:34:24 -0000
@@ -1,6 +1,6 @@
 /*
  *  PUPA  --  Preliminary Universal Programming Architecture for GRUB
- *  Copyright (C) 1999,2000,2001,2002  Free Software Foundation, Inc.
+ *  Copyright (C) 1999,2000,2001,2002,2004  Free Software Foundation, Inc.
  *  Copyright (C) 2003  Yoshinori K. Okuji <address@hidden>
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -24,7 +24,7 @@
 #define PUPA_LINUX_MAGIC_SIGNATURE     0x53726448      /* "HdrS" */
 #define PUPA_LINUX_DEFAULT_SETUP_SECTS 4
 #define PUPA_LINUX_FLAG_CAN_USE_HEAP   0x80
-#define PUPA_LINUX_INITRD_MAX_ADDRESS  0x38000000
+#define PUPA_LINUX_INITRD_MAX_ADDRESS  0x37FFFFFF
 #define PUPA_LINUX_MAX_SETUP_SECTS     64
 #define PUPA_LINUX_BOOT_LOADER_TYPE    0x72
 #define PUPA_LINUX_HEAP_END_OFFSET     (0x9000 - 0x200)
@@ -67,7 +67,8 @@ struct linux_kernel_header
   pupa_uint32_t header;                        /* Magic signature "HdrS" */
   pupa_uint16_t version;               /* Boot protocol version supported */
   pupa_uint32_t realmode_swtch;                /* Boot loader hook */
-  pupa_uint32_t start_sys;             /* Points to kernel version string */
+  pupa_uint16_t start_sys;             /* The load-low segment (obsolete) */
+  pupa_uint16_t kernel_version;                /* Points to kernel version 
string */
   pupa_uint8_t type_of_loader;         /* Boot loader identifier */
   pupa_uint8_t loadflags;              /* Boot protocol option flags */
   pupa_uint16_t setup_move_size;       /* Move to high memory size */
@@ -78,6 +79,7 @@ struct linux_kernel_header
   pupa_uint16_t heap_end_ptr;          /* Free memory after setup end */
   pupa_uint16_t pad1;                  /* Unused */
   char *cmd_line_ptr;                  /* Points to the kernel command line */
+  pupa_uint32_t initrd_addr_max;        /* Highest address for initrd */
 } __attribute__ ((packed));
 
 #endif /* ! ASM_FILE */
Index: loader/i386/pc/linux.c
===================================================================
RCS file: /cvsroot/pupa/pupa/loader/i386/pc/linux.c,v
retrieving revision 1.2
diff -u -p -r1.2 linux.c
--- loader/i386/pc/linux.c      20 Jan 2003 04:13:46 -0000      1.2
+++ loader/i386/pc/linux.c      16 Jan 2004 19:34:24 -0000
@@ -1,7 +1,7 @@
 /* linux.c - boot Linux zImage or bzImage */
 /*
  *  PUPA  --  Preliminary Universal Programming Architecture for GRUB
- *  Copyright (C) 1999,2000,2001,2002  Free Software Foundation, Inc.
+ *  Copyright (C) 1999,2000,2001,2002,2004  Free Software Foundation, Inc.
  *  Copyright (C) 2003  Yoshinori K. Okuji <address@hidden>
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -66,6 +66,7 @@ pupa_rescue_cmd_linux (int argc, char *a
   struct linux_kernel_header lh;
   pupa_uint8_t setup_sects;
   pupa_size_t real_size, prot_size;
+  pupa_ssize_t len;
   int i;
   char *dest;
 
@@ -233,8 +234,13 @@ pupa_rescue_cmd_linux (int argc, char *a
 
   /* Put the real mode code at the temporary address.  */
   pupa_memmove (pupa_linux_tmp_addr, &lh, sizeof (lh));
-  pupa_file_read (file, pupa_linux_tmp_addr + sizeof (lh),
-                 real_size + PUPA_DISK_SECTOR_SIZE - sizeof (lh));
+
+  len = real_size + PUPA_DISK_SECTOR_SIZE - sizeof (lh);
+  if (pupa_file_read (file, pupa_linux_tmp_addr + sizeof (lh), len) != len)
+    {
+      pupa_error (PUPA_ERR_FILE_READ_ERROR, "Couldn't read file");
+      goto fail;
+    }
 
   if (lh.header != pupa_cpu_to_le32 (PUPA_LINUX_MAGIC_SIGNATURE)
       || pupa_le_to_cpu16 (lh.version) < 0x0200)
@@ -261,8 +267,10 @@ pupa_rescue_cmd_linux (int argc, char *a
 
   *dest = '\0';
 
-  pupa_file_read (file, (char *) PUPA_LINUX_BZIMAGE_ADDR, prot_size);
-  
+  len = prot_size;
+  if (pupa_file_read (file, (char *) PUPA_LINUX_BZIMAGE_ADDR, len) != len)
+    pupa_error (PUPA_ERR_FILE_READ_ERROR, "Couldn't read file");
+ 
   if (pupa_errno == PUPA_ERR_NONE)
     {
       pupa_linux_prot_size = prot_size;
@@ -285,8 +293,81 @@ pupa_rescue_cmd_linux (int argc, char *a
 void
 pupa_rescue_cmd_initrd (int argc, char *argv[])
 {
-  pupa_error (PUPA_ERR_NOT_IMPLEMENTED_YET, "not implemented yet");
+  pupa_file_t file = 0;
+  pupa_ssize_t size;
+  pupa_addr_t addr_max, addr_min, addr;
+  struct linux_kernel_header *lh;
+
+  if (argc == 0)
+    {
+      pupa_error (PUPA_ERR_BAD_ARGUMENT, "No module specified");
+      goto fail;
+    }
+  
+  if (!loaded)
+    {
+      pupa_error (PUPA_ERR_BAD_ARGUMENT, "You need to load the kernel first.");
+      goto fail;
+    }
+
+  lh = (struct linux_kernel_header *) pupa_linux_tmp_addr;
+
+  if (!(lh->header == pupa_cpu_to_le32 (PUPA_LINUX_MAGIC_SIGNATURE)
+       && pupa_le_to_cpu16 (lh->version) >= 0x0200))
+    {
+      pupa_error (PUPA_ERR_BAD_OS, "The kernel is too old for initrd.");
+      goto fail;
+    }
+
+  /* Get the highest address available for the initrd.  */
+  if (pupa_le_to_cpu16 (lh->version) >= 0x0203)
+    addr_max = pupa_cpu_to_le32 (lh->initrd_addr_max);
+  else
+    addr_max = PUPA_LINUX_INITRD_MAX_ADDRESS;
+
+  if (!linux_mem_size && linux_mem_size < addr_max)
+    addr_max = linux_mem_size;
+
+  /* Linux 2.3.xx has a bug in the memory range check, so avoid
+     the last page.
+     Linux 2.2.xx has a bug in the memory range check, which is
+     worse than that of Linux 2.3.xx, so avoid the last 64kb.  */
+  addr_max -= 0x10000;
+
+  if (addr_max > pupa_os_area_addr + pupa_os_area_size)
+    addr_max = pupa_os_area_addr + pupa_os_area_size;
+
+  addr_min = (pupa_addr_t) pupa_linux_tmp_addr + PUPA_LINUX_CL_END_OFFSET;
+
+  file = pupa_file_open (argv[0]);
+  if (!file)
+    goto fail;
+
+  size = pupa_file_size (file);
+
+  /* Put the initrd as high as possible, 4Ki aligned.  */
+  addr = (addr_max - size) & ~0xFFF;
+
+  if (addr < addr_min)
+    {
+      pupa_error (PUPA_ERR_OUT_OF_RANGE, "The initrd is too big");
+      goto fail;
+    }
+
+  if (pupa_file_read (file, (void *)addr, size) != size)
+    {
+      pupa_error (PUPA_ERR_FILE_READ_ERROR, "Couldn't read file");
+      goto fail;
+    }
+
+  lh->ramdisk_image = addr;
+  lh->ramdisk_size = size;
+  
+ fail:
+  if (file)
+    pupa_file_close (file);
 }
+
 
 PUPA_MOD_INIT
 {




reply via email to

[Prev in Thread] Current Thread [Next in Thread]