[PATCH 09/10] qi-add-initrd-support.patch
Andy Green
andy at openmoko.com
Wed Oct 22 08:43:29 CEST 2008
Signed-off-by: Andy Green <andy at openmoko.com>
---
include/qi.h | 1
src/phase2.c | 117 ++++++++++++++++++++++++++++++++++------------------------
2 files changed, 69 insertions(+), 49 deletions(-)
diff --git a/include/qi.h b/include/qi.h
index 7b03687..a6c5b59 100644
--- a/include/qi.h
+++ b/include/qi.h
@@ -46,6 +46,7 @@ enum filesystem {
struct kernel_source {
const char *name; /* NULL name means invalid */
const char *filepath;
+ const char *initramfs_filepath;
int (*block_init)(void);
int (*block_read)(unsigned char * buf, unsigned long start512,
int blocks512);
diff --git a/src/phase2.c b/src/phase2.c
index efca157..3056aa6 100644
--- a/src/phase2.c
+++ b/src/phase2.c
@@ -35,11 +35,50 @@ unsigned long partition_length_blocks = 0;
struct kernel_source const * this_kernel = 0;
+const int INITRD_OFFSET = (8 * 1024 * 1024);
+
int raise(int n)
{
return 0;
}
+int read_file(const char * filepath, u8 * destination, int size)
+{
+ unsigned int len = size;
+
+ switch (this_kernel->filesystem) {
+ case FS_EXT2:
+ if (!ext2fs_mount()) {
+ puts("Unable to mount ext2 filesystem\n");
+ return -1;
+ }
+ puts(" EXT2 open: ");
+ puts(filepath);
+ puts("\n");
+ len = ext2fs_open(filepath);
+ if (len < 0) {
+ puts("Open failed\n");
+ return -1;
+ }
+ ext2fs_read((char *)destination, size);
+ break;
+
+ case FS_FAT:
+ /* FIXME */
+ case FS_RAW:
+ puts(" RAW open: +");
+ printdec(partition_offset_blocks);
+ puts(" 512-byte blocks\n");
+ if (this_kernel->block_read(destination,
+ partition_offset_blocks, size >> 9) < 0) {
+ puts ("Bad kernel header\n");
+ return -1;
+ }
+ break;
+ }
+
+ return len;
+}
void bootloader_second_phase(void)
{
@@ -47,6 +86,7 @@ void bootloader_second_phase(void)
int kernel = 0;
const struct board_variant * board_variant =
(this_board->get_board_variant)();
+ unsigned int initramfs_len = 0;
/* we try the possible kernels for this board in order */
@@ -124,40 +164,11 @@ void bootloader_second_phase(void)
partition_offset_blocks =
this_kernel->offset_blocks512_if_no_partition;
- switch (this_kernel->filesystem) {
- case FS_EXT2:
- if (!ext2fs_mount()) {
- puts("Unable to mount ext2 filesystem\n");
- this_kernel = &this_board->
- kernel_source[kernel++];
- continue;
- }
- puts(" EXT2 open: ");
- puts(this_kernel->filepath);
- puts("\n");
- if (ext2fs_open(this_kernel->filepath) < 0) {
- puts("Open failed\n");
- this_kernel = &this_board->
- kernel_source[kernel++];
- continue;
- }
- ext2fs_read(kernel_dram, 4096);
- break;
+ /* pull the kernel image */
- case FS_FAT:
- /* FIXME */
- case FS_RAW:
- puts(" RAW open: +");
- printdec(partition_offset_blocks);
- puts(" 512-byte blocks\n");
- if (this_kernel->block_read(kernel_dram,
- partition_offset_blocks, 8) < 0) {
- puts ("Bad kernel header\n");
- this_kernel = &this_board->
- kernel_source[kernel++];
- continue;
- }
- break;
+ if (read_file(this_kernel->filepath, kernel_dram, 4096) < 0) {
+ this_kernel = &this_board->kernel_source[kernel++];
+ continue;
}
hdr = (image_header_t *)kernel_dram;
@@ -179,24 +190,22 @@ void bootloader_second_phase(void)
kernel_size = ((__be32_to_cpu(hdr->ih_size) +
sizeof(image_header_t) + 2048) & ~(2048 - 1));
- switch (this_kernel->filesystem) {
- case FS_EXT2:
- /* This read API always restarts from beginning */
- ext2fs_read(kernel_dram, kernel_size);
- break;
-
- case FS_FAT:
- /* FIXME */
- case FS_RAW:
- if ((this_kernel->block_read)(
- kernel_dram, partition_offset_blocks,
- kernel_size >> 9) < 0) {
- puts ("Bad kernel read\n");
- this_kernel = &this_board->
- kernel_source[kernel++];
+ if (read_file(this_kernel->filepath, kernel_dram,
+ kernel_size) < 0) {
+ this_kernel = &this_board->kernel_source[kernel++];
+ continue;
+ }
+
+ /* initramfs if needed */
+
+ if (this_kernel->initramfs_filepath) {
+ initramfs_len = read_file(this_kernel->initramfs_filepath,
+ (u8 *)this_board->linux_mem_start + INITRD_OFFSET, 16 * 1024 * 1024);
+ if (initramfs_len < 0) {
+ puts("initramfs load failed\n");
+ this_kernel = &this_board->kernel_source[kernel++];
continue;
}
- break;
}
puts(" Cmdline: ");
@@ -244,6 +253,16 @@ void bootloader_second_phase(void)
params->u.mem.size = this_board->linux_mem_size;
params = tag_next(params);
+ if (this_kernel->initramfs_filepath) {
+ /* INITRD2 tag */
+ params->hdr.tag = ATAG_INITRD2;
+ params->hdr.size = tag_size (tag_initrd);
+ params->u.initrd.start = this_board->linux_mem_start +
+ INITRD_OFFSET;
+ params->u.initrd.size = initramfs_len;
+ params = tag_next(params);
+ }
+
/* kernel commandline */
if (*p) {
More information about the openmoko-kernel
mailing list