Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/sandpoint/stand/altboot Build altboot.img, which fa...



details:   https://anonhg.NetBSD.org/src/rev/40222ee8e800
branches:  trunk
changeset: 762739:40222ee8e800
user:      phx <phx%NetBSD.org@localhost>
date:      Sat Feb 26 20:11:24 2011 +0000

description:
Build altboot.img, which fakes a Linux kernel module, loadable with "bootm",
for extremely stripped U-Boot firmware. Arguments are passed through the
"bootargs" environment variable, which is detected automatically when
using bootm.
The startup code also fixes a bug in bootm, which doesn't flush the cache
before running the image.

diffstat:

 sys/arch/sandpoint/stand/altboot/Makefile |  10 +++--
 sys/arch/sandpoint/stand/altboot/entry.S  |  37 ++++++++++++++++++++++-
 sys/arch/sandpoint/stand/altboot/main.c   |  49 +++++++++++++++++++++++++++++-
 sys/arch/sandpoint/stand/altboot/version  |   1 +
 4 files changed, 89 insertions(+), 8 deletions(-)

diffs (186 lines):

diff -r 8f0ff17b217a -r 40222ee8e800 sys/arch/sandpoint/stand/altboot/Makefile
--- a/sys/arch/sandpoint/stand/altboot/Makefile Sat Feb 26 20:03:09 2011 +0000
+++ b/sys/arch/sandpoint/stand/altboot/Makefile Sat Feb 26 20:11:24 2011 +0000
@@ -1,14 +1,14 @@
-#      $NetBSD: Makefile,v 1.7 2011/01/28 22:15:36 phx Exp $
+#      $NetBSD: Makefile,v 1.8 2011/02/26 20:11:24 phx Exp $
 
 S=             ${.CURDIR}/../../../..
 
 PROG=          altboot
-FILES+=                ${PROG}.bin
+FILES+=                ${PROG}.bin ${PROG}.img
 NOMAN=         # defined
 SRCS=          entry.S main.c brdsetup.c pci.c devopen.c dev_net.c nif.c
 SRCS+=         fxp.c tlp.c rge.c skg.c dsk.c pciide.c siisata.c printf.c
 SRCS+=         vers.c
-CLEANFILES+=   vers.c ${PROG} ${PROG}.bin
+CLEANFILES+=   vers.c ${PROG} ${PROG}.bin ${PROG}.img
 CFLAGS+=       -Wall -Wno-main -ffreestanding -msoft-float -mmultiple
 CFLAGS+=       -Wmissing-prototypes -Wstrict-prototypes -Wpointer-arith
 CPPFLAGS+=     -D_STANDALONE -DSUPPORT_DHCP
@@ -63,6 +63,8 @@
 ${PROG}: ${OBJS} ${LIBSA} ${LIBZ} ${LIBKERN}
        ${LD} -N -Ttext ${RELOC} -Bstatic -e ${ENTRY} -o ${PROG} \
            ${OBJS} ${LIBSA} ${LIBZ} ${LIBKERN}
-       ${OBJCOPY} -S -O binary ${.TARGET} ${.TARGET}.bin
+       ${OBJCOPY} -S -O binary ${PROG} ${PROG}.bin
+       ${TOOL_MKUBOOTIMAGE} -A powerpc -T kernel -C none -O linux \
+           -a 0x${RELOC} -n ${PROG} ${PROG}.bin ${PROG}.img
 
 .include <bsd.prog.mk>
diff -r 8f0ff17b217a -r 40222ee8e800 sys/arch/sandpoint/stand/altboot/entry.S
--- a/sys/arch/sandpoint/stand/altboot/entry.S  Sat Feb 26 20:03:09 2011 +0000
+++ b/sys/arch/sandpoint/stand/altboot/entry.S  Sat Feb 26 20:11:24 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: entry.S,v 1.1 2011/01/23 01:05:30 nisimura Exp $ */
+/* $NetBSD: entry.S,v 1.2 2011/02/26 20:11:24 phx Exp $ */
 
 #include <powerpc/psl.h>
 #include <powerpc/spr.h>
@@ -9,8 +9,41 @@
        .text
        .globl _start
 _start:
+       /*
+        * Save possible argc and argv values from the firmware, usually
+        * passed in r3 and r4.
+        * When started with "bootm", as a Linux kernel module, r6 and r7
+        * point to the start and end address of the bootargs.
+        */
        mr      30,3
        mr      31,4
+       mr      28,6
+       mr      29,7
+
+       /*
+        * U-Boot/PPCBoot forgets to flush the cache when using the "bootm"
+        * command, so we have to do that now.
+        */
+       lis     3,_start@ha
+       addi    3,3,_start@l
+       andi.   3,3,~31@l
+       lis     4,(_edata+31)@ha
+       addi    4,4,(_edata+31)@l
+       mr      5,3
+10:
+       dcbst   0,5
+       addi    5,5,32
+       cmplw   5,4
+       ble     10b
+       sync
+11:
+       icbi    0,3
+       addi    3,3,32
+       cmplw   3,4
+       ble     11b
+       sync
+       isync
+
        mfspr   11,SPR_HID0
        andi.   0,11,HID0_DCE
        ori     11,11,HID0_ICE
@@ -93,6 +126,8 @@
        bl      brdsetup
        mr      3,30
        mr      4,31
+       mr      5,28
+       mr      6,29
        bl      main
 
 hang:  b       hang
diff -r 8f0ff17b217a -r 40222ee8e800 sys/arch/sandpoint/stand/altboot/main.c
--- a/sys/arch/sandpoint/stand/altboot/main.c   Sat Feb 26 20:03:09 2011 +0000
+++ b/sys/arch/sandpoint/stand/altboot/main.c   Sat Feb 26 20:11:24 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: main.c,v 1.6 2011/02/10 13:38:08 nisimura Exp $ */
+/* $NetBSD: main.c,v 1.7 2011/02/26 20:11:24 phx Exp $ */
 
 /*-
  * Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -88,7 +88,7 @@
 void module_load(char *);
 int module_open(struct boot_module *);
 
-void main(int, char **);
+void main(int, char **, char *, char *);
 extern char bootprog_name[], bootprog_rev[];
 
 struct pcidev lata[2];
@@ -100,13 +100,18 @@
 uint32_t busclock, cpuclock;
 
 static int check_bootname(char *);
+static int parse_cmdline(char **, int, char *, char *);
+static int is_space(char);
+
 #define        BNAME_DEFAULT "nfs:"
+#define MAX_ARGS 10
 
 void
-main(int argc, char *argv[])
+main(int argc, char *argv[], char *bootargs_start, char *bootargs_end)
 {
        struct brdprop *brdprop;
        unsigned long marks[MARK_MAX];
+       char *new_argv[MAX_ARGS];
        int n, i, fd, howto;
        char *bname;
 
@@ -166,6 +171,18 @@
        if (netif_init(&lnif[0]) == 0)
                printf("no NET device driver was found\n");
 
+       /*
+        * When argc is too big then it is probably a pointer, which could
+        * indicate that we were launched as a Linux kernel module using
+        * "bootm".
+        */
+       if (argc > MAX_ARGS) {
+               /* parse Linux bootargs */
+               argv = new_argv;
+               argc = parse_cmdline(argv, MAX_ARGS, bootargs_start,
+                   bootargs_end);
+       }
+
        howto = RB_AUTOBOOT;            /* default is autoboot = 0 */
 
        /* get boot options and determine bootname */
@@ -490,3 +507,29 @@
        }
        return 0;
 }
+
+static int
+parse_cmdline(char **argv, int maxargc, char *p, char *end)
+{
+       int argc;
+
+       argv[0] = "";
+       for (argc = 1; argc < maxargc && p < end; argc++) {
+               while (is_space(*p))
+                       p++;
+               if (p >= end)
+                       break;
+               argv[argc] = p;
+               while (!is_space(*p) && p < end)
+                       p++;
+               *p++ = '\0';
+       }
+
+       return argc;
+}
+
+static int
+is_space(char c)
+{
+       return c > '\0' && c <= ' ';
+}
diff -r 8f0ff17b217a -r 40222ee8e800 sys/arch/sandpoint/stand/altboot/version
--- a/sys/arch/sandpoint/stand/altboot/version  Sat Feb 26 20:03:09 2011 +0000
+++ b/sys/arch/sandpoint/stand/altboot/version  Sat Feb 26 20:11:24 2011 +0000
@@ -5,3 +5,4 @@
        maintainance more confortable
 1.4:   load kernels from local disk
 1.5:   altboot is the new name as this is capable of handling net & dsk.
+1.6:   build altboot.img to fake a Linux kernel module, supports bootargs



Home | Main Index | Thread Index | Old Index