From: Bill Nottingham <notting@redhat.com>
To: linux-ia64@vger.kernel.org
Subject: [Linux-ia64] initrd suport for ELI, kernel
Date: Thu, 01 Jun 2000 21:19:28 +0000 [thread overview]
Message-ID: <marc-linux-ia64-105590678205112@msgid-missing> (raw)
[-- Attachment #1: Type: text/plain, Size: 403 bytes --]
Here's some patches that add initrd support to ELI
and the kernel. To use, simply add:
initrd=<some file>
to your eli.cfg. The ELI code that loads the kernel is
shamelessly copied from the kernel loading code. This
currently loads the initrd directly after the kernel.
Current bugs:
- the kernel assumes the address passed to it for
the initrd is valid. We should probably check this.
Bill
[-- Attachment #2: eli-initrd.diff --]
[-- Type: text/plain, Size: 5964 bytes --]
diff -ru eli-0.3.0-old/eli.c eli-0.3.0/eli.c
--- eli-0.3.0-old/eli.c Thu Mar 2 15:56:24 2000
+++ eli-0.3.0/eli.c Tue May 30 16:43:30 2000
@@ -64,6 +64,8 @@
struct vector *vectors; /* physical address of vector table */
fpswa_interface_t *efi_fpswa; /* the fpswa interface which contains the revision and a physical pointer to the FPSWA function */
+ UINT64 initrd_start;
+ UINT64 initrd_size;
};
#define MAX_IMAGE_NAME 15
@@ -76,6 +78,7 @@
CHAR16 *filename;
CHAR16 *append;
CHAR16 *root;
+ CHAR16 *initrd;
};
struct boot_image *image_head = NULL, *image_tail = NULL, *default_image = NULL;
@@ -268,6 +271,9 @@
image->root = StrDuplicate(aToU(p2));
else
root = StrDuplicate(aToU(p2));
+ } else if (strncmpa(p1, "initrd",6) == 0) {
+ if (image)
+ image->initrd = StrDuplicate(aToU(p2));
} else if (strncmpa(p1, "read-only", 9) == 0) {
readonly = 1;
} else if (strncmpa(p1, "read-write", 10) == 0) {
@@ -308,7 +314,110 @@
}
INTN
-load_elf (EFI_FILE_HANDLE fs, CHAR16 *filename, EFI_SYSTEM_TABLE *systab, UINT64 *start_addr)
+load_ramdisk (EFI_FILE_HANDLE fs, CHAR16 *filename, EFI_SYSTEM_TABLE *systab, UINT64 start_addr, UINT64 *initrd_size)
+{
+ EFI_FILE_HANDLE file;
+ EFI_STATUS status;
+ INTN total_size = 0, size = 0;
+ UINTN pages;
+ EFI_FILE_INFO *initrd_info;
+
+ /*
+ * Reset the input interface, is this needed?
+ * I think this is a bug in the 10/20/99 release of EFI.
+ * but it seems to fix the problem with ReadKeyStroke() becoming
+ * blocking !
+ */
+ systab->ConIn->Reset(systab->ConIn, 1);
+
+ /* Open the file */
+ status = fs->Open(fs, &file, filename, EFI_FILE_MODE_READ, EFI_FILE_READ_ONLY);
+ if (EFI_ERROR(status)) {
+ Print(W2U(L"%s: open failed: %r\n"), filename, status);
+ return EFI_LOAD_ERROR;
+ }
+
+#ifdef DEBUG
+ Print(W2U(L"Open %s worked\n"), filename);
+#endif
+
+ initrd_info = LibFileInfo(file);
+ if (!initrd_info) {
+ Print(W2U(L"%s: couldn't read file info\n"),filename);
+ return EFI_LOAD_ERROR;
+ }
+
+ total_size = initrd_info->FileSize;
+ *initrd_size = total_size;
+
+ /* round up to get required number of pages */
+ pages = SIZE_TO_PAGES(total_size);
+
+ /* Make Buffer point to the requested physical address in memory */
+#ifdef BROKEN_EFI_FLOPPY
+ /*
+ * Early versions of EFI had troubles loading files
+ * from floppies in a single big request. Breaking
+ * the read down into chunks of 4KB fixed that
+ * problem. Once EFI is fixed, this is no longer
+ * needed.
+ */
+ {
+ EFI_PHYSICAL_ADDRESS buffer;
+ UINTN j = 0;
+
+ buffer = virt_to_phys(start_addr);
+ while (total_size > 0) {
+ CHAR8 helicopter[4] = { '|' , '/' , '-' , '\\' };
+ int x;
+
+ size = 4 * PAGE_SIZE;
+ if (size > total_size)
+ size = total_size;
+ status = fs->Read(file, &size, (VOID *)buffer);
+ if (EFI_ERROR(status)) {
+ Print(W2U(L"%s: read failed: %r\n"), filename, status);
+ BS->FreePages(start_addr, pages);
+ return EFI_LOAD_ERROR;
+ }
+
+ Print(W2U(L"%c\b"), helicopter[j++%4]);
+ buffer += size;
+ total_size -= size;
+
+ if (check_abort(systab) == EFI_SUCCESS)
+ goto load_abort;
+ }
+ }
+#else
+ size = total_size;
+ status = fs->Read(file, &size, (VOID *) virt_to_phys(start_addr));
+ if (EFI_ERROR(status)) {
+ Print(W2U(L"%s: read failed: %r\n"), filename, status);
+ BS->FreePages(start_addr, pages);
+ return EFI_LOAD_ERROR;
+ }
+ Print(W2U(L"-> %ld bytes\n"), size);
+#endif
+ fs->Close(file);
+
+ return EFI_SUCCESS;
+
+#ifdef BROKEN_EFI_FLOPPY
+load_abort:
+ Print(W2U(L"\nLoading aborted\n"));
+ status = BS->FreePages(start_addr, pages);
+ if (status != EFI_SUCCESS)
+ efi_perror(W2U(L"FreePages"), status);
+ else if (verbose)
+ Print(W2U(L"Freed %ld pages starting at 0x%lx\n"), pages, start_addr);
+ status = fs->Close(file);
+ return EFI_NOT_READY;
+#endif
+}
+
+INTN
+load_elf (EFI_FILE_HANDLE fs, CHAR16 *filename, EFI_SYSTEM_TABLE *systab, UINT64 *start_addr, UINT64 *end_addr)
{
Elf64_Ehdr ehdr;
Elf64_Phdr phdr;
@@ -501,6 +610,7 @@
}
fs->Close(file);
*start_addr = ehdr.e_entry;
+ *end_addr = max_addr;
return EFI_SUCCESS;
@@ -649,7 +759,8 @@
*/
static EFI_STATUS
create_boot_params (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab, CHAR16 *args,
- struct acpi_op *acpi_root, UINT64 start_addr)
+ struct acpi_op *acpi_root, UINT64 start_addr, UINT64 initrd_start,
+ UINT64 initrd_size)
{
UINTN num_pages, cookie, desc_size, cols, rows, args_size, map_size = 512;
SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
@@ -744,6 +855,8 @@
bp->num_vectors = num_vectors;
bp->vectors = vectors;
+ bp->initrd_start = initrd_start;
+ bp->initrd_size = initrd_size;
/* fetch console parameters: */
conout = systab->ConOut;
@@ -970,6 +1083,9 @@
EFI_FILE_HANDLE fs;
EFI_STATUS status;
UINT64 start_addr;
+ UINT64 end_addr;
+ UINT64 initrd_start = 0;
+ UINT64 initrd_size = 0;
UINTN argc, i;
CHAR16 *argv[MAX_ARGS];
struct boot_image *boot_image;
@@ -1107,7 +1223,7 @@
Print(W2U(L"eli: booting `%s' with args=`%s' "), kernel_name, args);
#endif
- switch (load_elf(fs, kernel_name, systab, &start_addr)) {
+ switch (load_elf(fs, kernel_name, systab, &start_addr, &end_addr)) {
case EFI_SUCCESS:
break;
@@ -1118,9 +1234,20 @@
case EFI_LOAD_ERROR:
return EFI_LOAD_ERROR;
}
+ if (boot_image && boot_image->initrd) {
+ end_addr = (end_addr/PAGE_SIZE+1) * PAGE_SIZE;
+ switch (load_ramdisk(fs, boot_image->initrd, systab, end_addr, &initrd_size)) {
+ case EFI_SUCCESS:
+ initrd_start = end_addr;
+ break;
+ case EFI_OUT_OF_RESOURCES:
+ case EFI_LOAD_ERROR:
+ return EFI_LOAD_ERROR;
+ }
+ }
/* No console output permitted after create_boot_params()! */
- status = create_boot_params(image, systab, args, acpi_root, start_addr);
+ status = create_boot_params(image, systab, args, acpi_root, start_addr, initrd_start, initrd_size);
if (status != EFI_SUCCESS)
return status;
start_kernel(start_addr);
[-- Attachment #3: kernel-initrd.diff --]
[-- Type: text/plain, Size: 2497 bytes --]
diff -ru redhat/BUILD/linux/arch/ia64/kernel/setup.c lfoo/arch/ia64/kernel/setup.c
--- redhat/BUILD/linux/arch/ia64/kernel/setup.c Tue May 30 16:32:59 2000
+++ lfoo/arch/ia64/kernel/setup.c Tue May 30 16:36:18 2000
@@ -26,6 +26,9 @@
#include <linux/string.h>
#include <linux/threads.h>
#include <linux/console.h>
+#ifdef CONFIG_BLK_DEV_RAM
+#include <linux/blk.h>
+#endif
#include <asm/acpi-ext.h>
#include <asm/page.h>
@@ -125,11 +128,24 @@
* change APIs, they'd do things for the better. Grumble...
*/
bootmap_start = PAGE_ALIGN(__pa(&_end));
+ if (ia64_boot_param.initrd_size) {
+ bootmap_start = PAGE_ALIGN(bootmap_start+ia64_boot_param.initrd_size);
+ }
bootmap_size = init_bootmem(bootmap_start >> PAGE_SHIFT, max_pfn);
efi_memmap_walk(free_available_memory, 0);
reserve_bootmem(bootmap_start, bootmap_size);
+#ifdef CONFIG_BLK_DEV_INITRD
+ initrd_start = ia64_boot_param.initrd_start;
+ if (initrd_start) {
+ initrd_end = initrd_start+ia64_boot_param.initrd_size;
+ printk("Initial ramdisk at: 0x%p (%lu bytes)\n",
+ (void *) initrd_start, ia64_boot_param.initrd_size);
+ reserve_bootmem(virt_to_phys(initrd_start),
+ ia64_boot_param.initrd_size);
+ }
+#endif
#if 0
/* XXX fix me */
init_mm.start_code = (unsigned long) &_stext;
diff -ru redhat/BUILD/linux/arch/ia64/mm/init.c lfoo/arch/ia64/mm/init.c
--- redhat/BUILD/linux/arch/ia64/mm/init.c Tue May 30 16:32:59 2000
+++ lfoo/arch/ia64/mm/init.c Wed May 24 22:05:11 2000
@@ -179,6 +180,19 @@
}
printk ("Freeing unused kernel memory: %ldkB freed\n",
(&__init_end - &__init_begin) >> 10);
+}
+
+void
+free_initrd_mem(unsigned long start, unsigned long end)
+{
+ if (start < end)
+ printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+ for (; start < end; start += PAGE_SIZE) {
+ clear_bit(PG_reserved, &mem_map[MAP_NR(start)].flags);
+ set_page_count(&mem_map[MAP_NR(start)], 1);
+ free_page(start);
+ ++totalram_pages;
+ }
}
void
diff -ru redhat/BUILD/linux/include/asm-ia64/system.h lfoo/include/asm-ia64/system.h
--- redhat/BUILD/linux/include/asm-ia64/system.h Tue May 30 16:33:01 2000
+++ lfoo/include/asm-ia64/system.h Thu May 25 16:47:59 2000
@@ -54,6 +54,8 @@
__u16 num_pci_vectors; /* number of ACPI derived PCI IRQ's*/
__u64 pci_vectors; /* physical address of PCI data (pci_vector_struct)*/
__u64 fpswa; /* physical address of the the fpswa interface */
+ __u64 initrd_start;
+ __u64 initrd_size;
} ia64_boot_param;
extern inline void
next reply other threads:[~2000-06-01 21:19 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2000-06-01 21:19 Bill Nottingham [this message]
2000-06-01 21:26 ` [Linux-ia64] initrd suport for ELI, kernel Johannes Erdfelt
2000-06-01 21:50 ` Bill Nottingham
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=marc-linux-ia64-105590678205112@msgid-missing \
--to=notting@redhat.com \
--cc=linux-ia64@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.