Module Name: src
Committed By: phx
Date: Sat Feb 26 20:11:24 UTC 2011
Modified Files:
src/sys/arch/sandpoint/stand/altboot: Makefile entry.S main.c version
Log Message:
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.
To generate a diff of this commit:
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/sandpoint/stand/altboot/Makefile
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/sandpoint/stand/altboot/entry.S
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/sandpoint/stand/altboot/main.c
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/sandpoint/stand/altboot/version
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/sandpoint/stand/altboot/Makefile
diff -u src/sys/arch/sandpoint/stand/altboot/Makefile:1.7 src/sys/arch/sandpoint/stand/altboot/Makefile:1.8
--- src/sys/arch/sandpoint/stand/altboot/Makefile:1.7 Fri Jan 28 22:15:36 2011
+++ src/sys/arch/sandpoint/stand/altboot/Makefile Sat Feb 26 20:11:24 2011
@@ -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>
Index: src/sys/arch/sandpoint/stand/altboot/entry.S
diff -u src/sys/arch/sandpoint/stand/altboot/entry.S:1.1 src/sys/arch/sandpoint/stand/altboot/entry.S:1.2
--- src/sys/arch/sandpoint/stand/altboot/entry.S:1.1 Sun Jan 23 01:05:30 2011
+++ src/sys/arch/sandpoint/stand/altboot/entry.S Sat Feb 26 20:11:24 2011
@@ -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
Index: src/sys/arch/sandpoint/stand/altboot/main.c
diff -u src/sys/arch/sandpoint/stand/altboot/main.c:1.6 src/sys/arch/sandpoint/stand/altboot/main.c:1.7
--- src/sys/arch/sandpoint/stand/altboot/main.c:1.6 Thu Feb 10 13:38:08 2011
+++ src/sys/arch/sandpoint/stand/altboot/main.c Sat Feb 26 20:11:24 2011
@@ -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 <= ' ';
+}
Index: src/sys/arch/sandpoint/stand/altboot/version
diff -u src/sys/arch/sandpoint/stand/altboot/version:1.2 src/sys/arch/sandpoint/stand/altboot/version:1.3
--- src/sys/arch/sandpoint/stand/altboot/version:1.2 Sun Jan 23 07:41:38 2011
+++ src/sys/arch/sandpoint/stand/altboot/version Sat Feb 26 20:11:24 2011
@@ -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