[Top][All Lists]
[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
{