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