Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

/*	$NetBSD: bootxx.c,v 1.17 2016/06/11 06:28:07 dholland Exp $	*/

/*
 * Copyright (c) 1995 Waldi Ravens.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *        This product includes software developed by Waldi Ravens.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#define	boot_BSD	bsd_startup

#include <lib/libsa/stand.h>
#include <atari_stand.h>
#include <libkern.h>
#include <tosdefs.h>
#include <sys/boot_flag.h>
#include <sys/exec.h>
#include <sys/reboot.h>
#include <machine/cpu.h>

typedef int      (*bxxx_t)(void *, void *, struct osdsc *);

int	bootxx(void *, void *, int);
void	boot_BSD(struct kparamb *) __attribute__((noreturn));
int	bootxxx(void *, void *, struct osdsc *);
int	load_booter(struct osdsc *);
int	usr_info(struct osdsc *);

#define	BOOTXXX_MAXSIZE	(64 * 1024)
#define	HEAPSIZE	(64 * 1024)	/* should be >32KB for ffs blocksize */
#define	HEAPSTART	(LOADADDR3 + BOOTXXX_MAXSIZE)
#define	HEAPEND		(HEAPSTART + HEAPSIZE)

int
bootxx(void *readsector, void *disklabel, int autoboot)
{
	static osdsc_t	os_desc;
	extern char	end[], edata[];
	osdsc_t		*od = &os_desc;
	bxxx_t		bootxxx = (bxxx_t)(LOADADDR3);

	memset(edata, 0, end - edata);
	setheap((void *)HEAPSTART, (void *)HEAPEND);

	printf("\033v\nNetBSD/atari secondary bootloader"
						" ($Revision: 1.17 $)\n\n");

	if (init_dskio(readsector, disklabel, -1))
		return -1;

	for (;;) {
		od->rootfs = 0;			/* partition a */
		od->osname = "/netbsd";
		od->ostype = &od->osname[1];
		od->boothowto = (RB_RDONLY);

		if (!autoboot) {
			int	pref;

			od->boothowto = (RB_RDONLY|RB_SINGLE);
			pref = usr_info(od);
			if (pref < 0)
				continue;
			if (pref > 0)
				return pref;
		}
		autoboot = 0;			/* in case auto boot fails */

		if (init_dskio(readsector, disklabel, od->rootfs))
			continue;

		if (load_booter(od))
			continue;

		(*bootxxx)(readsector, disklabel, od);
	}
	/* NOTREACHED */
}


int
usr_info(osdsc_t *od)
{
	static char	line[800];
	char		c, *p = line;

	printf("\nEnter os-type [.%s] root-fs [:a] kernel [%s]"
	       " options [none]:\n\033e", od->ostype, od->osname);
	kgets(p, sizeof(line));
	printf("\033f");

	for (;;) {
		while (isspace(*p))
			*p++ = '\0';

		switch (*p++) {
		case '\0':
			goto done;
		case ':':
			if ((c = *p) >= 'a' && c <= 'z')
				od->rootfs = c - 'a';
			else if (c >= 'A' && c <= 'Z')
				od->rootfs = c - ('A' - 27);
			else
				return -1;

			if (!od->rootfs)
				break;
			*p = 'b';
			/* FALLTHROUGH */
		  case '-':
			if ((c = *p) == 'a')
				od->boothowto &= ~RB_SINGLE;
			else if (c == 'b')
				od->boothowto |= RB_ASKNAME;
			else
				BOOT_FLAG(c, od->boothowto);
			break;
		  case '.':
			od->ostype = p;
			break;
		  case '/':
			od->osname = --p;
			break;
		  default:
			return -1;
		}

		while ((c = *p) && !isspace(c))
			p += 1;
	}

done:
	c = od->ostype[0];
	if (isupper(c))
		c = tolower(c);

	switch (c) {
	case 'n':		/* NetBSD */
		return 0;
	case 'l':		/* Linux  */
		return 0x10;
	case 'a':		/* ASV    */
		return 0x40;
	case 't':		/* TOS    */
		return 0x80;
	default:
		return -1;
	}
}

int
load_booter(osdsc_t *od)
{
	int		fd = -1;
	u_char		*bstart = (u_char *)(LOADADDR3);
	int		bsize;
	char		*fname;
	char		*boot_names[] = {	/* 3rd level boot names	  */
				"/boot.atari",	/* in order of preference */
				"/boot",
				"/boot.ata",
				NULL };		/* NULL terminated!	  */

	/*
	 * Read booter's exec-header.
	 */
	for (fname = boot_names[0]; fname != NULL; fname++) {
		if ((fd = open(fname, 0)) < 0)
			printf("Cannot open '%s'\n", fname);
		else
			break;
	}
	if (fd < 0)
		return -1;
	while ((bsize = read(fd, bstart, 1024)) > 0) {
		bstart += bsize;
	}
	close(fd);
	return 0;
}

void
_rtt(void)
{

	printf("Halting...\n");
	for (;;)
		;
}