[PATCH 1/6] Add a NetBSD loader, ported over from ARAnyM

[ Thread Index | Date Index | More lists.tuxfamily.org/hatari-devel Archives ]


---
 src/CMakeLists.txt           |   2 +-
 src/configuration.c          |  21 ++
 src/includes/configuration.h |  10 +
 src/includes/netbsd.h        |  18 +
 src/netbsd.c                 | 657 +++++++++++++++++++++++++++++++++++
 src/options.c                |  11 +
 src/tos.c                    |   8 +
 7 files changed, 726 insertions(+), 1 deletion(-)
 create mode 100644 src/includes/netbsd.h
 create mode 100644 src/netbsd.c

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b459c0dc..8b499354 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -9,7 +9,7 @@ set(SOURCES
 	ncr5380.c paths.c  psg.c printer.c resolution.c rs232.c reset.c rtc.c
 	scandir.c scc.c stMemory.c screen.c screenConvert.c screenSnapShot.c
 	shortcut.c sound.c spec512.c statusbar.c str.c tos.c utils.c
-	vdi.c vme.c inffile.c video.c wavFormat.c xbios.c ymFormat.c lilo.c)
+	vdi.c vme.c inffile.c video.c wavFormat.c xbios.c ymFormat.c lilo.c netbsd.c)
 
 # Disk image code is shared with the hmsa tool, so we put it into a library:
 add_library(Floppy createBlankImage.c dim.c msa.c st.c zip.c)
diff --git a/src/configuration.c b/src/configuration.c
index 9f386c85..18d10f2b 100644
--- a/src/configuration.c
+++ b/src/configuration.c
@@ -431,6 +431,15 @@ static const struct Config_Tag configs_Lilo[] =
 	{ NULL , Error_Tag, NULL }
 };
 
+/* Used to load/save NetBSD options, names are same as with Aranym */
+static const struct Config_Tag configs_Netbsd[] =
+{
+	{ "Args", String_Tag, ConfigureParams.Netbsd.szCommandLine },
+	{ "Kernel", String_Tag, ConfigureParams.Netbsd.szKernelFileName },
+	{ "HaltOnReboot", Bool_Tag, &ConfigureParams.Netbsd.bHaltOnReboot },
+	{ NULL , Error_Tag, NULL }
+};
+
 /* Used to load/save RS232 options */
 static const struct Config_Tag configs_Rs232[] =
 {
@@ -758,6 +767,13 @@ void Configuration_SetDefault(void)
 	ConfigureParams.Lilo.bKernelToFastRam = true;
 	ConfigureParams.Lilo.bHaltOnReboot = true;
 
+	/* Set defaults for NetBSD */
+	strcpy(ConfigureParams.Netbsd.szCommandLine, "-b");
+	File_MakePathBuf(ConfigureParams.Netbsd.szKernelFileName,
+	                 sizeof(ConfigureParams.Netbsd.szKernelFileName),
+	                 Paths_GetDataDir(), "netbsd.gz", NULL);
+	ConfigureParams.Lilo.bHaltOnReboot = true;
+
 	/* Set defaults for System */
 	ConfigureParams.System.nMachineType = MACHINE_ST;
 	ConfigureParams.System.nCpuLevel = 0;
@@ -893,6 +909,8 @@ void Configuration_Apply(bool bReset)
 		File_MakeAbsoluteName(ConfigureParams.Lilo.szKernelSymbols);
 	if (strlen(ConfigureParams.Lilo.szRamdiskFileName) > 0)
 		File_MakeAbsoluteName(ConfigureParams.Lilo.szRamdiskFileName);
+	if (strlen(ConfigureParams.Netbsd.szKernelFileName) > 0)
+		File_MakeAbsoluteName(ConfigureParams.Netbsd.szKernelFileName);
 	File_CleanFileName(ConfigureParams.HardDisk.szHardDiskDirectories[0]);
 	File_MakeAbsoluteName(ConfigureParams.HardDisk.szHardDiskDirectories[0]);
 	File_MakeAbsoluteName(ConfigureParams.Memory.szMemoryCaptureFileName);
@@ -1029,6 +1047,7 @@ void Configuration_Load(const char *psFileName)
 	Configuration_LoadSection(psFileName, configs_Ide, "[IDE]");
 	Configuration_LoadSection(psFileName, configs_Rom, "[ROM]");
 	Configuration_LoadSection(psFileName, configs_Lilo, "[LILO]");
+	Configuration_LoadSection(psFileName, configs_Netbsd, "[NETBSD]");
 	Configuration_LoadSection(psFileName, configs_Rs232, "[RS232]");
 	Configuration_LoadSection(psFileName, configs_Printer, "[Printer]");
 	Configuration_LoadSection(psFileName, configs_Midi, "[Midi]");
@@ -1086,6 +1105,7 @@ void Configuration_Save(void)
 	Configuration_SaveSection(sConfigFileName, configs_Ide, "[IDE]");
 	Configuration_SaveSection(sConfigFileName, configs_Rom, "[ROM]");
 	Configuration_SaveSection(sConfigFileName, configs_Lilo, "[LILO]");
+	Configuration_SaveSection(sConfigFileName, configs_Netbsd, "[NETBSD]");
 	Configuration_SaveSection(sConfigFileName, configs_Rs232, "[RS232]");
 	Configuration_SaveSection(sConfigFileName, configs_Printer, "[Printer]");
 	Configuration_SaveSection(sConfigFileName, configs_Midi, "[Midi]");
@@ -1108,6 +1128,7 @@ void Configuration_MemorySnapShot_Capture(bool bSave)
 
 	MemorySnapShot_Store(ConfigureParams.Lilo.szKernelFileName, sizeof(ConfigureParams.Lilo.szKernelFileName));
 	MemorySnapShot_Store(ConfigureParams.Lilo.szRamdiskFileName, sizeof(ConfigureParams.Lilo.szRamdiskFileName));
+	MemorySnapShot_Store(ConfigureParams.Netbsd.szKernelFileName, sizeof(ConfigureParams.Netbsd.szKernelFileName));
 
 	MemorySnapShot_Store(&ConfigureParams.Memory.STRamSize_KB, sizeof(ConfigureParams.Memory.STRamSize_KB));
 	MemorySnapShot_Store(&ConfigureParams.Memory.TTRamSize_KB, sizeof(ConfigureParams.Memory.TTRamSize_KB));
diff --git a/src/includes/configuration.h b/src/includes/configuration.h
index e29b77e0..170b94d4 100644
--- a/src/includes/configuration.h
+++ b/src/includes/configuration.h
@@ -64,6 +64,15 @@ typedef struct
 } CNF_LILO;
 
 
+/* NetBSD configuration */
+typedef struct
+{
+  char szCommandLine[256];	/* bootinfo CL_SIZE */
+  char szKernelFileName[FILENAME_MAX];
+  bool bHaltOnReboot;
+} CNF_NETBSD;
+
+
 /* Sound configuration */
 typedef struct
 {
@@ -427,6 +436,7 @@ typedef struct
   CNF_IDEDEV Ide[MAX_IDE_DEVS];
   CNF_ROM Rom;
   CNF_LILO Lilo;
+  CNF_NETBSD Netbsd;
   CNF_RS232 RS232;
   CNF_PRINTER Printer;
   CNF_MIDI Midi;
diff --git a/src/includes/netbsd.h b/src/includes/netbsd.h
new file mode 100644
index 00000000..4497b205
--- /dev/null
+++ b/src/includes/netbsd.h
@@ -0,0 +1,18 @@
+/*
+ Hatari - netbsd.h
+
+ This file is distributed under the GNU General Public License, version 2
+ or at your option any later version. Read the file gpl.txt for details.
+*/
+
+#ifndef NETBSD_H
+#define NETBSD_H
+
+extern bool bUseNetbsd;
+
+/**
+ * return true if Linux loading succeeds
+ */
+extern bool netbsd_init(void);
+
+#endif /* NETBSD_H */
diff --git a/src/netbsd.c b/src/netbsd.c
new file mode 100644
index 00000000..b0502e2b
--- /dev/null
+++ b/src/netbsd.c
@@ -0,0 +1,657 @@
+/*
+ NetBSD/m68k OS loader
+
+ Adaption from ARAnyM (bootos_netbsd.cpp) to Hatari (C) 2002 Thorsten Otto
+
+ This file is distributed under the GNU General Public License, version 2
+ or at your option any later version. Read the file gpl.txt for details.
+*/
+
+#include "main.h"
+#include "configuration.h"
+#include "file.h"
+#include "netbsd.h"
+#include "log.h"
+#include "tos.h"	/* TosAddress */
+#include "stMemory.h"	/* STRam etc */
+#include "symbols.h"
+#include <stdint.h>
+#include <SDL_endian.h>
+#include "newcpu.h"
+
+bool bUseNetbsd;
+
+#define NETBSD_DEBUG 0
+#if NETBSD_DEBUG
+#define Dprintf(a) printf a
+#else
+#define Dprintf(a)
+#endif
+
+/*--- Rip from elf.h ---*/
+
+/* Type for a 16-bit quantity.  */
+typedef uint16_t Elf32_Half;
+
+/* Types for signed and unsigned 32-bit quantities.  */
+typedef uint32_t Elf32_Word;
+typedef	int32_t  Elf32_Sword;
+
+/* Types for signed and unsigned 64-bit quantities.  */
+typedef uint64_t Elf32_Xword;
+typedef	int64_t  Elf32_Sxword;
+
+/* Type of addresses.  */
+typedef uint32_t Elf32_Addr;
+
+/* Type of file offsets.  */
+typedef uint32_t Elf32_Off;
+
+/* Type for section indices, which are 16-bit quantities.  */
+typedef uint16_t Elf32_Section;
+
+/* Type for version symbol information.  */
+typedef Elf32_Half Elf32_Versym;
+
+
+/* The ELF file header.  This appears at the start of every ELF file.  */
+
+#define EI_NIDENT (16)
+
+typedef struct
+{
+  unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
+  Elf32_Half	e_type;			/* Object file type */
+  Elf32_Half	e_machine;		/* Architecture */
+  Elf32_Word	e_version;		/* Object file version */
+  Elf32_Addr	e_entry;		/* Entry point virtual address */
+  Elf32_Off	e_phoff;		/* Program header table file offset */
+  Elf32_Off	e_shoff;		/* Section header table file offset */
+  Elf32_Word	e_flags;		/* Processor-specific flags */
+  Elf32_Half	e_ehsize;		/* ELF header size in bytes */
+  Elf32_Half	e_phentsize;		/* Program header table entry size */
+  Elf32_Half	e_phnum;		/* Program header table entry count */
+  Elf32_Half	e_shentsize;		/* Section header table entry size */
+  Elf32_Half	e_shnum;		/* Section header table entry count */
+  Elf32_Half	e_shstrndx;		/* Section header string table index */
+} Elf32_Ehdr;
+
+/* Program segment header.  */
+
+typedef struct
+{
+  Elf32_Word	p_type;			/* Segment type */
+  Elf32_Off	p_offset;		/* Segment file offset */
+  Elf32_Addr	p_vaddr;		/* Segment virtual address */
+  Elf32_Addr	p_paddr;		/* Segment physical address */
+  Elf32_Word	p_filesz;		/* Segment size in file */
+  Elf32_Word	p_memsz;		/* Segment size in memory */
+  Elf32_Word	p_flags;		/* Segment flags */
+  Elf32_Word	p_align;		/* Segment alignment */
+} Elf32_Phdr;
+
+#define EI_MAG0		0		/* File identification byte 0 index */
+#define	ELFMAG		"\177ELF"
+#define	SELFMAG		4
+#define ET_EXEC		2		/* Executable file */
+#define EM_68K		 4		/* Motorola m68k family */
+#define EV_CURRENT	1		/* Current version */
+
+/*
+ * Section Headers
+ */
+typedef struct {
+	Elf32_Word	sh_name;	/* section name (.shstrtab index) */
+	Elf32_Word	sh_type;	/* section type */
+	Elf32_Word	sh_flags;	/* section flags */
+	Elf32_Addr	sh_addr;	/* virtual address */
+	Elf32_Off	sh_offset;	/* file offset */
+	Elf32_Word	sh_size;	/* section size */
+	Elf32_Word	sh_link;	/* link to another */
+	Elf32_Word	sh_info;	/* misc info */
+	Elf32_Word	sh_addralign;	/* memory alignment */
+	Elf32_Word	sh_entsize;	/* table entry size */
+} Elf32_Shdr;
+
+/* sh_type */
+#define	SHT_NULL	0		/* Section header table entry unused */
+#define	SHT_PROGBITS	1		/* Program information */
+#define	SHT_SYMTAB	2		/* Symbol table */
+#define	SHT_STRTAB	3		/* String table */
+#define	SHT_RELA	4		/* Relocation information w/ addend */
+#define	SHT_HASH	5		/* Symbol hash table */
+#define	SHT_DYNAMIC	6		/* Dynamic linking information */
+#define	SHT_NOTE	7		/* Auxiliary information */
+#define	SHT_NOBITS	8		/* No space allocated in file image */
+#define	SHT_REL		9		/* Relocation information w/o addend */
+#define	SHT_SHLIB	10		/* Reserved, unspecified semantics */
+#define	SHT_DYNSYM	11		/* Symbol table for dynamic linker */
+#define	SHT_NUM		12
+
+#define	SHT_LOOS	0x60000000	/* Operating system specific range */
+#define	SHT_HIOS	0x6fffffff
+#define	SHT_LOPROC	0x70000000	/* Processor-specific range */
+#define	SHT_HIPROC	0x7fffffff
+#define	SHT_LOUSER	0x80000000	/* Application-specific range */
+#define	SHT_HIUSER	0xffffffff
+
+/* sh_flags */
+#define	SHF_WRITE	0x1		/* Section contains writable data */
+#define	SHF_ALLOC	0x2		/* Section occupies memory */
+#define	SHF_EXECINSTR	0x4		/* Section contains executable insns */
+
+#define	SHF_MASKOS	0x0f000000	/* Operating system specific values */
+#define	SHF_MASKPROC	0xf0000000	/* Processor-specific values */
+
+/* end of rip from elf.h */
+
+/*
+ * Values for 'bootflags'.
+ * Note: These must match the values NetBSD uses!
+ */
+#define	ATARI_68000	1		/* 68000 CPU			*/
+#define	ATARI_68010	(1<<1)		/* 68010 CPU			*/
+#define	ATARI_68020	(1<<2)		/* 68020 CPU			*/
+#define	ATARI_68030	(1<<3)		/* 68030 CPU			*/
+#define	ATARI_68040	(1<<4)		/* 68040 CPU			*/
+#define	ATARI_68060	(1<<6)		/* 68060 CPU			*/
+#define	ATARI_TT	(1L<<11)	/* This is a TT030		*/
+#define	ATARI_FALCON	(1L<<12)	/* This is a Falcon		*/
+#define	ATARI_HADES	(1L<<13)	/* This is a Hades		*/
+#define	ATARI_MILAN	(1L<<14)	/* This is a Milan		*/
+
+#define	ATARI_CLKBROKEN	(1<<16)		/* GEMDOS has faulty year base	*/
+
+#define	ATARI_ANYCPU	(ATARI_68000|ATARI_68010|ATARI_68020|ATARI_68030|ATARI_68040|ATARI_68060)
+#define	ATARI_ANYMACH	(ATARI_TT|ATARI_FALCON|ATARI_HADES|ATARI_MILAN)
+
+/*
+ * Definitions for boothowto
+ * Note: These must match the values NetBSD uses!
+ */
+#define	RB_AUTOBOOT	0x00
+#define	RB_ASKNAME	0x01
+#define	RB_SINGLE	0x02
+#define	RB_KDB		0x40
+
+
+/*--- Other defines ---*/
+
+#undef PAGE_SIZE
+#define PAGE_SIZE 8192
+
+#define M68K_EMUL_RESET 0x7102
+
+/* Start address of kernel in Atari RAM */
+#define KERNEL_START		PAGE_SIZE
+
+/*--- Structures ---*/
+
+struct atari_bootinfo {
+	uint32_t	kp;			/* 00: Kernel load address	*/
+	uint32_t	ksize;		/* 04: Size of loaded kernel	*/
+	uint32_t	entry;		/* 08: Kernel entry point	*/
+	uint32_t	stmem_size;	/* 12: Size of st-ram		*/
+	uint32_t	ttmem_size;	/* 16: Size of tt-ram		*/
+	uint32_t	bootflags;	/* 20: Various boot flags	*/
+	uint32_t	boothowto;	/* 24: How to boot		*/
+	uint32_t	ttmem_start;	/* 28: Start of tt-ram		*/
+	uint32_t	esym_loc;	/* 32: End of symbol table	*/
+};
+
+static struct atari_bootinfo bi;
+
+static bool netbsd_load(void);
+static void *load_file(const char *filename, uint32_t *length);
+static bool check_kernel(void *kernel, Elf32_Addr *offset);
+static bool set_machine_type(void);
+
+
+/*	NetBSD/m68k loader */
+
+bool netbsd_init(void)
+{
+	uint8_t *ROMBaseHost = &RomMem[TosAddress];
+
+	if (!ConfigureParams.System.bMMU || ConfigureParams.Memory.STRamSize_KB < 8*1024) {
+		Log_AlertDlg(LOG_FATAL, "NetBSD requires MMU and at least 8MB of RAM!");
+		return false;
+	}
+	/* RESET + Linux/m68k boot */
+	ROMBaseHost[0x0000] = 0x4e;		/* reset */
+	ROMBaseHost[0x0001] = 0x70;
+	ROMBaseHost[0x0002] = 0x4e;		/* jmp <abs.addr> */
+	ROMBaseHost[0x0003] = 0xf9;
+
+	/* TODO: ROM + 0x30 is Linux reset address on AB40, 0x4 on Falcon/TT */
+#if 0
+	if (!(ConfigureParams.Log.bNatFeats && ConfigureParams.Netbsd.bHaltOnReboot)) {
+		/* set up a minimal OS for successful Linux/m68k reboot */
+		ROMBaseHost[0x0030] = 0x46;		/* move.w #$2700,sr */
+		ROMBaseHost[0x0031] = 0xfc;
+		ROMBaseHost[0x0032] = 0x27;
+		ROMBaseHost[0x0033] = 0x00;
+		ROMBaseHost[0x0034] = 0x4e;		/* reset */
+		ROMBaseHost[0x0035] = 0x70;
+		ROMBaseHost[0x0036] = M68K_EMUL_RESET >> 8;
+		ROMBaseHost[0x0037] = M68K_EMUL_RESET & 0xff;
+	} else {
+		/* quit Hatari with NatFeats when Linux/m68k tries to reboot */
+		ROMBaseHost[0x0030] = 0x48;		/* pea.l NF_SHUTDOWN(pc) */
+		ROMBaseHost[0x0031] = 0x7a;
+		ROMBaseHost[0x0032] = 0x00;
+		ROMBaseHost[0x0033] = 0x0c;
+		ROMBaseHost[0x0034] = 0x59;		/* subq.l #4,sp */
+		ROMBaseHost[0x0035] = 0x8f;
+		ROMBaseHost[0x0036] = 0x73;		/* NF_ID */
+		ROMBaseHost[0x0037] = 0x00;
+		ROMBaseHost[0x0038] = 0x2f;		/* move.l d0,-(sp) */
+		ROMBaseHost[0x0039] = 0x00;
+		ROMBaseHost[0x003a] = 0x59;		/* subq.l #4,sp */
+		ROMBaseHost[0x003b] = 0x8f;
+		ROMBaseHost[0x003c] = 0x73;		/* NF_CALL */
+		ROMBaseHost[0x003d] = 0x01;
+		ROMBaseHost[0x003e] = 'N';		/* "NF_SHUTDOWN" */
+		ROMBaseHost[0x003f] = 'F';
+		ROMBaseHost[0x0040] = '_';
+		ROMBaseHost[0x0041] = 'S';
+		ROMBaseHost[0x0042] = 'H';
+		ROMBaseHost[0x0043] = 'U';
+		ROMBaseHost[0x0044] = 'T';
+		ROMBaseHost[0x0045] = 'D';
+		ROMBaseHost[0x0046] = 'O';
+		ROMBaseHost[0x0047] = 'W';
+		ROMBaseHost[0x0048] = 'N';
+		ROMBaseHost[0x0049] = 0;
+	}
+#endif
+	return netbsd_load();
+}
+
+/*--- Private functions ---*/
+
+static bool netbsd_load(void)
+{
+	const char *kernel_s  = ConfigureParams.Netbsd.szKernelFileName;
+	Elf32_Addr kernel_offset;
+	bool loaded;
+
+	void *kernel = NULL;
+	uint32_t kernel_length = 0;
+
+	/* Load the kernel */
+	kernel = load_file(kernel_s, &kernel_length);
+	if (!kernel) {
+		Log_AlertDlg(LOG_FATAL, "NetBSD: error loading NetBSD kernel:\n'%s'", kernel_s);
+		return false;
+	}
+
+	/* Check the kernel */
+	loaded = check_kernel(kernel, &kernel_offset);
+
+	/* Kernel copied in Atari RAM, we can free them */
+	free(kernel);
+
+	if (loaded) {
+	} else {
+		Log_AlertDlg(LOG_FATAL, "NetBSD: error setting up kernel!");
+	}
+	return true;
+}
+
+static void *load_file(const char *filename, uint32_t *length)
+{
+	void *buffer = NULL;
+	long nFileLength = 0;
+
+	if (strlen(filename) == 0) {
+		Dprintf(("NetBSD: empty filename\n"));
+		return NULL;
+	}
+
+#ifdef HAVE_LIBZ
+	buffer = File_ZlibRead(filename, &nFileLength);
+#else
+	buffer = File_ReadAsIs(filename, &nFileLength);
+#endif
+	*length = nFileLength;
+
+	if (buffer) {
+		Dprintf(("NetBSD: (uncompressed) '%s' size: %d bytes\n",
+			 filename, *length));
+	}
+	return buffer;
+}
+
+/**
+ * Load given kernel code to suitable memory area,
+ * and update bootinfo accordingly.
+ * Return true for success
+ */
+static bool check_kernel(void *kernel, Elf32_Addr *kernel_offset)
+{
+	/* map Hatari variables to Aranym code */
+	const uint32_t RAMSize = 1024 * ConfigureParams.Memory.STRamSize_KB;
+	uint8_t *RAMBaseHost = STRam;
+
+	const uint32_t FastRAMBase = 0x01000000;
+
+	/* TODO: separate FastRAM setting for kernel & ramdisk? */
+	const uint32_t FastRAMSize = TTmemory ? 1024 * ConfigureParams.Memory.TTRamSize_KB : 0;
+
+	Elf32_Ehdr *kexec_elf;	/* header of kernel executable */
+	Elf32_Phdr *kernel_phdrs;
+	Elf32_Addr min_addr = 0xffffffff, max_addr = 0;
+	Elf32_Addr kernel_size;
+	Elf32_Addr mem_ptr;
+	Elf32_Addr symsize, symstart;
+	uint32_t *tmp;
+	int i;
+	int debug_flag;
+	int no_symbols;
+	int stmem_only;
+	char *ptr;
+
+	bi.boothowto = RB_SINGLE;
+	debug_flag = 0;
+	no_symbols = 0;
+	stmem_only = 0;
+
+	/* NetBSD does not seem to have a way to pass arguments to the kernel,
+	   but we handle a few that loadbsd does */
+	ptr = ConfigureParams.Netbsd.szCommandLine;
+	while (*ptr != '\0')
+	{
+		while (*ptr == ' ')
+			ptr++;
+		if (*ptr == '-')
+		{
+			++ptr;
+			switch (*ptr)
+			{
+			case 'a': /* autoboot: Boot up to multi-user mode. */
+				bi.boothowto &= ~(RB_SINGLE);
+				bi.boothowto |= RB_AUTOBOOT;
+				break;
+			case 'b': /* Ask for root device to use. */
+				bi.boothowto |= RB_ASKNAME;
+				break;
+			case 'd': /* Enter kernel debugger. */
+				bi.boothowto |= RB_KDB;
+				break;
+			case 'D': /* printout debug information while loading */
+				debug_flag = 1;
+				break;
+			case 'N':
+				no_symbols = 1; /* No symbols must be loaded. */
+				break;
+			case 's':
+				stmem_only = 1;
+				break;
+			}
+		}
+		while (*ptr != '\0' && *ptr != ' ')
+			ptr++;
+	}
+
+	if (!set_machine_type()) {
+		return false;
+	}
+
+	kexec_elf = (Elf32_Ehdr *) kernel;
+	if (memcmp(&kexec_elf->e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0 ||
+		SDL_SwapBE16(kexec_elf->e_type) != ET_EXEC ||
+		SDL_SwapBE16(kexec_elf->e_machine) != EM_68K ||
+		SDL_SwapBE32(kexec_elf->e_version) != EV_CURRENT) {
+		fprintf(stderr, "NetBSD: Invalid ELF header contents in kernel\n");
+		return false;
+	}
+
+	/*--- Copy the kernel at start of RAM ---*/
+
+	/* Load the program headers */
+	kernel_phdrs = (Elf32_Phdr *) (((char *) kexec_elf) + SDL_SwapBE32(kexec_elf->e_phoff));
+
+	/* calculate the total required amount of memory */
+	Dprintf(("NetBSD: kexec_elf->e_phnum = 0x%08x\n", SDL_SwapBE16(kexec_elf->e_phnum)));
+
+	for (i = 0; i < SDL_SwapBE16(kexec_elf->e_phnum); i++) {
+		if (debug_flag)
+		{
+			printf("NetBSD: kernel_phdrs[%d].p_vaddr  = 0x%08x\n", i, SDL_SwapBE32(kernel_phdrs[i].p_vaddr));
+			printf("NetBSD: kernel_phdrs[%d].p_offset = 0x%08x\n", i, SDL_SwapBE32(kernel_phdrs[i].p_offset));
+			printf("NetBSD: kernel_phdrs[%d].p_filesz = 0x%08x\n", i, SDL_SwapBE32(kernel_phdrs[i].p_filesz));
+			printf("NetBSD: kernel_phdrs[%d].p_memsz  = 0x%08x\n", i, SDL_SwapBE32(kernel_phdrs[i].p_memsz));
+		}
+
+		if (min_addr > SDL_SwapBE32(kernel_phdrs[i].p_vaddr)) {
+			min_addr = SDL_SwapBE32(kernel_phdrs[i].p_vaddr);
+		}
+		if (max_addr < SDL_SwapBE32(kernel_phdrs[i].p_vaddr) + SDL_SwapBE32(kernel_phdrs[i].p_memsz)) {
+			max_addr = SDL_SwapBE32(kernel_phdrs[i].p_vaddr) + SDL_SwapBE32(kernel_phdrs[i].p_memsz);
+		}
+	}
+
+	kernel_size = max_addr - min_addr;
+	Dprintf(("NetBSD: kernel_size = %u\n", kernel_size));
+	Dprintf(("NetBSD: %d kB ST-RAM, %d kB TT-RAM\n",
+		 ConfigureParams.Memory.STRamSize_KB,
+		 ConfigureParams.Memory.TTRamSize_KB));
+
+	/*
+	 * look for symbols and calculate the size
+	 * XXX: This increases the load time by a factor 2 for gzipped
+	 *      images!
+	 */
+	symsize = 0;
+	symstart = 0;
+	if (!no_symbols)
+	{
+		Elf32_Shdr *shdr = (Elf32_Shdr *) ((char *) kexec_elf + SDL_SwapBE32(kexec_elf->e_shoff));
+		for (i = 0; i < SDL_SwapBE16(kexec_elf->e_shnum); i++)
+		{
+			if (SDL_SwapBE32(shdr[i].sh_type) == SHT_SYMTAB || SDL_SwapBE32(shdr[i].sh_type) == SHT_STRTAB)
+			{
+				if (shdr[i].sh_offset != 0)
+				{
+					Elf32_Addr size = SDL_SwapBE32(shdr[i].sh_size);
+					size = (size + 3) & -4;
+					symsize += size;
+				}
+			}
+		}
+	}
+
+	if (symsize != 0)
+	{
+		symstart = kernel_size;
+		kernel_size += symsize + sizeof(*kexec_elf) + SDL_SwapBE16(kexec_elf->e_shnum) * sizeof(Elf32_Shdr);
+	}
+
+	/*
+	 * Note: the kernel copies itself to ST-RAM upon startup,
+	 * so there is no point in loading it into FastRAM first
+	 */
+	if (KERNEL_START + kernel_size > RAMSize) {
+		fprintf(stderr, "NetBSD: kernel of size %x does not fit in RAM of size %x\n", kernel_size, RAMSize);
+		return false;
+	}
+
+	*kernel_offset = 0;
+	mem_ptr = KERNEL_START;
+	int segments = SDL_SwapBE16(kexec_elf->e_phnum);
+	Dprintf(("NetBSD: copying %d segments to %s...\n", segments,
+		 "ST-RAM"));
+	for (i = 0; i < segments; i++) {
+		Elf32_Word segment_length;
+		Elf32_Addr segment_ptr;
+		Elf32_Off segment_offset;
+
+		segment_offset = SDL_SwapBE32(kernel_phdrs[i].p_offset);
+		segment_length = SDL_SwapBE32(kernel_phdrs[i].p_filesz);
+
+		if (segment_offset == 0xffffffffu) {
+			fprintf(stderr, "NetBSD: Failed to seek to segment %d\n", i);
+			return false;
+		}
+		segment_ptr = SDL_SwapBE32(kernel_phdrs[i].p_vaddr);
+
+		if (debug_flag)
+		{
+			printf("NetBSD: Copying segment %d: 0x%08x,0x%08x to 0x%08x-0x%08x\n", i, segment_offset, segment_length, *kernel_offset + mem_ptr + segment_ptr, *kernel_offset + mem_ptr + segment_ptr + segment_length);
+		}
+		memcpy(RAMBaseHost + mem_ptr + segment_ptr, (char *) kexec_elf + segment_offset, segment_length);
+	}
+
+	/*
+	 * Read symbols and strings
+	 */
+	if (symsize != 0)
+	{
+		unsigned char *p, *symtab;
+		int nhdrs;
+		Elf32_Shdr *shp;
+		Elf32_Addr size;
+
+		symtab = RAMBaseHost + KERNEL_START + symstart;
+
+		p = symtab + sizeof(*kexec_elf);
+		nhdrs = SDL_SwapBE16(kexec_elf->e_shnum);
+		memcpy(p, (char *) kexec_elf + SDL_SwapBE32(kexec_elf->e_shoff), nhdrs * sizeof(*shp));
+		shp = (Elf32_Shdr*)p;
+		p += nhdrs * sizeof(*shp);
+		for (i = 0; i < nhdrs; i++)
+		{
+			if (SDL_SwapBE32(shp[i].sh_type) == SHT_SYMTAB || SDL_SwapBE32(shp[i].sh_type) == SHT_STRTAB)
+			{
+				if (shp[i].sh_offset != 0)
+				{
+					/* Get the symbol table. */
+					size = SDL_SwapBE32(shp[i].sh_size);
+					if (debug_flag)
+					{
+						uint32_t pmem = (uint32_t)(p - RAMBaseHost);
+						printf("NetBSD: Copying %s: 0x%08x,0x%08x to 0x%08x-0x%08x\n", SDL_SwapBE32(shp[i].sh_type) == SHT_SYMTAB ? "symbol table" : "symbol strings",
+							SDL_SwapBE32(shp[i].sh_offset), size, pmem, pmem + SDL_SwapBE32(shp[i].sh_size));
+					}
+					memcpy(p, (char *) kexec_elf + SDL_SwapBE32(shp[i].sh_offset), size);
+					shp[i].sh_offset = SDL_SwapBE32(p - symtab);
+					size = (size + 3) & -4;
+					p += size;
+				}
+			}
+		}
+		kexec_elf->e_shoff = SDL_SwapBE32(sizeof(*kexec_elf));
+		memcpy(symtab, kexec_elf, sizeof(*kexec_elf));
+	}
+
+	/*--- Create the bootinfo structure ---*/
+
+	/* Machine type, memory banks */
+	bi.kp = *kernel_offset + KERNEL_START;
+	bi.ksize = kernel_size;
+	bi.entry = SDL_SwapBE32(kexec_elf->e_entry);
+	bi.stmem_size = RAMSize;
+	bi.ttmem_size = stmem_only ? 0 : FastRAMSize;
+	bi.ttmem_start = FastRAMBase;
+	bi.esym_loc = symsize ? kernel_size : 0;
+
+	if (debug_flag)
+	{
+		printf("Machine info:\n");
+		printf("ST-RAM size\t: %10d bytes\n", bi.stmem_size);
+		printf("TT-RAM size\t: %10d bytes\n", bi.ttmem_size);
+		printf("TT-RAM start\t: 0x%08x\n", bi.ttmem_start);
+		printf("Cpu-type\t: 0x%08x\n", bi.bootflags);
+		printf("Kernel loadaddr\t: 0x%08x\n", bi.kp);
+		printf("Kernel size\t: %10d (0x%x) bytes\n", bi.ksize, bi.ksize);
+		printf("Kernel entry\t: 0x%08x\n", bi.entry);
+		printf("Kernel esym\t: 0x%08x\n", bi.esym_loc);
+	}
+
+	/*--- Init SP & PC ---*/
+	tmp = (uint32_t *)RAMBaseHost;
+	tmp[0] = SDL_SwapBE32(*kernel_offset + KERNEL_START);	/* SP */
+	tmp[1] = SDL_SwapBE32(0x00e00000);		/* PC = ROMBase */
+
+	uint8_t *ROMBaseHost = &RomMem[0x00e00000];
+
+	/* fill in the jmp address at start of ROM, to the kernel entry point */
+	tmp = (uint32_t *)ROMBaseHost;
+	tmp[1] = SDL_SwapBE32(bi.kp + bi.entry);
+
+	/*
+	 * the BSD kernel wants values into the following registers:
+	 * d0:  ttmem-size
+	 * d1:  stmem-size
+	 * d2:  cputype
+	 * d3:  boothowto
+	 * d4:  length of loaded kernel
+	 * d5:  start of fastram
+	 * a0:  start of loaded kernel
+	 * a1:  end of symbols (esym)
+	 * All other registers zeroed for possible future requirements.
+	 */
+	regs.regs[0] = bi.ttmem_size;
+	regs.regs[1] = bi.stmem_size;
+	regs.regs[2] = bi.bootflags;
+	regs.regs[3] = bi.boothowto;
+	regs.regs[4] = bi.ksize;
+	regs.regs[5] = bi.ttmem_start;
+	regs.regs[6] = 0;
+	regs.regs[7] = 0;
+	regs.regs[8] = bi.kp;
+	regs.regs[9] = bi.esym_loc;
+	regs.regs[10] = 0;
+	regs.regs[11] = 0;
+	regs.regs[12] = 0;
+	regs.regs[13] = 0;
+	regs.regs[14] = 0;
+
+	/* beware: make sure those register values remain valid until M68000_Start() is called */
+
+	Dprintf(("NetBSD: OK\n"));
+
+	return true;
+}
+
+/**
+ * Set machine type settings to bootinfo based on Hatari configuration
+ * Return true for success
+ */
+static bool set_machine_type(void)
+{
+	bi.bootflags = 0;
+
+	switch (ConfigureParams.System.nMachineType) {
+	case MACHINE_FALCON:
+		bi.bootflags |= ATARI_FALCON;
+		break;
+	case MACHINE_TT:
+		bi.bootflags |= ATARI_TT;
+		break;
+	case MACHINE_STE:
+	case MACHINE_MEGA_STE:
+		break;
+	case MACHINE_ST:
+	case MACHINE_MEGA_ST:
+		break;
+	}
+
+	switch(ConfigureParams.System.nCpuLevel) {
+	case 3:
+		bi.bootflags |= ATARI_68030;
+		break;
+	case 4:
+		bi.bootflags |= ATARI_68040;
+		break;
+	case 5:
+		bi.bootflags |= ATARI_68060;
+		break;
+	default:
+		Log_AlertDlg(LOG_FATAL, "NetBSD: BSD requires at least 030 CPU (for MMU), not 0%d0!",
+			ConfigureParams.System.nCpuLevel);
+		return false;
+	}
+	return true;
+}
diff --git a/src/options.c b/src/options.c
index 2037c876..4aee8036 100644
--- a/src/options.c
+++ b/src/options.c
@@ -46,6 +46,7 @@ const char Options_fileid[] = "Hatari options.c";
 #include "stMemory.h"
 #include "tos.h"
 #include "lilo.h"
+#include "netbsd.h"
 
 
 bool bLoadAutoSave;        /* Load autosave memory snapshot at startup */
@@ -189,6 +190,7 @@ enum {
 	OPT_DEBUG,
 	OPT_EXCEPTIONS,
 	OPT_LILO,
+	OPT_NETBSD,
 	OPT_BIOSINTERCEPT,
 	OPT_CONOUT,
 	OPT_DISASM,
@@ -477,6 +479,7 @@ static const opt_t HatariOptions[] = {
 	{ OPT_EXCEPTIONS, NULL, "--debug-except",
 	  "<flags>", "Exceptions invoking debugger, see '--debug-except help'" },
 	{ OPT_LILO, NULL, "--lilo", "<x>", "Boot Linux (see manual page)" },
+	{ OPT_NETBSD, NULL, "--netbsd", NULL, "Boot NetBSD (see manual page)" },
 	{ OPT_BIOSINTERCEPT, NULL, "--bios-intercept",
 	  "<bool>", "Enable/disable XBIOS command parsing support" },
 	{ OPT_CONOUT,   NULL, "--conout",
@@ -2129,6 +2132,14 @@ bool Opt_ParseParameters(int argc, const char * const argv[])
 			break;
 		}
 
+		case OPT_NETBSD: {
+			bLoadAutoSave = false;
+			bUseNetbsd = true;
+			bUseTos = false;
+			ConfigureParams.HardDisk.bUseHardDiskDirectories = false;
+			break;
+		}
+
 		case OPT_BIOSINTERCEPT:
 			ok = Opt_Bool(argv[++i], OPT_BIOSINTERCEPT, &bBiosIntercept);
 			Log_Printf(LOG_DEBUG, "XBIOS 11/20/255 Hatari versions %sabled: "
diff --git a/src/tos.c b/src/tos.c
index c5006798..e980e0dc 100644
--- a/src/tos.c
+++ b/src/tos.c
@@ -35,6 +35,7 @@ const char TOS_fileid[] = "Hatari tos.c";
 #include "str.h"
 #include "tos.h"
 #include "lilo.h"
+#include "netbsd.h"
 #include "vdi.h"
 #include "falcon/dsp.h"
 #include "clocks_timings.h"
@@ -1276,6 +1277,13 @@ int TOS_InitImage(void)
 		if (!lilo_init())
 			return -1;
 	}
+	else if (bUseNetbsd)
+	{
+		TosSize = 0;
+		/* load NetBSD */
+		if (!netbsd_init())
+			return -1;
+	}
 	else if (!bUseTos)
 	{
 		/* Load test program (has to be done after memory has been cleared) */
-- 
2.24.0


--nextPart47411014.jKvtMvv4xN
Content-Disposition: attachment; filename="0002-Move-common-definitions-in-lilo.c-netbsd.c-to-elf.h.patch"
Content-Transfer-Encoding: 7Bit
Content-Type: text/x-patch; charset="UTF-8"; name="0002-Move-common-definitions-in-lilo.c-netbsd.c-to-elf.h.patch"



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/