[PATCH 1/6] Add a NetBSD loader, ported over from ARAnyM |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/hatari-devel Archives
]
- Subject: [PATCH 1/6] Add a NetBSD loader, ported over from ARAnyM
- From: Thorsten Otto <admin@xxxxxxxxxxx>
- Date: Mon, 25 Jul 2022 06:33:54 +0200
---
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"