Hi, On Sun, Dec 08, 2013 at 01:26:59AM +0200, Aaro Koskinen wrote: > Allocate memory for kernel image dynamically on sun4u. This allows to > boot bigger modern day kernels. > > External root image is not yet supported, but this can be workarounded > by embedding the rootfs into the kernel with CONFIG_INITRAMFS_SOURCE. It seems it's possible to pass the ramdisk straight from TILO image with: image_table[kernel_number].root_start = (unsigned)orig_code + image_table[ROOT_IMAGE].packed_start + 0x400000; There are also some other minor issues in the patches, I'll post an updated series maybe after next week. A. > Signed-off-by: Aaro Koskinen <aaro.koskinen@xxxxxx> > --- > tilo/tilo.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------ > 1 file changed, 106 insertions(+), 11 deletions(-) > > diff --git a/tilo/tilo.c b/tilo/tilo.c > index d2fcd97b525f..75772b77ca49 100644 > --- a/tilo/tilo.c > +++ b/tilo/tilo.c > @@ -171,6 +171,69 @@ extern struct ImageInfo image_table[4]; /* Sun4 kernel, Sun4c/d/m kernel, Sun4u > > #define HDRS_TAG (('H'<<24) | ('d'<<16) | ('r'<<8) | 'S') > > +static char *sun4u_memory_find (unsigned int len) > +{ > + int n, node, i; > + struct p1275_mem { > + unsigned long long phys; > + unsigned long long size; > + } *p = (struct p1275_mem *)0; > + unsigned int virt = 0x40000000; > + unsigned long long phys = 0, phys_base; > + > + p = (struct p1275_mem *)malloc(2048); > + > + node = prom_finddevice("/memory"); > + > + n = prom_getproplen(node, "available"); > + > + if (!n || n == -1 || > + prom_getproperty(node, "available", (char *)p, 2048) == -1) { > + free (p); > + printf("Could not get available property\n"); > + return (char *)0; > + } > + > + phys = 0; > + n /= sizeof(*p); > + > + phys_base = ~(unsigned long long)0; > + for (i = 0; i < n; i++) { > + if (p[i].phys < phys_base) > + phys_base = p[i].phys; > + } > + > + for (i = 0; i < n; i++) { > + /* Do not mess with first 16 Megs of memory */ > + if (p[i].phys == phys_base) { > + if (p[i].size <= 0x1000000) > + continue; > + p[i].phys += 0x1000000; > + p[i].size -= 0x1000000; > + } > + > + if (p[i].size >= len) { > + phys = p[i].phys; > + break; > + } > + } > + > + free (p); > + > + if (!phys) { > + printf("Could not find any available memory\n"); > + return (char *)0; > + } > + > + if (prom_map(PROM_MAP_DEFAULT, (unsigned long long)len, virt, phys) == > + -1) { > + printf("Could not map memory\n"); > + return (char *)0; > + } > + > + return (char *)virt + 0x4000; > +} > + > void parse_executable(char *base, int image_len) > { > union { > @@ -275,7 +338,7 @@ void parse_executable(char *base, int image_len) > > char *my_main (struct linux_romvec *promvec, void *cifh, void *cifs) > { > -char *orig_code,*moved_code,*moved_ramdisk,*moved_kernel,*kernel_base; > +char *orig_code,*moved_code,*moved_ramdisk = NULL,*moved_kernel,*kernel_base; > unsigned *p,*q = NULL; > int kernel_number; > char *kernel_end, *kernel_limit; > @@ -307,21 +370,53 @@ char *kernel_end, *kernel_limit; > } > > orig_code = (char*) 0x4000; > - moved_code = (char*) MOVED_BASE; > - moved_ramdisk = (char*)((long)(moved_code - image_table[ROOT_IMAGE].packed_len) & ~0xfff); > - moved_kernel = (char*)((long)(moved_ramdisk - image_table[kernel_number].packed_len) & ~0xfff); > + > + /* > + * On sun4u we can allocate more memory and relocate the kernel. > + */ > + if (kernel_number == SUN4U_KERNEL) { > + unsigned int size; > + > + for (size = 64 * 1024 * 1024; size >= 4 * 1024 * 1024; > + size -= 4 * 1024 * 1024) { > + kernel_base = sun4u_memory_find(size); > + if (kernel_base) > + break; > + } > + if (!kernel_base) > + goto no_mem; > + kernel_limit = kernel_base + size; > + gzminp = (unsigned char *)orig_code + > + image_table[kernel_number].packed_start; > + if (image_table[ROOT_IMAGE].packed_len || > + image_table[kernel_number].root_start) { > + printf("External root image not yet supported - disabling.\n"); > + image_table[kernel_number].root_start = 0; > + image_table[ROOT_IMAGE].packed_len = 0; > + } > + } else { > +no_mem: > + moved_code = (char*)MOVED_BASE; > + moved_ramdisk = (char*)((long)(moved_code - > + image_table[ROOT_IMAGE].packed_len) & ~0xfff); > + moved_kernel = (char*)((long)(moved_ramdisk - > + image_table[kernel_number].packed_len) & ~0xfff); > #ifdef TILO_DEBUG > - printf("Locations: moved_code=%x moved_ramdisk=%x moved_kernel=%x\n", > - moved_code, moved_ramdisk, moved_kernel); > + printf("Locations: moved_code=%x moved_ramdisk=%x moved_kernel=%x\n", > + moved_code, moved_ramdisk, moved_kernel); > #endif > - memmove (moved_ramdisk, orig_code + image_table[ROOT_IMAGE].packed_start, image_table[ROOT_IMAGE].packed_len); > - memmove (moved_kernel, orig_code + image_table[kernel_number].packed_start, image_table[kernel_number].packed_len); > + memmove(moved_ramdisk, orig_code + image_table[ROOT_IMAGE].packed_start, > + image_table[ROOT_IMAGE].packed_len); > + memmove(moved_kernel, > + orig_code + image_table[kernel_number].packed_start, > + image_table[kernel_number].packed_len); > + > + kernel_base = (char*) 0x4000; > + kernel_limit = moved_kernel; > + } > > - gzminp = (unsigned char *)moved_kernel; /* decompress kernel */ > - kernel_base = (char*) 0x4000; > kernel_end = kernel_base + > ((image_table[kernel_number].unpacked_len + 0xfff) & ~0xfff); > - kernel_limit = moved_kernel; > > if (kernel_end > kernel_limit) { > printf("No space to decompress the kernel.\n"); > -- > 1.8.4.4 > > -- > To unsubscribe from this list: send the line "unsubscribe sparclinux" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe sparclinux" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html