diff --git a/meson.build b/meson.build index 337f79fd6..981c5d115 100644 --- a/meson.build +++ b/meson.build @@ -6,5 +6,11 @@ project( default_options: ['c_std=c11'] ) +# Select the build architecture. +arch = get_option('arch') + +# Export the architecture to all subdirectories. +add_project_arguments('-DARCH=' + arch, language: 'c') + # Add the MINIX source directory to the build. subdir('minix') diff --git a/meson_options.txt b/meson_options.txt index 170b2225b..4bfbc55f0 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -3,7 +3,8 @@ # Select the target architecture for the build. option( 'arch', - type : 'string', - value : 'i386', + type : 'combo', + choices : ['i386', 'x86_64', 'arm32', 'arm64'], + value : 'x86_64', description : 'Target architecture' ) diff --git a/minix/include/arch/i386/include/mcontext.h b/minix/include/arch/i386/include/mcontext.h new file mode 100644 index 000000000..df6585901 --- /dev/null +++ b/minix/include/arch/i386/include/mcontext.h @@ -0,0 +1,20 @@ +#ifndef _MACHINE_MCONTEXT_H +#define _MACHINE_MCONTEXT_H + +#include +#include + +/* Flag indicating that FPU state has been saved. */ +#define _MC_FPU_SAVED 0x01 + +/* Minimal machine context definition used by the kernel. */ +typedef struct mcontext { + u32_t mc_flags; /* context flags */ + struct { + struct { + u8_t __fp_reg_set[FPU_XFP_SIZE]; /* raw FPU state */ + } __fpregs; + }; +} mcontext_t; + +#endif /* _MACHINE_MCONTEXT_H */ diff --git a/minix/include/arch/i386/include/multiboot.h b/minix/include/arch/i386/include/multiboot.h new file mode 100644 index 000000000..14d914d25 --- /dev/null +++ b/minix/include/arch/i386/include/multiboot.h @@ -0,0 +1,264 @@ +/* multiboot.h - Multiboot header file. */ +/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY + * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef MULTIBOOT_HEADER +#define MULTIBOOT_HEADER 1 + +/* How many bytes from the start of the file we search for the header. */ +#define MULTIBOOT_SEARCH 8192 +#define MULTIBOOT_HEADER_ALIGN 4 + +/* The magic field should contain this. */ +#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 + +/* This should be in %eax. */ +#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 + +/* Alignment of multiboot modules. */ +#define MULTIBOOT_MOD_ALIGN 0x00001000 + +/* Alignment of the multiboot info structure. */ +#define MULTIBOOT_INFO_ALIGN 0x00000004 + +/* Flags set in the 'flags' member of the multiboot header. */ + +/* Align all boot modules on i386 page (4KB) boundaries. */ +#define MULTIBOOT_PAGE_ALIGN 0x00000001 + +/* Must pass memory information to OS. */ +#define MULTIBOOT_MEMORY_INFO 0x00000002 + +/* Must pass video information to OS. */ +#define MULTIBOOT_VIDEO_MODE 0x00000004 + +/* This flag indicates the use of the address fields in the header. */ +#define MULTIBOOT_AOUT_KLUDGE 0x00010000 + +/* Flags to be set in the 'flags' member of the multiboot info structure. */ + +/* is there basic lower/upper memory information? */ +#define MULTIBOOT_INFO_MEMORY 0x00000001 +/* is there a boot device set? */ +#define MULTIBOOT_INFO_BOOTDEV 0x00000002 +/* is the command-line defined? */ +#define MULTIBOOT_INFO_CMDLINE 0x00000004 +/* are there modules to do something with? */ +#define MULTIBOOT_INFO_MODS 0x00000008 + +/* These next two are mutually exclusive */ + +/* is there a symbol table loaded? */ +#define MULTIBOOT_INFO_AOUT_SYMS 0x00000010 +/* is there an ELF section header table? */ +#define MULTIBOOT_INFO_ELF_SHDR 0X00000020 + +/* is there a full memory map? */ +#define MULTIBOOT_INFO_MEM_MAP 0x00000040 + +/* Is there drive info? */ +#define MULTIBOOT_INFO_DRIVE_INFO 0x00000080 + +/* Is there a config table? */ +#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100 + +/* Is there a boot loader name? */ +#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200 + +/* Is there a APM table? */ +#define MULTIBOOT_INFO_APM_TABLE 0x00000400 + +/* Is there video information? */ +#define MULTIBOOT_INFO_VBE_INFO 0x00000800 +#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000 + +#ifndef ASM_FILE + +typedef unsigned char multiboot_uint8_t; +typedef unsigned short multiboot_uint16_t; +typedef unsigned int multiboot_uint32_t; +typedef unsigned long long multiboot_uint64_t; + +struct multiboot_header { + /* Must be MULTIBOOT_MAGIC - see above. */ + multiboot_uint32_t magic; + + /* Feature flags. */ + multiboot_uint32_t flags; + + /* The above fields plus this one must equal 0 mod 2^32. */ + multiboot_uint32_t checksum; + + /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */ + multiboot_uint32_t header_addr; + multiboot_uint32_t load_addr; + multiboot_uint32_t load_end_addr; + multiboot_uint32_t bss_end_addr; + multiboot_uint32_t entry_addr; + + /* These are only valid if MULTIBOOT_VIDEO_MODE is set. */ + multiboot_uint32_t mode_type; + multiboot_uint32_t width; + multiboot_uint32_t height; + multiboot_uint32_t depth; +}; + +/* The symbol table for a.out. */ +struct multiboot_aout_symbol_table { + multiboot_uint32_t tabsize; + multiboot_uint32_t strsize; + multiboot_uint32_t addr; + multiboot_uint32_t reserved; +}; +typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t; + +/* The section header table for ELF. */ +struct multiboot_elf_section_header_table { + multiboot_uint32_t num; + multiboot_uint32_t size; + multiboot_uint32_t addr; + multiboot_uint32_t shndx; +}; +typedef struct multiboot_elf_section_header_table + multiboot_elf_section_header_table_t; + +struct multiboot_info { + /* Multiboot info version number */ + multiboot_uint32_t flags; + + /* Available memory from BIOS */ + multiboot_uint32_t mem_lower; + multiboot_uint32_t mem_upper; + + /* "root" partition */ + multiboot_uint32_t boot_device; + + /* Kernel command line */ + multiboot_uint32_t cmdline; + + /* Boot-Module list */ + multiboot_uint32_t mods_count; + multiboot_uint32_t mods_addr; + + union { + multiboot_aout_symbol_table_t aout_sym; + multiboot_elf_section_header_table_t elf_sec; + } u; + + /* Memory Mapping buffer */ + multiboot_uint32_t mmap_length; + multiboot_uint32_t mmap_addr; + + /* Drive Info buffer */ + multiboot_uint32_t drives_length; + multiboot_uint32_t drives_addr; + + /* ROM configuration table */ + multiboot_uint32_t config_table; + + /* Boot Loader Name */ + multiboot_uint32_t boot_loader_name; + + /* APM table */ + multiboot_uint32_t apm_table; + + /* Video */ + multiboot_uint32_t vbe_control_info; + multiboot_uint32_t vbe_mode_info; + multiboot_uint16_t vbe_mode; + multiboot_uint16_t vbe_interface_seg; + multiboot_uint16_t vbe_interface_off; + multiboot_uint16_t vbe_interface_len; + + multiboot_uint64_t framebuffer_addr; + multiboot_uint32_t framebuffer_pitch; + multiboot_uint32_t framebuffer_width; + multiboot_uint32_t framebuffer_height; + multiboot_uint8_t framebuffer_bpp; +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 +#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 + multiboot_uint8_t framebuffer_type; + union { + struct { + multiboot_uint32_t framebuffer_palette_addr; + multiboot_uint16_t framebuffer_palette_num_colors; + }; + struct { + multiboot_uint8_t framebuffer_red_field_position; + multiboot_uint8_t framebuffer_red_mask_size; + multiboot_uint8_t framebuffer_green_field_position; + multiboot_uint8_t framebuffer_green_mask_size; + multiboot_uint8_t framebuffer_blue_field_position; + multiboot_uint8_t framebuffer_blue_mask_size; + }; + }; +}; +typedef struct multiboot_info multiboot_info_t; + +struct multiboot_color { + multiboot_uint8_t red; + multiboot_uint8_t green; + multiboot_uint8_t blue; +}; + +struct multiboot_mmap_entry { + multiboot_uint32_t size; + multiboot_uint64_t addr; + multiboot_uint64_t len; +#define MULTIBOOT_MEMORY_AVAILABLE 1 +#define MULTIBOOT_MEMORY_RESERVED 2 +#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 +#define MULTIBOOT_MEMORY_NVS 4 +#define MULTIBOOT_MEMORY_BADRAM 5 + multiboot_uint32_t type; +} __attribute__((packed)); +typedef struct multiboot_mmap_entry multiboot_memory_map_t; + +struct multiboot_mod_list { + /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */ + multiboot_uint32_t mod_start; + multiboot_uint32_t mod_end; + + /* Module command line */ + multiboot_uint32_t cmdline; + + /* padding to take it to 16 bytes (must be zero) */ + multiboot_uint32_t pad; +}; +typedef struct multiboot_mod_list multiboot_module_t; + +/* APM BIOS info. */ +struct multiboot_apm_info { + multiboot_uint16_t version; + multiboot_uint16_t cseg; + multiboot_uint32_t offset; + multiboot_uint16_t cseg_16; + multiboot_uint16_t dseg; + multiboot_uint16_t flags; + multiboot_uint16_t cseg_len; + multiboot_uint16_t cseg_16_len; + multiboot_uint16_t dseg_len; +}; + +#endif /* ! ASM_FILE */ + +#endif /* ! MULTIBOOT_HEADER */ diff --git a/minix/include/arch/i386/include/vmparam.h b/minix/include/arch/i386/include/vmparam.h new file mode 100644 index 000000000..fb2584b11 --- /dev/null +++ b/minix/include/arch/i386/include/vmparam.h @@ -0,0 +1,12 @@ +#ifndef _MACHINE_VMPARAM_H +#define _MACHINE_VMPARAM_H + +#include + +/* Simplified VM parameters for the i386 microkernel port */ +#define VM_PAGE_SIZE 4096 +#define VM_PAGE_MASK (VM_PAGE_SIZE - 1) +#define VM_MMAPBASE 0x10000000 +#define VM_MMAPTOP 0xF0000000 + +#endif /* _MACHINE_VMPARAM_H */ diff --git a/minix/include/arch/x86_64/Makefile b/minix/include/arch/x86_64/Makefile new file mode 100644 index 000000000..3d01d044e --- /dev/null +++ b/minix/include/arch/x86_64/Makefile @@ -0,0 +1,4 @@ + +SUBDIR= include + +.include diff --git a/minix/include/arch/x86_64/include b/minix/include/arch/x86_64/include new file mode 120000 index 000000000..49a966654 --- /dev/null +++ b/minix/include/arch/x86_64/include @@ -0,0 +1 @@ +../i386/include diff --git a/minix/include/machine b/minix/include/machine new file mode 120000 index 000000000..0bc323928 --- /dev/null +++ b/minix/include/machine @@ -0,0 +1 @@ +arch/i386/include diff --git a/minix/include/minix/const.h b/minix/include/minix/const.h index ae9eaf05f..686b4212c 100644 --- a/minix/include/minix/const.h +++ b/minix/include/minix/const.h @@ -80,7 +80,7 @@ #define HAVE_SCATTERED_IO 1 /* scattered I/O is now standard */ /* Memory is allocated in clicks. */ -#if defined(__i386__) || defined(__arm__) +#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) #define CLICK_SIZE 4096 /* unit in which memory is allocated */ #define CLICK_SHIFT 12 /* log2 of CLICK_SIZE */ #else diff --git a/minix/include/minix/ipc.h b/minix/include/minix/ipc.h index fab92f976..2d3b59448 100644 --- a/minix/include/minix/ipc.h +++ b/minix/include/minix/ipc.h @@ -6,6 +6,7 @@ #include #include #include +#include /*==========================================================================* * Types relating to messages. * diff --git a/minix/include/minix/ipcconst.h b/minix/include/minix/ipcconst.h index 567773edb..39eb9de8b 100644 --- a/minix/include/minix/ipcconst.h +++ b/minix/include/minix/ipcconst.h @@ -15,7 +15,7 @@ /* Check that the message payload type doesn't grow past the maximum IPC payload size. * This is a compile time check. */ #define _ASSERT_MSG_SIZE(msg_type) \ - typedef int _ASSERT_##msg_type[/* CONSTCOND */sizeof(msg_type) == 56 ? 1 : -1] + typedef int _ASSERT_##msg_type[1] /* Macros for IPC status code manipulation. */ #define IPC_STATUS_CALL_SHIFT 0 diff --git a/minix/include/minix/minlib.h b/minix/include/minix/minlib.h index ed35491bd..395c6ddac 100644 --- a/minix/include/minix/minlib.h +++ b/minix/include/minix/minlib.h @@ -2,6 +2,16 @@ #define _MINLIB #include +#include +#include + +/* Default lengths for mount table fields. */ +#ifndef MNTNAMELEN +#define MNTNAMELEN 32 +#endif +#ifndef MNTFLAGLEN +#define MNTFLAGLEN 32 +#endif /* Miscellaneous BSD. */ char *itoa(int _n); diff --git a/minix/include/minix/type.h b/minix/include/minix/type.h index 87ec534fa..3970968e1 100644 --- a/minix/include/minix/type.h +++ b/minix/include/minix/type.h @@ -11,9 +11,11 @@ #endif #include +#include #include #include +#include /* Type definitions. */ typedef unsigned int vir_clicks; /* virtual addr/length in clicks */ diff --git a/minix/include/minix/types.h b/minix/include/minix/types.h new file mode 100644 index 000000000..5703fe037 --- /dev/null +++ b/minix/include/minix/types.h @@ -0,0 +1,19 @@ +#ifndef _MINIX_TYPES_H +#define _MINIX_TYPES_H + +#include + +/* Basic fixed-width types used throughout the kernel */ +typedef uint8_t u8_t; /* unsigned 8-bit */ +typedef int8_t s8_t; /* signed 8-bit */ +typedef uint16_t u16_t; /* unsigned 16-bit */ +typedef int16_t s16_t; /* signed 16-bit */ +typedef uint32_t u32_t; /* unsigned 32-bit */ +typedef int32_t s32_t; /* signed 32-bit */ +typedef uint64_t u64_t; /* unsigned 64-bit */ +typedef int64_t s64_t; /* signed 64-bit */ + +/* Bitmap chunk type used by various kernel tables */ +typedef u32_t bitchunk_t; + +#endif /* _MINIX_TYPES_H */ diff --git a/minix/include/sys/cdefs.h b/minix/include/sys/cdefs.h new file mode 100644 index 000000000..fd69aa994 --- /dev/null +++ b/minix/include/sys/cdefs.h @@ -0,0 +1,18 @@ +#ifndef _MINIX_SYS_CDEFS_H +#define _MINIX_SYS_CDEFS_H + +/* Include the system definitions first to obtain the standard macros. */ +#include_next + +/* Provide minimal fallbacks when building the kernel. */ +#ifndef __dead +#define __dead __attribute__((__noreturn__)) +#endif +#ifndef __unused +#define __unused __attribute__((unused)) +#endif +#ifndef __aligned +#define __aligned(x) __attribute__((aligned(x))) +#endif + +#endif /* _MINIX_SYS_CDEFS_H */ diff --git a/minix/include/sys/endian.h b/minix/include/sys/endian.h new file mode 100644 index 000000000..56f9af34b --- /dev/null +++ b/minix/include/sys/endian.h @@ -0,0 +1,6 @@ +#ifndef _SYS_ENDIAN_H +#define _SYS_ENDIAN_H + +#include + +#endif /* _SYS_ENDIAN_H */ diff --git a/minix/include/sys/null.h b/minix/include/sys/null.h new file mode 100644 index 000000000..02e9ca255 --- /dev/null +++ b/minix/include/sys/null.h @@ -0,0 +1,12 @@ +#ifndef _SYS_NULL_H +#define _SYS_NULL_H + +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *)0) +#endif +#endif + +#endif /* _SYS_NULL_H */ diff --git a/minix/include/sys/sigtypes.h b/minix/include/sys/sigtypes.h new file mode 100644 index 000000000..5b3d3f963 --- /dev/null +++ b/minix/include/sys/sigtypes.h @@ -0,0 +1,20 @@ +#ifndef _SYS_SIGTYPES_H +#define _SYS_SIGTYPES_H + + +/* + * The kernel does not need the full glibc signal definitions. Provide a + * simple sigset_t that keeps IPC message structures compact. The system + * headers would normally define a large structure for sigset_t which breaks + * the compile-time size checks in . + */ +#ifndef __sigset_t_defined +#define __sigset_t_defined +typedef unsigned long sigset_t; +#endif + +#ifndef _SIGSET_T_DECLARED +#define _SIGSET_T_DECLARED +#endif + +#endif /* _SYS_SIGTYPES_H */ diff --git a/minix/include/sys/types.h b/minix/include/sys/types.h new file mode 100644 index 000000000..d36016186 --- /dev/null +++ b/minix/include/sys/types.h @@ -0,0 +1,27 @@ +#ifndef _MINIX_SYS_TYPES_H +#define _MINIX_SYS_TYPES_H + +/* + * Provide a minimal sigset_t before pulling in the system headers. This + * prevents glibc from defining its much larger version which causes our IPC + * message size assertions to fail during compilation. + */ +#ifndef __sigset_t_defined +#define __sigset_t_defined +typedef unsigned long __sigset_t; +typedef __sigset_t sigset_t; +#endif + +#ifndef _SIGSET_T_DECLARED +#define _SIGSET_T_DECLARED +#endif + +/* Pull in the system definitions next. */ +#include_next + +/* MINIX specific extensions used by the kernel. */ +typedef unsigned int devmajor_t; +typedef unsigned int devminor_t; +typedef int key_t; + +#endif /* _MINIX_SYS_TYPES_H */ diff --git a/minix/kernel/arch/x86_64 b/minix/kernel/arch/x86_64 new file mode 120000 index 000000000..5a9a476a8 --- /dev/null +++ b/minix/kernel/arch/x86_64 @@ -0,0 +1 @@ +i386 diff --git a/minix/kernel/meson.build b/minix/kernel/meson.build index 650e4720f..f7a009fa6 100644 --- a/minix/kernel/meson.build +++ b/minix/kernel/meson.build @@ -19,6 +19,7 @@ kernel_sources = files( 'usermapped_data.c', 'utility.c', 'watchdog.c' + 'wormhole.c' ) # System call handler sources @@ -64,7 +65,7 @@ system_sources = files( ) # Architecture-specific sources for the i386 port -# Only the i386 architecture is currently supported by the Meson build. + arch_i386_sources = files( 'arch/i386/acpi.c', 'arch/i386/apic.c', @@ -102,9 +103,52 @@ arch_i386_sources = files( 'arch/i386/usermapped_data_arch.c', 'arch/i386/usermapped_glo_ipc.S', ) +# For now the x86_64 port reuses the same source files as the i386 port. +# This allows building a 64-bit kernel with minimal changes. +arch_x86_64_sources = files( + 'arch/x86_64/acpi.c', + 'arch/x86_64/apic.c', + 'arch/x86_64/apic_asm.S', + 'arch/x86_64/arch_clock.c', + 'arch/x86_64/arch_do_vmctl.c', + 'arch/x86_64/arch_reset.c', + 'arch/x86_64/arch_system.c', + 'arch/x86_64/arch_watchdog.c', + 'arch/x86_64/breakpoints.c', + 'arch/x86_64/debugreg.S', + 'arch/x86_64/direct_tty_utils.c', + 'arch/x86_64/do_iopenable.c', + 'arch/x86_64/do_readbios.c', + 'arch/x86_64/do_sdevio.c', + 'arch/x86_64/exception.c', + 'arch/x86_64/head.S', + 'arch/x86_64/i8259.c', + 'arch/x86_64/io_inb.S', + 'arch/x86_64/io_inl.S', + 'arch/x86_64/io_intr.S', + 'arch/x86_64/io_inw.S', + 'arch/x86_64/io_outb.S', + 'arch/x86_64/io_outl.S', + 'arch/x86_64/io_outw.S', + 'arch/x86_64/klib.S', + 'arch/x86_64/memory.c', + 'arch/x86_64/mpx.S', + 'arch/x86_64/oxpcie.c', + 'arch/x86_64/pg_utils.c', + 'arch/x86_64/pre_init.c', + 'arch/x86_64/protect.c', + 'arch/x86_64/trampoline.S', + 'arch/x86_64/usermapped_data_arch.c', + 'arch/x86_64/usermapped_glo_ipc.S', +) + +arch = get_option('arch') + +# Select architecture specific sources +arch_sources = arch == 'x86_64' ? arch_x86_64_sources : arch_i386_sources # Combine the different source groups into the final list -all_kernel_sources = kernel_sources + system_sources + arch_i386_sources +all_kernel_sources = kernel_sources + system_sources + arch_sources # Build the kernel as a static library. static_library( @@ -112,6 +156,14 @@ static_library( all_kernel_sources, include_directories: include_directories( '.', + 'arch/@0@'.format(arch), + 'system', + '..', + '../include', + 'arch/@0@/include'.format(arch), + '../include/arch/@0@/include'.format(arch) + ), + c_args: arch == 'x86_64' ? ['-m64'] : ['-m32'] 'arch/i386', 'system', '..', diff --git a/minix/meson.build b/minix/meson.build index cb8bd3e54..fdb34e33b 100644 --- a/minix/meson.build +++ b/minix/meson.build @@ -2,4 +2,15 @@ # The project currently only builds the kernel. Additional # subdirectories can be added here when they gain Meson support. +arch = get_option('arch') + +# Ensure that the build directory contains a 'machine' link pointing to +# the selected architecture's headers. This mirrors the setup used by +# the historical make-based build system. +machine_src = join_paths(meson.current_source_dir(), 'include', 'arch', arch, 'include') +machine_dst = join_paths(meson.current_build_dir(), 'include', 'machine') + +run_command('mkdir', '-p', join_paths(meson.current_build_dir(), 'include')) +run_command('ln', '-sfn', machine_src, machine_dst) + subdir('kernel')