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

Reply via email to