From 18564abedd16b867a20ee90ef812e08eb4194dfe Mon Sep 17 00:00:00 2001 From: Dobrica Pavlinusic Date: Wed, 25 Jul 2007 03:10:12 -0500 Subject: [PATCH 1/1] import uloader-2.4.17 --- Makefile | 42 +++++++++ README.loader | 76 ++++++++++++++++ u-boot-load-hd.sh | 3 + uloader.o | Bin 0 -> 4821 bytes uloader_boot.S | 111 +++++++++++++++++++++++ uloader_mod.c | 220 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 452 insertions(+) create mode 100644 Makefile create mode 100644 README.loader create mode 100755 u-boot-load-hd.sh create mode 100644 uloader.o create mode 100644 uloader_boot.S create mode 100644 uloader_mod.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e2317de --- /dev/null +++ b/Makefile @@ -0,0 +1,42 @@ +# Makefile for uloader.o +# +# Copyright (C) 2006 Mihai Georgian +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# Based on: +# Makefile for loader.o by Chih-Chung Chang +# CFLAGS taken from linux-2.4.17_mvl21-sandpoint +# +# To compile this module you will need a fully configured kernel +# 2.4.17_mvl21-sandpoint and gcc 2.95 + +# Change INCLUDE to match your environment +INCLUDE = -nostdinc -I/opt/embedded/ppc/list/linux-2.4.17_mvl21-sandpoint.ref/include -I/opt/embedded/ppc/list/linux-2.4.17_mvl21-sandpoint.ref/arch/ppc -I/opt/embedded/ppc/toolchain/usr/lib/gcc-lib/powerpc-linux/2.95.3/include + +CFLAGS = -D__KERNEL__ -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -fsigned-char -msoft-float -pipe -ffixed-r2 -Wno-uninitialized -mmultiple -mstring -DMODULE + +CC = $(CROSS_COMPILE)gcc +LD = $(CROSS_COMPILE)ld + +uloader.o: uloader_mod.o uloader_boot.o + $(LD) -r uloader_mod.o uloader_boot.o -o uloader.o +uloader_mod.o: uloader_mod.c + $(CC) -c $(INCLUDE) $(CFLAGS) uloader_mod.c +uloader_boot.o: uloader_boot.S + $(CC) -c -mregnames uloader_boot.S +clean: + rm -f uloader.o uloader_mod.o uloader_boot.o diff --git a/README.loader b/README.loader new file mode 100644 index 0000000..9d6e6de --- /dev/null +++ b/README.loader @@ -0,0 +1,76 @@ +* Introduction + +Here is a small kernel module for booting new kernels on Kuro Box without +flashing. It loads a new kernel into memory and jumps to it directly. + +You need kernel header files to build the module. +I put the kernel source came with my Kuro Box in + +http://jan.csie.ntu.edu.tw/~jo/kuro/CD2/linux-2.4.17_kuro-box.tar.gz + +You also need a configuration file to build the kernel, +I use the one in + +ftp://linkstation.yi.org/pub/linkstation/kernel/config_kurobox.040630 + +* Building the new kernel + +cd /usr/src +tar xzvf ~/linux-2.4.17_kuro-box.tar.gz +cd linux-2.4.17_kuro-box +cp ~/config_kurobox.040630 .config +make oldconfig +make dep +make +# the loader need the kernel to be in binary format +objcopy -O binary vmlinux + +* Building the loader module + +tar xzvf loader.tar.gz +cd loader +# change Makefile for your kernel source directory +make + +* Loading the new kernel + +sync;insmod loader.o kernel=/usr/src/linux-2.4.17_kuro-box/vmlinux + +About one minute later or so, you can again telnet in your kuro box +and verify it is running the new kernel by typing "uname -a". + +There are three parameters for this module: + +kernel: kernel file name (the kernel must be in binary format) +initrd: initrd file name (it can be a gzip'ed file) +cmdline: kernel command line + +For example you can use an ramdisk as your root filesystem: + +sync;insmod loader.o kernel=/usr/src/linux-2.4.17_kuro-box/vmlinux \ +initrd=/root/initrd.gz cmdline="root=/dev/ram0" + +The cmdline parameter doesn't work unless a small patch is applied +to the kernel: + +--- arch/ppc/platforms/sandpoint_setup.c.orig Mon Mar 15 00:15:01 2004 ++++ arch/ppc/platforms/sandpoint_setup.c Sun Jan 9 20:54:55 2005 +@@ -666,6 +666,12 @@ + } + #endif + ++ if ( r6 ) ++ { ++ *(char *)(r7+KERNELBASE) = 0; ++ strcpy(cmd_line, (char *)(r6+KERNELBASE)); ++ } ++ + #ifdef NAS_DEBUG + printk("initrd_start: %08X\n",initrd_start); + printk("initrd_end: %08X\n",initrd_end); + +-- +Chih-Chung Chang + +P.S. This module works for me most of the time, but sometimes it +just crashes. I'd be glad to hear if you have any idea why :) diff --git a/u-boot-load-hd.sh b/u-boot-load-hd.sh new file mode 100755 index 0000000..c544503 --- /dev/null +++ b/u-boot-load-hd.sh @@ -0,0 +1,3 @@ +#!/bin/bash +sync;sync;insmod /mnt/share/uloader.o uboot=/mnt/share/u-boot-hd.ram.bin +init 6 diff --git a/uloader.o b/uloader.o new file mode 100644 index 0000000000000000000000000000000000000000..456d18656db94599d9b3b4aca43334e3b31bc15e GIT binary patch literal 4821 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 literal 0 HcmV?d00001 diff --git a/uloader_boot.S b/uloader_boot.S new file mode 100644 index 0000000..538bb63 --- /dev/null +++ b/uloader_boot.S @@ -0,0 +1,111 @@ +/* + * uloader_boot.S + * + * Copyright (C) 2006 Mihai Georgian + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Based on: arch/ppc/boot/sandpoint/head.S + * arch/ppc/kernel/head.S + * http://www-106.ibm.com/developerworks/library/pa-ppccache.html + */ + +#define HID0 0x3F0 /* Hardware Implementation Register 0 */ +#define HID0_ICE (1<<15) /* Instruction Cache Enable */ +#define HID0_DCE (1<<14) /* Data Cache Enable */ + +.section ".text" +.globl load_uboot + +load_uboot: + /* save parameters */ + mr r31,r3 /* pa_load_uboot */ + mr r30,r4 /* pa_uboot_buf */ + mr r29,r5 /* load_address */ + + /* disable interrupts */ + mfmsr r0 + rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */ + sync + mtmsr r0 + sync + + /* disable cache */ + bl disable_cache + + /* jump to after_mmu_off */ + addi r4,r31,after_mmu_off-load_uboot + li r3,0 + mtspr SRR0,r4 + mtspr SRR1,r3 + isync + sync + rfi + +after_mmu_off: + + /* copy uboot image */ + mr r4,r29 /* load address */ + addi r30,r30,4 /* skip size */ + +2: li r0,1024 + lwz r9,0(r30) + + mtctr r0 +1: lwz r0,0(r9) + addi r9,r9,4 + stw r0,0(r4) + addi r4,r4,4 + bdnz 1b + + addi r30,r30,4 + lwz r0,0(r30) + cmpwi r0,0 + bne 2b + + /* jump to uboot */ + lis r1,0x100 /* put stack at 16M */ + li r3,0 + mr r9,r29 + /* u-boot entry point is u-boot base + 0x100 */ + addi r9,r9,0x100 + mtlr r9 + blr + +disable_cache: + li r2,1024 /* flush 16K cache */ + mtctr r2 + mr r3,r2 + lis r4,0xC000 +loop1: + lwz r6,0(r4) + addi r4,r4,16 + bdnz loop1 + + lis r4,0xC000 + mtctr r3 +loop2: + dcbf r0,r4 + addi r4,r4,16 + bdnz loop2 + + mfspr r4,HID0 + li r3,0 + ori r3,r3,HID0_ICE|HID0_DCE + andc r4,r4,r3 + mtspr HID0,r4 + isync + blr diff --git a/uloader_mod.c b/uloader_mod.c new file mode 100644 index 0000000..0a9fa19 --- /dev/null +++ b/uloader_mod.c @@ -0,0 +1,220 @@ +/* + * uloader_mod.c + * + * Loads a RAM build of u-boot and starts it + * The load address is hardcoded to 0x03f00000 (for LS HLAN) + * + * Copyright (C) 2006 Mihai Georgian + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Based on: + * loader_mod.c by Chih-Chung Chang + */ +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mihai Georgian "); +MODULE_PARM(uboot, "s"); +MODULE_PARM(laddr, "l"); +MODULE_PARM_DESC(uboot, "u-boot file name (must be binary)"); +MODULE_PARM_DESC(laddr, "u-boot load address"); + +static char* uboot = "u-boot.bin"; +static unsigned long laddr = 0x03f00000; + +#define LOW_MEM 0x800000 /* no smaller than kernel + 1M (bss) + initrd */ + +void load_uboot(unsigned long pa_load_uboot, + unsigned long pa_uboot_buf, + unsigned long laddr); + +struct indirect_buffer { + int size; + unsigned long paddr[1]; /* physical address of each 4K page */ + /* terminate with zero */ +}; +static struct indirect_buffer *uboot_buf; + +static int uloader_notify_reboot (struct notifier_block *this, \ + unsigned long event, void *x); +static struct notifier_block uloader_notifier = { + uloader_notify_reboot, + NULL, + 0 +}; + +#define MAX_INDIRECT_BUFFER_SIZE ((PAGE_SIZE/4-1)*PAGE_SIZE) + +/* + * Allocate a page with physical address >= LOWMEM + */ +static void **save; +static int saved_pages; +static void *alloc_high_page(void) +{ + void *ptr; + if(!save) + { + save = vmalloc(((LOW_MEM+PAGE_SIZE-1)/PAGE_SIZE)*4); + if(!save) return 0; + } + + while(1) + { + ptr = kmalloc(PAGE_SIZE, GFP_KERNEL); + if(!ptr) return 0; + if(__pa(ptr) >= LOW_MEM) break; + save[saved_pages++] = ptr; + } + return ptr; +} + +static void free_saved_pages(void) +{ + if(save) + { + int i; + for(i=0;if_op || !file->f_op->read) + goto out; + + err = -EACCES; + inode = file->f_dentry->d_inode; + if(!S_ISREG(inode->i_mode)) + goto out; + + err = -ENOMEM; + ibuf = (struct indirect_buffer*)alloc_high_page(); + if(!ibuf) goto out; + memset(ibuf, 0, PAGE_SIZE); + + if(inode->i_size > MAX_INDIRECT_BUFFER_SIZE) goto out2; + size = (size_t)inode->i_size; + ibuf->size = size; + + for(i=0;ipaddr[i/PAGE_SIZE] = __pa(buf); + + err = -EIO; + file->f_pos = i; + fs = get_fs(); + set_fs(KERNEL_DS); + got = file->f_op->read(file, buf, todo, &file->f_pos); + set_fs(fs); + if(got != todo) goto out2; + } + + *indirect_buf = ibuf; + err = 0; + +out: + filp_close(file, NULL); + return err; +out2: + free_ibuffer(ibuf); + goto out; +} + +static void free_ibuffer(struct indirect_buffer *ibuf) +{ + int i; + for(i=0;ibuf->paddr[i];i++) + kfree((void *)__va(ibuf->paddr[i])); + kfree(ibuf); +} + +/* convert vmalloc'ed memory to physical address */ +static unsigned long va2pa(void *p) +{ + return iopa((unsigned long)p); +} + +static int uloader_notify_reboot (struct notifier_block *this, \ + unsigned long event, void *x) +{ + switch (event) { + case SYS_RESTART: + break; + default: + return NOTIFY_DONE; + } + + printk(KERN_INFO "uloader module booting u-boot\n"); + + load_uboot(va2pa(load_uboot), va2pa(uboot_buf), laddr); + + return NOTIFY_DONE; /* This should never be reached */ +} + +int init_module(void) +{ + int err; + + printk(KERN_INFO "uloader module loaded\n"); + printk(KERN_INFO "uboot=%s\n", uboot); + + if((err = read_file(uboot, &uboot_buf))) + goto out; + register_reboot_notifier(&uloader_notifier); + return 0; +out: + free_saved_pages(); + return err; +} + +void cleanup_module(void) +{ + printk(KERN_INFO "uloader module unloaded\n"); +} -- 2.20.1