From 28c176b668c841a3b7fb093faccf0efa39257603 Mon Sep 17 00:00:00 2001 From: Lunaixsky Date: Tue, 16 Jul 2024 22:17:07 +0100 Subject: [PATCH] Architectural Support: x86_64 (#37) * x86_64 port: exception model, syscall, arch utils * add port to exception model: hart state transistion, general interruption hanlding * add port to syscall: call convention, operand size * arch utils change: udiv64, add native implementation * makefile: add dedicated action to do configuration * trace: port register dumping * other refactorings * port: virtual memory inteface, vm partition * add support to 64bits virtual memory management scheme * add definitions for memory partition under 64 bits * refactor: routine clean up, remove deprecated MEM_* * fix: reverse the order of lo/hi in struct x86_sysdesc * rename i386 to x86 for clarity * port: boot code, preliminary memory setup * add boot code port to x86_64, include IA32e mode switching sequence recommended by Intel * add support of x86_64 to memory setup * refactor: move boot code into two separated directory for clarity * refactor: boot_helper: memory reservation code should go to arch-specific * feat: architectural-dependent linking * preprocess the linker script with gcc's preprocessor before commencing the linking * fix: LConfig: x86_feature setting missing when arch=x86_64 * decouple elf loading. Make thing compile * decouple the arch-related elf parsing and loading part from the kernel base * fix compiliation issues when compiling under 64 bit mode * fix a relocation issue where the boot code reference a symbol exported from relocated kernel's LMA for address calculation. * make thing more unified in LBuild * port other misc stuff to x86_64 * add boilerplate for multiboot2 bootloader interface * ensure the i386 invariant after refactroing for baseline * port: remove hidden assumption of VMS_SELF in vm model * creation of those lntep pteps mades a hidden assumption of VMS_SELF address used, which introduce inflexibility * adjust the vm map of x86_64 to make sure kernel's address can be relocated with R_86_64_32S policy * port: pplist mapping to x86_64 * refactor: rename all explicity comparision with VMS_SELF with an inline of active_vmnt() * refactor: encapsulate all explicity checking of ptep for unpacking into vmnt_packed() * fix: vmscpy, vmsfree and kmem_init assumption on vm map structure * fix: linking issue with 64bit addressing * previous: satisfy R_86_64_32S relocation by adjusting the kernel base address * fixup other issue due to previous refactoring * enable of x86_64 on usr/ * lunalibc: port: x86_64 support * lunalibc: fix: cut down the unnecessary register savings when invoking syscall. * lunalibc: refactor: better syscall invocation method * lunabuild: refactor: rename set() to set_value() to avoid confusion with set declaration * lunabuild: fix: cascade updating case stack overflow when triggered by itself through set_value() * makefile: fix: only triggered re-configuration shell when config save is deleted or explicit required. * makefile: feat: add a env variable ARCH= on make, to allow specifiy the targeted ISA without going through all the trouble of configuration shell * build: fix: use mcmode=kernel to allow linking with kernel base relocated to -2GiB while remove the need of the bloat of mcmode=large * make variadic syscall more portable * syscall: fix: va_list now only cross the kernel broader with a reference rather than value, which make the interface portable as some architecture abi require va_list to be a struct. * syscall: ref: (this is a refactor) remove the need of variadic syscall usage on sys_mmap and syslog. As they are point-less * fix: issues during the bootstrap stage * arch/boot: add missing mode switching from x86_64 compatibility mode to full 64-bits (long mode) * kpt_remap: rework the kernel high-mem remapping for x86_64. isolate the remap logic of x86_64 and i386 * gdt: when loading gdt, the descriptor must follow the i386's format (all field are required), as processor will perform all the checks upon loading * idt: remove the ist thing, we should reserve it for the "ABORT" interrupts to use. * ctx switch: fix issue of a register being left in stack * vm: add sign extend on virtual address to enforce consistency adjust the _PTE_X and introduce _PTE_NX minor adjustment on vm mapping for easy setup * kprintf: fix the 64-bit integer not being correctly displayed in hex. * acpi: fix the vague use of generic pointer type as acpi require all pointer type must be int32 * variadic: wrap the va_list unpacking method into arch-specific * makefile: invoke correct QEMU depend on build architecture * lunabuild: disable the gcc's SSE optimization when LConfig does enable this. * elf64: typo fix, should check for CLASS64 flag set, rather than CLASS32 * pmm: pplist mapping granularity fix. * reactor: some refactorings, clarify things * fix issues all the way to user space * interrupt64: incorrect stack address calculation temp saved %rax not being restored * kern/syscall: a confrontation to systemv abi, %rbx is trashed without being saved offset miscalculated, replaced with one defined in interrupt64.S.inc to avoid these magic number! * usr/syscall: there is no way to force param pass through stack under x86_64, roll back to use registers * gdt: it turns out you still need a valid data seg desc for both R0/R3 data selector * tss: fix incorrect offset for tss defined in interrupt64.S.inc * usr: use -mcmodel=large to link all user program, we may shift to PIC in the near future * pagetable: add __paddr to ensure we the calculated address (physical) does not exceed the maximium allowance (that is, 52 bits) * mempart: adjust the memory map to move user stack lower, so we can distinguish it from sign extended kernel address visually add extra term for specifiying max stack size PER THREAD, to avoid confusion. * tlb: add couple of invalidation to ensure freshness * procvm: fix the page table walking on step out single level when the structure has multiple level chained at the last pte. Which result incorrect L(n-1)TEP returned. fix the issue of ptep calculation for establishing self-reference on mounted vms, when we have ptw more than 2 levels. * thread: adjust the guardian pte injection logic, so it will no longer occupying the per-thread stack space * makefile: add qemu trace for tracking the interrupt event ( require my customized qemu version) * misc: refactorings of course. * fix issues in execve and lunalibc due to change of ABI * exec: fix: incorrect assumption on argv and envp, according to the POSIX, envp and argv in execve are mandatory (can not be null). * exec: ref: refactor the parameter injection code, so to be more uniform and readable. we also remove the auto injection of argv[0], and thus it is programmer's responsibility to ensure that. * libc: fix: x86_64 ABI for signal trampoline and crt*.S * i386: fix: i386 failed due to previous refactoring. The kernel stack page count must be napot. * an elegant way of configuring and creating QEMU instance * feat: rework the way to config and create QEMU instance, abstracting all the qemu specifications into a manifest file and thus more clear and less error-prone * feat: add ability of lazy evaluation of lunaconfig node, thus rendering the loading order insignificant * ref: separate the qemu launching task from the makefile. * ref: clean up and general house-keeping * always clear the LCR.DLAB bit before configuring * when two 16550 devices on different bus (isa and pci this case) the LCR.DLAB bit is somehow being set, causing subsequent write to register become undefined. It is unclear why qemu left this in such undefined state. * add a qemu-dir to qemu.py to allow override the qemu used * update readme * change the th_create syscall interface to be more flexible * th_create syscall need to be change in order to provide better integration with user space where trampoline must be used. * increase the limit of maximium syscall number * re-implement the pthread_create in lunalibc * fix issue in the threading interfacing * fix: thread handler calling in trampoline * fix: mismatch parameter count to the printf fmt in test_pthread, which causing segfault * fix: debug/trace does not print the $pc when a symbol is fail to locate * ref: refactor the /sys/version mapping to avoid doing formatting as they are all compile time constant * ref: remove the x86_recv_interrupt_all as it is too noisy. * ref: remove redundant cpu feature from the QEMU specification * update readme --- README.md | 157 ++--- lunaix-os/.gitignore | 2 + lunaix-os/.vscode/c_cpp_properties.json | 25 +- lunaix-os/LConfig | 2 +- lunaix-os/arch/LBuild | 3 +- lunaix-os/arch/LConfig | 23 +- lunaix-os/arch/README.md | 6 +- lunaix-os/arch/generic/includes/sys/hart.h | 3 - .../arch/generic/includes/sys/mm/mempart.h | 5 - .../arch/generic/includes/sys/mm/mm_defs.h | 2 +- lunaix-os/arch/i386/LBuild | 52 -- lunaix-os/arch/i386/LConfig | 23 - lunaix-os/arch/i386/exceptions/i386_isrdef.c | 537 ------------------ lunaix-os/arch/i386/includes/sys/abi.h | 81 --- .../arch/i386/includes/sys/boot/bstage.h | 8 - lunaix-os/arch/i386/includes/sys/i386_intr.h | 10 - lunaix-os/arch/i386/includes/sys/mm/mempart.h | 60 -- lunaix-os/arch/i386/includes/sys/x86_isa.h | 54 -- lunaix-os/arch/i386/klib/fast_str.c | 26 - lunaix-os/arch/i386/trace.c | 49 -- lunaix-os/arch/x86/LBuild | 82 +++ lunaix-os/arch/x86/LConfig | 34 ++ lunaix-os/arch/{i386 => x86}/arch.c | 15 +- lunaix-os/arch/x86/boot/boot_helper.c | 46 ++ .../boot/boot.S => x86/boot/i386/boot32.S} | 13 +- .../{i386/boot => x86/boot/i386}/init32.c | 6 +- .../kpt_setup.c => x86/boot/i386/kremap32.c} | 63 +- .../prologue.S => x86/boot/i386/prologue32.S} | 9 +- lunaix-os/arch/x86/boot/kpt_setup.c | 14 + lunaix-os/arch/{i386 => x86}/boot/mb_parser.c | 15 +- lunaix-os/arch/x86/boot/x86_64/boot64.S | 133 +++++ lunaix-os/arch/x86/boot/x86_64/init64.c | 17 + lunaix-os/arch/x86/boot/x86_64/kremap64.c | 188 ++++++ lunaix-os/arch/x86/boot/x86_64/prologue64.S | 73 +++ .../exceptions/interrupt32.S} | 10 +- lunaix-os/arch/x86/exceptions/interrupt64.S | 204 +++++++ .../{i386 => x86}/exceptions/interrupts.c | 12 +- .../{i386 => x86}/exceptions/intr_routines.c | 6 +- .../arch/{i386 => x86}/exceptions/intrhnds.S | 18 +- lunaix-os/arch/x86/exceptions/isrdef.c | 67 +++ .../i386_isrm.c => x86/exceptions/isrm.c} | 0 lunaix-os/arch/x86/exec/elf32.c | 13 + lunaix-os/arch/x86/exec/elf64.c | 14 + lunaix-os/arch/x86/exec/exec.c | 23 + lunaix-os/arch/{i386 => x86}/failsafe.S | 0 lunaix-os/arch/{i386 => x86}/gdbstub.c | 12 +- lunaix-os/arch/{i386 => x86}/hal/LBuild | 0 lunaix-os/arch/{i386 => x86}/hal/apic.c | 0 lunaix-os/arch/{i386 => x86}/hal/apic_timer.c | 0 lunaix-os/arch/{i386 => x86}/hal/apic_timer.h | 0 lunaix-os/arch/{i386 => x86}/hal/cpu.c | 0 lunaix-os/arch/{i386 => x86}/hal/ioapic.c | 0 lunaix-os/arch/{i386 => x86}/hal/mc146818a.c | 0 lunaix-os/arch/{i386 => x86}/hal/pic.h | 0 lunaix-os/arch/{i386 => x86}/hal/ps2kbd.c | 0 lunaix-os/arch/{i386 => x86}/hal/rngx86.c | 25 +- lunaix-os/arch/x86/hart.c | 22 + lunaix-os/arch/{i386/hart.c => x86/hart32.c} | 23 +- lunaix-os/arch/x86/hart64.c | 44 ++ .../x86/includes/linking/base_defs.ld.inc | 18 + .../arch/x86/includes/linking/boot_secs.ldx | 29 + lunaix-os/arch/x86/includes/sys/abi.h | 33 ++ lunaix-os/arch/x86/includes/sys/abi32.h | 41 ++ lunaix-os/arch/x86/includes/sys/abi64.h | 40 ++ .../arch/{i386 => x86}/includes/sys/apic.h | 0 .../includes/sys}/boot/archinit.h | 4 +- lunaix-os/arch/x86/includes/sys/boot/bstage.h | 37 ++ .../includes/sys/boot/mb.h} | 10 +- lunaix-os/arch/x86/includes/sys/boot/mb2.h | 414 ++++++++++++++ .../x86/includes/sys/boot/multiboot.S.inc | 39 ++ .../arch/x86/includes/sys/boot/multiboot.h | 14 + .../arch/{i386 => x86}/includes/sys/cpu.h | 44 +- .../arch/{i386 => x86}/includes/sys/crx.h | 24 + lunaix-os/arch/x86/includes/sys/exebi/elf.h | 69 +++ .../{i386 => x86}/includes/sys/failsafe.h | 18 +- .../arch/{i386 => x86}/includes/sys/gdbstub.h | 0 .../arch/{i386 => x86}/includes/sys/hart.h | 119 +++- lunaix-os/arch/x86/includes/sys/int_handler.h | 10 + .../includes/sys/interrupt32.S.inc} | 0 .../arch/x86/includes/sys/interrupt64.S.inc | 107 ++++ .../arch/{i386 => x86}/includes/sys/ioapic.h | 0 .../{i386 => x86}/includes/sys/mm/memory.h | 4 +- lunaix-os/arch/x86/includes/sys/mm/mempart.h | 10 + .../arch/x86/includes/sys/mm/mempart32.h | 67 +++ .../arch/x86/includes/sys/mm/mempart64.h | 71 +++ .../{i386 => x86}/includes/sys/mm/mm_defs.h | 26 +- .../{i386 => x86}/includes/sys/mm/pagetable.h | 69 +-- .../{i386 => x86}/includes/sys/mm/physical.h | 2 +- lunaix-os/arch/x86/includes/sys/mm/pt_def32.h | 64 +++ lunaix-os/arch/x86/includes/sys/mm/pt_def64.h | 71 +++ .../arch/{i386 => x86}/includes/sys/mm/tlb.h | 0 .../{i386 => x86}/includes/sys/muldiv64.h | 8 + .../arch/{i386 => x86}/includes/sys/pci_hba.h | 0 .../arch/{i386 => x86}/includes/sys/port_io.h | 0 .../arch/x86/includes/sys/syscall_utils.h | 17 + .../arch/{i386 => x86}/includes/sys/trace.h | 0 .../arch/{i386 => x86}/includes/sys/vectors.h | 0 lunaix-os/arch/x86/includes/sys/x86_isa.h | 96 ++++ lunaix-os/arch/{i386 => x86}/klib/fast_crc.c | 0 lunaix-os/arch/x86/klib/fast_str.c | 56 ++ lunaix-os/arch/{i386 => x86}/mm/fault.c | 2 +- lunaix-os/arch/{i386 => x86}/mm/gdt.c | 89 ++- lunaix-os/arch/{i386 => x86}/mm/pmm.c | 28 +- lunaix-os/arch/{i386 => x86}/mm/tlb.c | 0 lunaix-os/arch/{i386 => x86}/mm/vmutils.c | 11 + .../arch/{i386/syscall.S => x86/syscall32.S} | 52 +- lunaix-os/arch/x86/syscall64.S | 124 ++++ lunaix-os/arch/x86/trace.c | 102 ++++ lunaix-os/hal/acpi/acpi.c | 7 +- lunaix-os/hal/acpi/parser/madt_parser.c | 8 +- lunaix-os/hal/acpi/parser/mcfg_parser.c | 5 +- lunaix-os/hal/char/serial.c | 6 +- lunaix-os/hal/char/uart/16550.h | 6 +- lunaix-os/hal/char/uart/16550_base.c | 8 +- lunaix-os/includes/hal/acpi/fadt.h | 1 + lunaix-os/includes/hal/acpi/madt.h | 9 +- lunaix-os/includes/hal/acpi/sdt.h | 3 +- lunaix-os/includes/klibc/ia_utils.h | 2 +- lunaix-os/includes/lunaix/blkpart_gpt.h | 4 +- lunaix-os/includes/lunaix/boot_generic.h | 5 +- lunaix-os/includes/lunaix/compiler.h | 5 +- lunaix-os/includes/lunaix/exebi/elf.h | 106 ++++ lunaix-os/includes/lunaix/exebi/elf32.h | 130 ----- lunaix-os/includes/lunaix/exec.h | 35 +- lunaix-os/includes/lunaix/fs/iso9660.h | 36 +- lunaix-os/includes/lunaix/fs/twimap.h | 4 +- lunaix-os/includes/lunaix/mm/mm.h | 2 +- lunaix-os/includes/lunaix/mm/mmap.h | 1 + lunaix-os/includes/lunaix/mm/pagetable.h | 101 +++- lunaix-os/includes/lunaix/process.h | 2 +- lunaix-os/includes/lunaix/signal.h | 1 + lunaix-os/includes/lunaix/syscall_utils.h | 6 +- lunaix-os/includes/lunaix/types.h | 13 +- lunaix-os/includes/usr/lunaix/mann_flags.h | 10 + lunaix-os/includes/usr/lunaix/syscallid.h | 2 +- lunaix-os/includes/usr/lunaix/threads.h | 6 +- lunaix-os/kernel.mk | 36 +- lunaix-os/kernel/boot_helper.c | 21 +- lunaix-os/kernel/debug/trace.c | 10 +- lunaix-os/kernel/device/device.c | 6 +- lunaix-os/kernel/device/poll.c | 6 +- lunaix-os/kernel/exe/LBuild | 2 +- lunaix-os/kernel/exe/elf-generic/LBuild | 4 + .../elf32bfmt.c => elf-generic/elfbfmt.c} | 80 ++- .../{elf32/ldelf32.c => elf-generic/ldelf.c} | 41 +- lunaix-os/kernel/exe/elf32/LBuild | 4 - lunaix-os/kernel/exe/exec.c | 272 +++++---- lunaix-os/kernel/fs/fs_export.c | 8 +- lunaix-os/kernel/fs/iso9660/file.c | 4 +- lunaix-os/kernel/fs/twifs/twifs.c | 6 +- lunaix-os/kernel/fs/twimap.c | 6 +- lunaix-os/kernel/fs/vfs.c | 2 +- lunaix-os/kernel/kinit.c | 10 +- lunaix-os/kernel/kprint/kprintf.c | 22 +- lunaix-os/kernel/lunad.c | 4 +- lunaix-os/kernel/mm/dmm.c | 2 +- lunaix-os/kernel/mm/fault.c | 41 +- lunaix-os/kernel/mm/mmap.c | 40 +- lunaix-os/kernel/mm/procvm.c | 64 ++- lunaix-os/kernel/mm/region.c | 2 +- lunaix-os/kernel/process/process.c | 2 +- lunaix-os/kernel/process/thread.c | 46 +- lunaix-os/libs/klibc/itoa.c | 10 +- lunaix-os/link/base.ldx | 7 + lunaix-os/link/kernel.ldx | 31 + lunaix-os/link/lga.ldx | 101 ++++ lunaix-os/link/linker.ld | 203 ------- lunaix-os/link/lunaix.ldx | 51 ++ lunaix-os/live_debug.sh | 17 + lunaix-os/makefile | 75 +-- lunaix-os/makeinc/lunabuild.mkinc | 28 + lunaix-os/makeinc/os.mkinc | 5 - lunaix-os/makeinc/qemu.mkinc | 18 - lunaix-os/makeinc/toolchain.mkinc | 3 +- .../scripts/build-tools/lbuild/contract.py | 44 +- .../scripts/build-tools/lcfg/builtins.py | 7 +- lunaix-os/scripts/build-tools/lcfg/common.py | 13 +- lunaix-os/scripts/build-tools/lcfg/lcnodes.py | 7 + lunaix-os/scripts/build-tools/luna_build.py | 32 +- lunaix-os/scripts/gen_ksymtable.sh | 19 +- lunaix-os/scripts/grub/GRUB_TEMPLATE | 2 +- lunaix-os/scripts/qemu.py | 277 +++++++++ lunaix-os/scripts/qemus/qemu_x86_dev.json | 58 ++ lunaix-os/usr/.gitignore | 4 +- lunaix-os/usr/LBuild | 38 ++ lunaix-os/usr/LConfig | 11 + lunaix-os/usr/execs.list | 6 - lunaix-os/usr/init/init.c | 7 +- lunaix-os/usr/libc/LBuild | 28 + lunaix-os/usr/libc/arch/i386/LBuild | 8 + lunaix-os/usr/libc/arch/i386/crt0.S | 10 +- lunaix-os/usr/libc/arch/i386/dirent.c | 4 - lunaix-os/usr/libc/arch/i386/errno.c | 4 - lunaix-os/usr/libc/arch/i386/fcntl.c | 6 - lunaix-os/usr/libc/arch/i386/ioctl.c | 4 - lunaix-os/usr/libc/arch/i386/lunaix.c | 12 - lunaix-os/usr/libc/arch/i386/mann.c | 12 - lunaix-os/usr/libc/arch/i386/mount.c | 14 - lunaix-os/usr/libc/arch/i386/syscall.S | 23 +- lunaix-os/usr/libc/arch/i386/syscall.h | 69 --- lunaix-os/usr/libc/arch/i386/trampoline.S | 12 + lunaix-os/usr/libc/arch/i386/unistd.c | 124 ---- lunaix-os/usr/libc/arch/x86_64/LBuild | 8 + lunaix-os/usr/libc/arch/x86_64/crt0.S | 27 + lunaix-os/usr/libc/arch/x86_64/syscall.S | 43 ++ lunaix-os/usr/libc/arch/x86_64/trampoline.S | 36 ++ lunaix-os/usr/libc/includes/lunaix/mann.h | 4 +- lunaix-os/usr/libc/includes/lunaix/syscall.h | 2 +- lunaix-os/usr/libc/includes/stdio.h | 10 +- lunaix-os/usr/libc/makefile | 11 +- lunaix-os/usr/libc/src/_vprintf.c | 17 + lunaix-os/usr/libc/src/posix/dirent.c | 8 + lunaix-os/usr/libc/src/posix/errno.c | 8 + lunaix-os/usr/libc/src/posix/fcntl.c | 14 + lunaix-os/usr/libc/src/posix/ioctl.c | 15 + lunaix-os/usr/libc/src/posix/lunaix.c | 40 ++ lunaix-os/usr/libc/src/posix/mann.c | 24 + lunaix-os/usr/libc/src/posix/mount.c | 14 + .../libc/{arch/i386 => src/posix}/signal.c | 46 +- lunaix-os/usr/libc/src/posix/unistd.c | 211 +++++++ lunaix-os/usr/libc/src/pthread.c | 30 +- lunaix-os/usr/makefile | 54 +- lunaix-os/usr/sh/sh.c | 33 +- lunaix-os/usr/test_pthread.c | 17 +- lunaix-os/usr/{link-usr.ld => uexec.ldx} | 8 +- 225 files changed, 5244 insertions(+), 2473 deletions(-) delete mode 100644 lunaix-os/arch/i386/LBuild delete mode 100644 lunaix-os/arch/i386/LConfig delete mode 100644 lunaix-os/arch/i386/exceptions/i386_isrdef.c delete mode 100644 lunaix-os/arch/i386/includes/sys/abi.h delete mode 100644 lunaix-os/arch/i386/includes/sys/boot/bstage.h delete mode 100644 lunaix-os/arch/i386/includes/sys/i386_intr.h delete mode 100644 lunaix-os/arch/i386/includes/sys/mm/mempart.h delete mode 100644 lunaix-os/arch/i386/includes/sys/x86_isa.h delete mode 100644 lunaix-os/arch/i386/klib/fast_str.c delete mode 100644 lunaix-os/arch/i386/trace.c create mode 100644 lunaix-os/arch/x86/LBuild create mode 100644 lunaix-os/arch/x86/LConfig rename lunaix-os/arch/{i386 => x86}/arch.c (69%) create mode 100644 lunaix-os/arch/x86/boot/boot_helper.c rename lunaix-os/arch/{i386/boot/boot.S => x86/boot/i386/boot32.S} (74%) rename lunaix-os/arch/{i386/boot => x86/boot/i386}/init32.c (78%) rename lunaix-os/arch/{i386/boot/kpt_setup.c => x86/boot/i386/kremap32.c} (67%) rename lunaix-os/arch/{i386/boot/prologue.S => x86/boot/i386/prologue32.S} (82%) create mode 100644 lunaix-os/arch/x86/boot/kpt_setup.c rename lunaix-os/arch/{i386 => x86}/boot/mb_parser.c (89%) create mode 100644 lunaix-os/arch/x86/boot/x86_64/boot64.S create mode 100644 lunaix-os/arch/x86/boot/x86_64/init64.c create mode 100644 lunaix-os/arch/x86/boot/x86_64/kremap64.c create mode 100644 lunaix-os/arch/x86/boot/x86_64/prologue64.S rename lunaix-os/arch/{i386/exceptions/interrupt.S => x86/exceptions/interrupt32.S} (97%) create mode 100644 lunaix-os/arch/x86/exceptions/interrupt64.S rename lunaix-os/arch/{i386 => x86}/exceptions/interrupts.c (82%) rename lunaix-os/arch/{i386 => x86}/exceptions/intr_routines.c (93%) rename lunaix-os/arch/{i386 => x86}/exceptions/intrhnds.S (96%) create mode 100644 lunaix-os/arch/x86/exceptions/isrdef.c rename lunaix-os/arch/{i386/exceptions/i386_isrm.c => x86/exceptions/isrm.c} (100%) create mode 100644 lunaix-os/arch/x86/exec/elf32.c create mode 100644 lunaix-os/arch/x86/exec/elf64.c create mode 100644 lunaix-os/arch/x86/exec/exec.c rename lunaix-os/arch/{i386 => x86}/failsafe.S (100%) rename lunaix-os/arch/{i386 => x86}/gdbstub.c (92%) rename lunaix-os/arch/{i386 => x86}/hal/LBuild (100%) rename lunaix-os/arch/{i386 => x86}/hal/apic.c (100%) rename lunaix-os/arch/{i386 => x86}/hal/apic_timer.c (100%) rename lunaix-os/arch/{i386 => x86}/hal/apic_timer.h (100%) rename lunaix-os/arch/{i386 => x86}/hal/cpu.c (100%) rename lunaix-os/arch/{i386 => x86}/hal/ioapic.c (100%) rename lunaix-os/arch/{i386 => x86}/hal/mc146818a.c (100%) rename lunaix-os/arch/{i386 => x86}/hal/pic.h (100%) rename lunaix-os/arch/{i386 => x86}/hal/ps2kbd.c (100%) rename lunaix-os/arch/{i386 => x86}/hal/rngx86.c (64%) create mode 100644 lunaix-os/arch/x86/hart.c rename lunaix-os/arch/{i386/hart.c => x86/hart32.c} (79%) create mode 100644 lunaix-os/arch/x86/hart64.c create mode 100644 lunaix-os/arch/x86/includes/linking/base_defs.ld.inc create mode 100644 lunaix-os/arch/x86/includes/linking/boot_secs.ldx create mode 100644 lunaix-os/arch/x86/includes/sys/abi.h create mode 100644 lunaix-os/arch/x86/includes/sys/abi32.h create mode 100644 lunaix-os/arch/x86/includes/sys/abi64.h rename lunaix-os/arch/{i386 => x86}/includes/sys/apic.h (100%) rename lunaix-os/arch/{i386 => x86/includes/sys}/boot/archinit.h (77%) create mode 100644 lunaix-os/arch/x86/includes/sys/boot/bstage.h rename lunaix-os/arch/{i386/includes/sys/boot/multiboot.h => x86/includes/sys/boot/mb.h} (97%) create mode 100644 lunaix-os/arch/x86/includes/sys/boot/mb2.h create mode 100644 lunaix-os/arch/x86/includes/sys/boot/multiboot.S.inc create mode 100644 lunaix-os/arch/x86/includes/sys/boot/multiboot.h rename lunaix-os/arch/{i386 => x86}/includes/sys/cpu.h (77%) rename lunaix-os/arch/{i386 => x86}/includes/sys/crx.h (69%) create mode 100644 lunaix-os/arch/x86/includes/sys/exebi/elf.h rename lunaix-os/arch/{i386 => x86}/includes/sys/failsafe.h (73%) rename lunaix-os/arch/{i386 => x86}/includes/sys/gdbstub.h (100%) rename lunaix-os/arch/{i386 => x86}/includes/sys/hart.h (61%) create mode 100644 lunaix-os/arch/x86/includes/sys/int_handler.h rename lunaix-os/arch/{i386/includes/sys/interrupt.S.inc => x86/includes/sys/interrupt32.S.inc} (100%) create mode 100644 lunaix-os/arch/x86/includes/sys/interrupt64.S.inc rename lunaix-os/arch/{i386 => x86}/includes/sys/ioapic.h (100%) rename lunaix-os/arch/{i386 => x86}/includes/sys/mm/memory.h (87%) create mode 100644 lunaix-os/arch/x86/includes/sys/mm/mempart.h create mode 100644 lunaix-os/arch/x86/includes/sys/mm/mempart32.h create mode 100644 lunaix-os/arch/x86/includes/sys/mm/mempart64.h rename lunaix-os/arch/{i386 => x86}/includes/sys/mm/mm_defs.h (56%) rename lunaix-os/arch/{i386 => x86}/includes/sys/mm/pagetable.h (71%) rename lunaix-os/arch/{i386 => x86}/includes/sys/mm/physical.h (83%) create mode 100644 lunaix-os/arch/x86/includes/sys/mm/pt_def32.h create mode 100644 lunaix-os/arch/x86/includes/sys/mm/pt_def64.h rename lunaix-os/arch/{i386 => x86}/includes/sys/mm/tlb.h (100%) rename lunaix-os/arch/{i386 => x86}/includes/sys/muldiv64.h (91%) rename lunaix-os/arch/{i386 => x86}/includes/sys/pci_hba.h (100%) rename lunaix-os/arch/{i386 => x86}/includes/sys/port_io.h (100%) create mode 100644 lunaix-os/arch/x86/includes/sys/syscall_utils.h rename lunaix-os/arch/{i386 => x86}/includes/sys/trace.h (100%) rename lunaix-os/arch/{i386 => x86}/includes/sys/vectors.h (100%) create mode 100644 lunaix-os/arch/x86/includes/sys/x86_isa.h rename lunaix-os/arch/{i386 => x86}/klib/fast_crc.c (100%) create mode 100644 lunaix-os/arch/x86/klib/fast_str.c rename lunaix-os/arch/{i386 => x86}/mm/fault.c (91%) rename lunaix-os/arch/{i386 => x86}/mm/gdt.c (56%) rename lunaix-os/arch/{i386 => x86}/mm/pmm.c (73%) rename lunaix-os/arch/{i386 => x86}/mm/tlb.c (100%) rename lunaix-os/arch/{i386 => x86}/mm/vmutils.c (72%) rename lunaix-os/arch/{i386/syscall.S => x86/syscall32.S} (72%) create mode 100644 lunaix-os/arch/x86/syscall64.S create mode 100644 lunaix-os/arch/x86/trace.c create mode 100644 lunaix-os/includes/lunaix/exebi/elf.h delete mode 100644 lunaix-os/includes/lunaix/exebi/elf32.h create mode 100644 lunaix-os/kernel/exe/elf-generic/LBuild rename lunaix-os/kernel/exe/{elf32/elf32bfmt.c => elf-generic/elfbfmt.c} (61%) rename lunaix-os/kernel/exe/{elf32/ldelf32.c => elf-generic/ldelf.c} (73%) delete mode 100644 lunaix-os/kernel/exe/elf32/LBuild create mode 100644 lunaix-os/link/base.ldx create mode 100644 lunaix-os/link/kernel.ldx create mode 100644 lunaix-os/link/lga.ldx delete mode 100644 lunaix-os/link/linker.ld create mode 100644 lunaix-os/link/lunaix.ldx create mode 100755 lunaix-os/live_debug.sh create mode 100644 lunaix-os/makeinc/lunabuild.mkinc delete mode 100644 lunaix-os/makeinc/os.mkinc delete mode 100644 lunaix-os/makeinc/qemu.mkinc create mode 100755 lunaix-os/scripts/qemu.py create mode 100644 lunaix-os/scripts/qemus/qemu_x86_dev.json create mode 100644 lunaix-os/usr/LBuild create mode 100644 lunaix-os/usr/LConfig delete mode 100644 lunaix-os/usr/execs.list create mode 100644 lunaix-os/usr/libc/LBuild create mode 100644 lunaix-os/usr/libc/arch/i386/LBuild delete mode 100644 lunaix-os/usr/libc/arch/i386/dirent.c delete mode 100644 lunaix-os/usr/libc/arch/i386/errno.c delete mode 100644 lunaix-os/usr/libc/arch/i386/fcntl.c delete mode 100644 lunaix-os/usr/libc/arch/i386/ioctl.c delete mode 100644 lunaix-os/usr/libc/arch/i386/lunaix.c delete mode 100644 lunaix-os/usr/libc/arch/i386/mann.c delete mode 100644 lunaix-os/usr/libc/arch/i386/mount.c delete mode 100644 lunaix-os/usr/libc/arch/i386/syscall.h delete mode 100644 lunaix-os/usr/libc/arch/i386/unistd.c create mode 100644 lunaix-os/usr/libc/arch/x86_64/LBuild create mode 100644 lunaix-os/usr/libc/arch/x86_64/crt0.S create mode 100644 lunaix-os/usr/libc/arch/x86_64/syscall.S create mode 100644 lunaix-os/usr/libc/arch/x86_64/trampoline.S create mode 100644 lunaix-os/usr/libc/src/posix/dirent.c create mode 100644 lunaix-os/usr/libc/src/posix/errno.c create mode 100644 lunaix-os/usr/libc/src/posix/fcntl.c create mode 100644 lunaix-os/usr/libc/src/posix/ioctl.c create mode 100644 lunaix-os/usr/libc/src/posix/lunaix.c create mode 100644 lunaix-os/usr/libc/src/posix/mann.c create mode 100644 lunaix-os/usr/libc/src/posix/mount.c rename lunaix-os/usr/libc/{arch/i386 => src/posix}/signal.c (58%) create mode 100644 lunaix-os/usr/libc/src/posix/unistd.c rename lunaix-os/usr/{link-usr.ld => uexec.ldx} (62%) diff --git a/README.md b/README.md index 49ec98f..e891078 100644 --- a/README.md +++ b/README.md @@ -12,52 +12,70 @@ LunaixOS - 一个简单的,详细的,POSIX兼容的(但愿!),带有 ## 1. 一些实用资源 -如果有意研读LunaixOS的内核代码和其中的设计,以下资料可能会对此有用。 +如果有意研读LunaixOS的内核代码和其中的设计,或欲开始属于自己的OS开发之道,以下资料可能会对此有用。 + [最新的LunaixOS源代码分析教程](docs/tutorial/0-教程介绍和环境搭建.md) + [内核虚拟内存的详细布局](docs/img/lunaix-os-mem.png) + [LunaixOS启动流程概览](docs/img/boot_sequence.jpeg) + LunaixOS总体架构概览(WIP) ++ [作者修改的QEMU](https://github.com/Minep/qemu) (添加了一些额外用于调试的功能) ## 2. 当前进度以及支持的功能 -该操作系统支持x86架构,运行在保护模式中,采用宏内核架构,目前仅支持单核心。架构与内核的解耦合工作正在进行中。 +Lunaix内核具有支持多种不同的指令集架构的能力,目前支持如下: -在下述列表中,则列出目前所支持的所用功能和特性。列表项按照项目时间戳进行升序排列。 ++ x86_32 ++ x86_64 + +Lunaix全部特性一览: + 使用Multiboot进行引导启动 + + Multiboot 1 + + Multiboot 2 (WIP) + APIC/IOAPIC作为中断管理器和计时器 + ACPI + 虚拟内存 -+ 内存管理与按需分页 -+ 键盘输入 + + 架构中性设计 + + 按需分页 + + Copy-on-Write ++ 内存管理 + 进程模型 -+ 54个常见的Linux/POSIX系统调用([附录1](#appendix1)) -+ 用户模式 ++ 61个常见的Linux/POSIX系统调用([附录1](#appendix1)) ++ 用户/内核态隔离 + 信号机制 + PCI 3.0 + PCIe 1.1 (WIP) -+ Serial ATA AHCI -+ 文件系统 ++ 块设备驱动 + + Serial ATA AHCI + + ATA设备 + + ATAPI封装的SCSI协议 ++ 文件系统(POSIX.1-2008, section 5 & 10) + 虚拟文件系统 + + 内核态文件系统(twifs, Lunaix自己的sysfs) + + 设备文件系统(devfs, Lunaix自己的udev) + + 进程文件系统(procfs) + ISO9660 - + 原生 - + Rock Ridge拓展 + + ECMA-119 + + IEEE P1282(Rock Ridge拓展) + 远程GDB串口调试 (COM1@9600Bd) + 用户程序加载与执行 -+ 动态链接 (WIP) + 通用设备抽象层 -+ 通用图形设备抽象层 - + 标准VGA实现 -+ 虚拟终端设备接口(兼容 POSIX.1-2008) + + 架构中性的设备支持位于:`lunaix-os/hal` + + 16550 UART + + ACPI (不完全实现) + + 架构耦合的设备支持位于:`lunaix-os/arch//hal` + + x86 + + APIC/IOAPIC 组合 + + MC146818 RTC + + i8042 PS/2 + + RNG(使用`rdrand`) ++ 通用图形设备抽象层 (Draft) + + 参考:`lunaix-os/hal/gfxa` ++ 虚拟终端设备接口(POSIX.1-2008, section 11) + + 参考:`lunaix-os/hal/term` + 线程模型 - -已经测试过的环境: - -+ QEMU (>=7.0.0) -+ Bochs(SATA功能不支持) -+ Virtualbox -+ Dell G3 3779 + + 用户线程支持(pthread系列) + + 内核线程支持(抢占式内核设计) ## 3. 目录结构 @@ -69,6 +87,8 @@ LunaixOS - 一个简单的,详细的,POSIX兼容的(但愿!),带有 ## 4. 编译与构建 +**!如果想要立刻构建并运行,请参考4.6!** + 构建该项目需要满足以下条件: + gcc 工具链 @@ -78,7 +98,7 @@ LunaixOS - 一个简单的,详细的,POSIX兼容的(但愿!),带有 ### 4.1 使用 GNU CC 工具链 -正如同大多数OS一样,LunaixOS 是一个混合了 C 和汇编的产物。这就意味着你得要使用一些标准的C编译器来构建Lunaix。在这里,我推荐使用 GNU CC 工具链来进行构建。至于其他的工具链,如llvm,也可以去尝试,但对此我就不能作任何的保证了。 +正如同大多数OS一样,LunaixOS 是一个混合了 C 和汇编的产物。这就意味着你得要使用一些标准的C编译器来构建Lunaix。在这里,我推荐使用 GNU CC 工具链来进行构建。因为Lunaix 在编写时使用了大量的GNU CC 相关编译器属性修饰 (`__attribute__`) 。假若使用其他工具链,如LLVM,我对此就不能做出任何保证了。 如果你使用的是基于 x86 指令集的Linux系统,不论是64位还是32位,**其本机自带的gcc就足以编译Lunaix**。 当然了,如果说你的平台是其他非x86的,你也可以指定使用某个针对x86_32的gcc套件来进行交叉编译——在`make`时通过`CX_PREFIX`变量来指定gcc套件的前缀。如下例所示,我们可以在任意平台上,如risc-v,单独使用一个面向x86_32的gcc来进行交叉编译: @@ -86,89 +106,82 @@ LunaixOS - 一个简单的,详细的,POSIX兼容的(但愿!),带有 make CX_PREFIX=i686-linux-gnu- all ``` -由于目前Lunaix仅支持x86_32微架构, `CX_PREFIX` 指向的gcc必须具有针对x86_32架构进行交叉编译的能力。 - ### 4.2 Docker镜像 对于开发环境,本项目也提供了Docker镜像封装。开箱即用,无需配置,非常适合懒人或惜时者。详细使用方法请转到:[Lunaix OSDK项目](https://github.com/Minep/os-devkit)。 ### 4.3 构建选项 + 假若条件满足,那么可以直接执行`make all`进行构建,完成后可在生成的`build`目录下找到可引导的iso。 本项目支持的make命令: | 命令 | 用途 | | ------------------------ | ----------------------------------------------- | -| `make all` | 构建镜像(`-O2`,但禁用CSE相关的优化项 **※** ) | -| `make instable` | 构建镜像(`-O2`,开启CSE相关优化) | -| `make all-debug` | 构建适合调试用的镜像(`-Og`) | -| `make run` | 使用QEMU运行build目录下的镜像 | -| `make debug-qemu` | 构建并使用QEMU进行调试 | -| `make debug-bochs` | 构建并使用Bochs进行调试 | -| `make debug-qemu-vscode` | 用于vscode整合 | -| `make clean` | 删除build目录 | +| `make all` | 等价于 `make image` | +| `make image` | 构建ISO镜像,可直接启动,使用ISO9660文件系统 | +| `make kernel` | 构建内核ELF镜像,无法直接启动,需要引导程序 | +| `make clean` | 删除构建缓存,用于重新构建 | +| `make config` | 配置Lunaix | -**※:由于在`-O2`模式下,GCC会进行CSE优化,这导致LunaixOS会出现一些非常奇怪、离谱的bug,从而影响到基本运行。具体原因有待调查。** +与make命令配套的环境变量,Lunaix的makefile会自动检测这些环境变量,以更改构建行为 -### 4.4 设置内核启动参数 ++ `MODE={debug|release}` 使用debug模式构建(-Og)或者release模式(-O2) ++ `ARCH=` 为指定的指令集架构编译Lunaix。 所使用的配置选项均为选定架构默认,该环境变量 + 存在的目的就是方便用户进行快速编译,而无需钻研Lunaix的种种配置项。 -在 make 的时候通过`CMDLINE`变量可以设置内核启动参数列表。该列表可以包含多个参数,通过一个或多个空格来分割。每个参数可以为键值对 `=` 或者是开关标志位 ``。目前 Lunaix 支持以下参数: +### 4.4 Lunaix的功能配置 -+ `console=` 设置系统终端的输入输出设备(tty设备)。其中 `` 是设备文件路径 (注意,这里的设备文件路径是针对Lunaix,而非Linux)。关于LunaixOS设备文件系统的介绍可参考 Lunaix Wiki(WIP) +Lunaix是一个可配置的内核,允许用户在编译前选择应当包含或移除的功能。 -如果`CMDLINE`未指定,则将会载入默认参数: +使用`make config`来进行基于命令行的交互配置。呈现方式采用Shell的形式,所有的配置项按照类似于文件树的形式组织,如单个配置项为一个“文件”,多个配置项组成的配置组为一个目录,呈现形式为方括号`[]`包裹起来的项目。在提示符中输入`usage`并回车可以查看具体的使用方法。 + +一个最常用的配置可能就是`architecture_support/arch`了,也就是配置Lunaix所面向的指令集。比如,编译一个在x86_64平台上运行的Lunaix,在提示符中输入(**注意等号两侧的空格,这是不能省略的**): ``` -console=/dev/ttyFB0 +/architecture_support/arch = x86_64 ``` -其中,`/dev/ttyFB0` 指向基于VGA文本模式的tty设备,也就是平时启动QEMU时看到的黑色窗口。 - -当然,读者也可以使用 `/dev/ttyS0` 来作为默认tty设备,来验证 Lunaix 的灵活性与兼容性。该路径指向第一个串口设备。可以通过telnet协议在`12345`端口上进行访问——端口号可以自行修改QEMU启动参数(位于:`makeinc/qemu.mkinc`)来变更。 - -**注意:** 根据操作系统和键盘布局的不同,telnet客户端对一些关键键位的映射(如退格,回车)可能有所差别(如某些版本的Linux会将退格键映射为`0x7f`,也就是ASCII的``字符,而非我们熟知`0x08`)。如果读者想要通过串口方式把玩Lunaix,请修改`usr/init/init.c`里面的终端初始化代码,将`VERASE`设置为正确的映射(修改方式可以参考 POSIX termios 的使用方式。由于Lunaix的终端接口的实现是完全兼容POSIX的,读者可以直接去查阅Linux自带的帮助`man termios`,无需作任何的转换) - -## 5. 运行,分支以及 Issue +之后输入`exit`保存并推出。而后正常编译。 -### 5.1 虚拟磁盘(非必须) -你可以绑定一个虚拟磁盘镜像,可以使用如下命令快速创建一个: +### 4.5 设置内核启动参数 -```bash -qemu-img create -f vdi machine/disk0.vdi 128M -``` +在 make 的时候通过`CMDLINE`变量可以设置内核启动参数列表。该列表可以包含多个参数,通过一个或多个空格来分割。每个参数可以为键值对 `=` 或者是开关标志位 ``。目前 Lunaix 支持以下参数: -如果你想要使用别的磁盘镜像,需要修改`configs/make-debug-tool` ++ `console=` 设置系统终端的输入输出设备(tty设备)。其中 `` 是设备文件路径 (注意,这里的设备文件路径是针对Lunaix,而非Linux)。关于LunaixOS设备文件系统的介绍可参考 Lunaix Wiki(WIP) -找到这一行: +如果`CMDLINE`未指定,则将会载入默认参数: ``` --drive id=disk,file="machine/disk0.vdi",if=none \ +console=/dev/ttyFB0 ``` -然后把`machine/disk0.vdi`替换成你的磁盘路径。 +其中,`/dev/ttyFB0` 指向基于VGA文本模式的tty设备,也就是平时启动QEMU时看到的黑色窗口。 -有很多办法去创建一个虚拟磁盘,比如[qemu-img](https://qemu-project.gitlab.io/qemu/system/images.html)。 +当然,读者也可以使用 `/dev/ttyS0` 来作为默认tty设备,来验证 Lunaix 的灵活性与兼容性。该路径指向第一个串口设备。可以通过telnet协议在`12345`端口上进行访问——端口号可以自行修改QEMU启动参数(位于:`makeinc/qemu.mkinc`)来变更。 -### 5.2 代码稳定性 +**注意:** 根据操作系统和键盘布局的不同,telnet客户端对一些关键键位的映射(如退格,回车)可能有所差别(如某些版本的Linux会将退格键映射为`0x7f`,也就是ASCII的``字符,而非我们熟知`0x08`)。如果读者想要通过串口方式把玩Lunaix,请修改`usr/init/init.c`里面的终端初始化代码,将`VERASE`设置为正确的映射(修改方式可以参考 POSIX termios 的使用方式。由于Lunaix的终端接口的实现是完全兼容POSIX的,读者可以直接去查阅Linux自带的帮助`man termios`,无需作任何的转换) -主分支一般是稳定的。因为在大多数情况下,我都会尽量保证本机运行无误后,push到该分支中。至于其他的分支,则是作为标记或者是开发中的功能。前者标记用分支一般会很快删掉;后者开发分支不能保证稳定性,这些分支的代码有可能没有经过测试,但可以作为Lunaix当前开发进度的参考。 +### 4.6 测试与体验 Lunaix -该系统是经过虚拟机和真机测试。如果发现在使用`make all`之后,虚拟机中运行报错,则一般是编译器优化问题。这个问题笔者一般很快就会修复,如果你使用别的版本的gcc(笔者版本11.2),出现了此问题,欢迎提issue。请参考[附录3:Issue的提交](#appendix3) +用户可以使用脚本`live_debug.sh` 来快速运行Lunaix。 该脚本自动按照默认的选项构建Lunaix,而后调用 `scripts/qemu.py` 根据配置文件生成QEMU启动参数 +(配置文件位于`scripts/qemus/`) -下面列出一些可能会出现的问题。 +由于该脚本的主要用途是方便作者进行调试,所以在QEMU窗口打开后还需要进行以下动作: -#### 问题#1: QEMU下8042控制器提示找不到 +1. 使用telnet连接到`localhost:12345`,这里是Lunaix进行标准输入输出所使用的UART映射(QEMU为guest提供UART实现,并将其利用telnet协议重定向到宿主机) +2. 在GDB窗口中输入`c`然后回车,此时Lunaix开始运行。这样做的目的是允许在QEMU进行模拟前,事先打好感兴趣的断点。 -这是QEMU配置ACPI时的一个bug,在7.0.0版中修复了。 +该脚本的运行需要设置 `ARCH=` 环境变量,其值需要与编译时制定的值一致。 -#### 问题#2:多进程运行时,偶尔会出现General Protection错误 +## 5. 运行,分支以及 Issue -这很大概率是出现了竞态条件。虽然是相当不可能的。但如果出现了,还是请提issue。 +### 5.1 代码稳定性 -#### 问题#3:Bochs无法运行,提示找不到AHCI控制器 +主分支一般是稳定的。因为在大多数情况下,我都会尽量保证本机运行无误后,push到该分支中。至于其他的分支,则是作为标记或者是开发中的功能。前者标记用分支一般会很快删掉;后者开发分支不能保证稳定性,这些分支的代码有可能没有经过测试,但可以作为Lunaix当前开发进度的参考。 -正常,**因为Bochs不支持SATA**。请使用QEMU或VirtualBox。 +该系统是经过虚拟机和真机测试。如果发现在使用`make all`之后,虚拟机中运行报错,则一般是编译器优化问题。这个问题笔者一般很快就会修复,如果你使用别的版本的gcc(笔者版本11.2),出现了此问题,欢迎提issue。请参考[附录3:Issue的提交](#appendix3) ## 6. 调试 Lunaix 内核 @@ -189,7 +202,15 @@ qemu-img create -f vdi machine/disk0.vdi 128M ## 7. 参考教程 -**没有!!** 本教程以及该操作系统均为原创,没有基于任何市面上现行的操作系统开发教程,且并非是基于任何的开源内核的二次开发。 +#### 没有!! + +本教程以及该操作系统的所有的架构设计与实现**均为原创**。 + +对此,作者可以保证,该项目是做到了三个 “没有”: + ++ **没有** 参考任何现行的,关于操作系统开发的,教程或书籍。 ++ **没有** 参考任何开源内核的源代码(包括Linux) ++ **没有** 基于任何开源内核的二次开发行为。 为了制作LunaixOS,作者耗费大量时间和精力钻研技术文档,手册,理论书籍以及现行工业标准,从而尽量保证了知识的一手性。(这样一来,读者和听众们也算是拿到了二手的知识,而不是三手,四手,甚至n手的知识)。 @@ -227,7 +248,7 @@ qemu-img create -f vdi machine/disk0.vdi 128M #### 网站 -+ [OSDev](https://wiki.osdev.org/Main_Page) - 杂七杂八的参考,很多过来人的经验。作者主要用于上古资料查询以及收集;技术文献,手册,标准的粗略总结;以及开发环境/工具链的搭建。 ++ [OSDev](https://wiki.osdev.org/Main_Page) - 杂七杂八的参考,很多过来人的经验。作者主要用于上古资料查询以及收集;技术文献,手册,标准的粗略总结;以及开发环境/工具链的搭建。当然,上面的内容假设了x86_32架构的生态,对于其他的ISA支持,该网站便失去了其价值了。 + [FreeVGA](http://www.osdever.net/FreeVGA/home.htm) - 98年的资源!关于VGA编程技术的宝藏网站。 + GNU CC 和 GNU LD 的官方文档。 + [PCI Lookup](https://www.pcilookup.com/) - PCI设备编号查询 diff --git a/lunaix-os/.gitignore b/lunaix-os/.gitignore index eb55d3d..a8dbb20 100644 --- a/lunaix-os/.gitignore +++ b/lunaix-os/.gitignore @@ -14,6 +14,8 @@ __pycache__/ .builder/ .config.json +link/lunaix.ld + .gdb_history **.o diff --git a/lunaix-os/.vscode/c_cpp_properties.json b/lunaix-os/.vscode/c_cpp_properties.json index a0c612f..b315a23 100644 --- a/lunaix-os/.vscode/c_cpp_properties.json +++ b/lunaix-os/.vscode/c_cpp_properties.json @@ -6,16 +6,33 @@ "${workspaceFolder}/includes", "${workspaceFolder}/includes/usr", "${workspaceFolder}/usr/includes", - "${workspaceFolder}/arch/i386/includes", + "${workspaceFolder}/arch/x86/includes", ], "compilerArgs": [ "-ffreestanding", - "-D__ARCH__=i386", - "-D__LUNAIXOS_DEBUG__", + "-m32", "-include .builder/configs.h" ], "defines": [], - "compilerPath": "${HOME}/opt/i686-gcc-12/bin/i686-elf-gcc", + "compilerPath": "/usr/bin/gcc", + "cStandard": "gnu99", + "intelliSenseMode": "gcc-x86" + }, + { + "name": "OS-DEV64", + "includePath": [ + "${workspaceFolder}/includes", + "${workspaceFolder}/includes/usr", + "${workspaceFolder}/usr/includes", + "${workspaceFolder}/arch/x86/includes", + ], + "compilerArgs": [ + "-ffreestanding", + "-m64", + "-include .builder/configs.h" + ], + "defines": [], + "compilerPath": "/usr/bin/gcc", "cStandard": "gnu99", "intelliSenseMode": "gcc-x86" } diff --git a/lunaix-os/LConfig b/lunaix-os/LConfig index 3d0a179..ecd4a03 100644 --- a/lunaix-os/LConfig +++ b/lunaix-os/LConfig @@ -13,7 +13,7 @@ def lunaix_ver(): type(str) seq_num = int(time.time() / 3600) - default("dev-2024_%d"%(seq_num)) + default("%s dev-2024_%d"%(v(arch), seq_num)) @Collection def debug_and_testing(): diff --git a/lunaix-os/arch/LBuild b/lunaix-os/arch/LBuild index 8a4af8b..8617597 100644 --- a/lunaix-os/arch/LBuild +++ b/lunaix-os/arch/LBuild @@ -1,6 +1,7 @@ use({ config("arch"): { - "i386": "i386", + "i386": "x86", + "x86_64": "x86", "aarch64": "arm", "rv64": "riscv" } diff --git a/lunaix-os/arch/LConfig b/lunaix-os/arch/LConfig index 30c67b6..22f96c0 100644 --- a/lunaix-os/arch/LConfig +++ b/lunaix-os/arch/LConfig @@ -1,4 +1,4 @@ -include("i386/LConfig") +include("x86/LConfig") @Collection def architecture_support(): @@ -11,3 +11,24 @@ def architecture_support(): """ Config ISA support """ type(["i386", "x86_64", "aarch64", "rv64"]) default("i386") + + env_val = env("ARCH") + if env_val is not None: + set_value(env_val) + + @Term + @ReadOnly + def arch_bits(): + type(["64", "32"]) + match v(arch): + case "i386": + default("32") + case "aarch64": + default("64") + case "rv64": + default("64") + case "x86_64": + default("64") + case _: + default("32") + \ No newline at end of file diff --git a/lunaix-os/arch/README.md b/lunaix-os/arch/README.md index 0a2ead5..df5349f 100644 --- a/lunaix-os/arch/README.md +++ b/lunaix-os/arch/README.md @@ -19,13 +19,13 @@ Lunaix provide bunch of headers that **MUST** be implemented. + Add implementation to function signature defined in header files under `includes/lunaix/generic` -+ Add implementation of syscall dispatching (Reference: `arhc/i386/syscall.S`) ++ Add implementation of syscall dispatching (Reference: `arhc/x86/syscall.S`) + Add implementation of interrupt handler dispatching (Reference: - `arhc/i386/exceptions/intrhnds.S`) + `arhc/x86/exceptions/intrhnds.S`) + Add implementation of context switching, signal handling. (Reference: - `arhc/i386/exceptions/interrupt.S`) + `arhc/x86/exceptions/interrupt.S`) **TODO: make this procedure more standalone** ## Preparing the Flows diff --git a/lunaix-os/arch/generic/includes/sys/hart.h b/lunaix-os/arch/generic/includes/sys/hart.h index 340a0ee..e820608 100644 --- a/lunaix-os/arch/generic/includes/sys/hart.h +++ b/lunaix-os/arch/generic/includes/sys/hart.h @@ -22,9 +22,6 @@ struct exec_param struct hart_state* parent_state; } compact; -void -hart_flow_redirect(struct hart_state* state, ptr_t pc, ptr_t sp); - ptr_t hart_pc(struct hart_state* state); diff --git a/lunaix-os/arch/generic/includes/sys/mm/mempart.h b/lunaix-os/arch/generic/includes/sys/mm/mempart.h index 28d7ba6..055da0c 100644 --- a/lunaix-os/arch/generic/includes/sys/mm/mempart.h +++ b/lunaix-os/arch/generic/includes/sys/mm/mempart.h @@ -1,11 +1,6 @@ #ifndef __LUNAIX_ARCH_MEMPART_H #define __LUNAIX_ARCH_MEMPART_H -#define MEM_PAGE 0x1000UL -#define MEM_1M 0x100000UL -#define MEM_4M 0x400000UL -#define MEM_HUGE 0x400000UL -#define MEM_1G 0x40000000UL #define END_POINT(name) (name + name##_SIZE - 1) diff --git a/lunaix-os/arch/generic/includes/sys/mm/mm_defs.h b/lunaix-os/arch/generic/includes/sys/mm/mm_defs.h index 79ce14c..6370963 100644 --- a/lunaix-os/arch/generic/includes/sys/mm/mm_defs.h +++ b/lunaix-os/arch/generic/includes/sys/mm/mm_defs.h @@ -6,7 +6,7 @@ #include "pagetable.h" #define KSTACK_PAGES 3 -#define KSTACK_SIZE (KSTACK_PAGES * MEM_PAGE) +#define KSTACK_SIZE (KSTACK_PAGES * PAGE_SIZE) /* Regardless architecture we need to draw the line very carefully, and must diff --git a/lunaix-os/arch/i386/LBuild b/lunaix-os/arch/i386/LBuild deleted file mode 100644 index 8a7f155..0000000 --- a/lunaix-os/arch/i386/LBuild +++ /dev/null @@ -1,52 +0,0 @@ -use("hal") - -sources([ - "exceptions/interrupts.c", - "exceptions/i386_isrdef.c", - "exceptions/intr_routines.c", - "exceptions/i386_isrm.c", - - "exceptions/interrupt.S", - "exceptions/intrhnds.S", -]) - -sources([ - "boot/mb_parser.c", - "boot/kpt_setup.c", - "boot/init32.c", - - "boot/boot.S", - "boot/prologue.S" -]) - -sources([ - "mm/fault.c", - "mm/tlb.c", - "mm/pmm.c", - "mm/gdt.c", - "mm/vmutils.c" -]) - -sources([ - "klib/fast_crc.c", - "klib/fast_str.c", - "hart.c", - "arch.c", - "gdbstub.c", - "trace.c", - - "syscall.S", - "failsafe.S" -]) - -headers([ - "includes" -]) - -compile_opts([ - "-m32" -]) - -linking_opts([ - "-m32" -]) \ No newline at end of file diff --git a/lunaix-os/arch/i386/LConfig b/lunaix-os/arch/i386/LConfig deleted file mode 100644 index 1445686..0000000 --- a/lunaix-os/arch/i386/LConfig +++ /dev/null @@ -1,23 +0,0 @@ - -@Group -def x86_configurations(): - @Term - def x86_enable_sse_feature(): - """ - Config whether to allow using SSE feature for certain - optimization - """ - - type(bool) - default(False) - - add_to_collection(architecture_support) - - - @Term - def x86_boot_options(): - type(["multiboot"]) - # type(["multiboot", "none"]) - default("multiboot") - - return v(arch) == "i386" \ No newline at end of file diff --git a/lunaix-os/arch/i386/exceptions/i386_isrdef.c b/lunaix-os/arch/i386/exceptions/i386_isrdef.c deleted file mode 100644 index 8bebb96..0000000 --- a/lunaix-os/arch/i386/exceptions/i386_isrdef.c +++ /dev/null @@ -1,537 +0,0 @@ -/* Generated from i386_isrdef.c.j2. Do NOT modify */ - -#include -#include - -#define IDT_INTERRUPT 0x70 -#define KERNEL_CS 0x8 -#define IDT_ATTR(dpl, type) (((type) << 5) | ((dpl & 3) << 13) | (1 << 15)) -#define IDT_ENTRY 256 - -#define DECLARE_ISR(iv) extern void _asm_isr##iv(); - -#define ISR_INSTALL(idt, iv, isr, dpl) \ - _idt[iv] = ((ptr_t)isr & 0xffff0000) | IDT_ATTR(dpl, IDT_INTERRUPT); \ - _idt[iv] <<= 32; \ - _idt[iv] |= (KERNEL_CS << 16) | ((ptr_t)isr & 0x0000ffff); \ - -u64_t _idt[IDT_ENTRY]; -u16_t _idt_limit = sizeof(_idt) - 1; - -DECLARE_ISR(0) -DECLARE_ISR(1) -DECLARE_ISR(2) -DECLARE_ISR(3) -DECLARE_ISR(4) -DECLARE_ISR(5) -DECLARE_ISR(6) -DECLARE_ISR(7) -DECLARE_ISR(8) -DECLARE_ISR(9) -DECLARE_ISR(10) -DECLARE_ISR(11) -DECLARE_ISR(12) -DECLARE_ISR(13) -DECLARE_ISR(14) -DECLARE_ISR(15) -DECLARE_ISR(16) -DECLARE_ISR(17) -DECLARE_ISR(18) -DECLARE_ISR(19) -DECLARE_ISR(20) -DECLARE_ISR(21) -DECLARE_ISR(22) -DECLARE_ISR(23) -DECLARE_ISR(24) -DECLARE_ISR(25) -DECLARE_ISR(26) -DECLARE_ISR(27) -DECLARE_ISR(28) -DECLARE_ISR(29) -DECLARE_ISR(30) -DECLARE_ISR(31) -DECLARE_ISR(32) -DECLARE_ISR(33) -DECLARE_ISR(34) -DECLARE_ISR(35) -DECLARE_ISR(36) -DECLARE_ISR(37) -DECLARE_ISR(38) -DECLARE_ISR(39) -DECLARE_ISR(40) -DECLARE_ISR(41) -DECLARE_ISR(42) -DECLARE_ISR(43) -DECLARE_ISR(44) -DECLARE_ISR(45) -DECLARE_ISR(46) -DECLARE_ISR(47) -DECLARE_ISR(48) -DECLARE_ISR(49) -DECLARE_ISR(50) -DECLARE_ISR(51) -DECLARE_ISR(52) -DECLARE_ISR(53) -DECLARE_ISR(54) -DECLARE_ISR(55) -DECLARE_ISR(56) -DECLARE_ISR(57) -DECLARE_ISR(58) -DECLARE_ISR(59) -DECLARE_ISR(60) -DECLARE_ISR(61) -DECLARE_ISR(62) -DECLARE_ISR(63) -DECLARE_ISR(64) -DECLARE_ISR(65) -DECLARE_ISR(66) -DECLARE_ISR(67) -DECLARE_ISR(68) -DECLARE_ISR(69) -DECLARE_ISR(70) -DECLARE_ISR(71) -DECLARE_ISR(72) -DECLARE_ISR(73) -DECLARE_ISR(74) -DECLARE_ISR(75) -DECLARE_ISR(76) -DECLARE_ISR(77) -DECLARE_ISR(78) -DECLARE_ISR(79) -DECLARE_ISR(80) -DECLARE_ISR(81) -DECLARE_ISR(82) -DECLARE_ISR(83) -DECLARE_ISR(84) -DECLARE_ISR(85) -DECLARE_ISR(86) -DECLARE_ISR(87) -DECLARE_ISR(88) -DECLARE_ISR(89) -DECLARE_ISR(90) -DECLARE_ISR(91) -DECLARE_ISR(92) -DECLARE_ISR(93) -DECLARE_ISR(94) -DECLARE_ISR(95) -DECLARE_ISR(96) -DECLARE_ISR(97) -DECLARE_ISR(98) -DECLARE_ISR(99) -DECLARE_ISR(100) -DECLARE_ISR(101) -DECLARE_ISR(102) -DECLARE_ISR(103) -DECLARE_ISR(104) -DECLARE_ISR(105) -DECLARE_ISR(106) -DECLARE_ISR(107) -DECLARE_ISR(108) -DECLARE_ISR(109) -DECLARE_ISR(110) -DECLARE_ISR(111) -DECLARE_ISR(112) -DECLARE_ISR(113) -DECLARE_ISR(114) -DECLARE_ISR(115) -DECLARE_ISR(116) -DECLARE_ISR(117) -DECLARE_ISR(118) -DECLARE_ISR(119) -DECLARE_ISR(120) -DECLARE_ISR(121) -DECLARE_ISR(122) -DECLARE_ISR(123) -DECLARE_ISR(124) -DECLARE_ISR(125) -DECLARE_ISR(126) -DECLARE_ISR(127) -DECLARE_ISR(128) -DECLARE_ISR(129) -DECLARE_ISR(130) -DECLARE_ISR(131) -DECLARE_ISR(132) -DECLARE_ISR(133) -DECLARE_ISR(134) -DECLARE_ISR(135) -DECLARE_ISR(136) -DECLARE_ISR(137) -DECLARE_ISR(138) -DECLARE_ISR(139) -DECLARE_ISR(140) -DECLARE_ISR(141) -DECLARE_ISR(142) -DECLARE_ISR(143) -DECLARE_ISR(144) -DECLARE_ISR(145) -DECLARE_ISR(146) -DECLARE_ISR(147) -DECLARE_ISR(148) -DECLARE_ISR(149) -DECLARE_ISR(150) -DECLARE_ISR(151) -DECLARE_ISR(152) -DECLARE_ISR(153) -DECLARE_ISR(154) -DECLARE_ISR(155) -DECLARE_ISR(156) -DECLARE_ISR(157) -DECLARE_ISR(158) -DECLARE_ISR(159) -DECLARE_ISR(160) -DECLARE_ISR(161) -DECLARE_ISR(162) -DECLARE_ISR(163) -DECLARE_ISR(164) -DECLARE_ISR(165) -DECLARE_ISR(166) -DECLARE_ISR(167) -DECLARE_ISR(168) -DECLARE_ISR(169) -DECLARE_ISR(170) -DECLARE_ISR(171) -DECLARE_ISR(172) -DECLARE_ISR(173) -DECLARE_ISR(174) -DECLARE_ISR(175) -DECLARE_ISR(176) -DECLARE_ISR(177) -DECLARE_ISR(178) -DECLARE_ISR(179) -DECLARE_ISR(180) -DECLARE_ISR(181) -DECLARE_ISR(182) -DECLARE_ISR(183) -DECLARE_ISR(184) -DECLARE_ISR(185) -DECLARE_ISR(186) -DECLARE_ISR(187) -DECLARE_ISR(188) -DECLARE_ISR(189) -DECLARE_ISR(190) -DECLARE_ISR(191) -DECLARE_ISR(192) -DECLARE_ISR(193) -DECLARE_ISR(194) -DECLARE_ISR(195) -DECLARE_ISR(196) -DECLARE_ISR(197) -DECLARE_ISR(198) -DECLARE_ISR(199) -DECLARE_ISR(200) -DECLARE_ISR(201) -DECLARE_ISR(202) -DECLARE_ISR(203) -DECLARE_ISR(204) -DECLARE_ISR(205) -DECLARE_ISR(206) -DECLARE_ISR(207) -DECLARE_ISR(208) -DECLARE_ISR(209) -DECLARE_ISR(210) -DECLARE_ISR(211) -DECLARE_ISR(212) -DECLARE_ISR(213) -DECLARE_ISR(214) -DECLARE_ISR(215) -DECLARE_ISR(216) -DECLARE_ISR(217) -DECLARE_ISR(218) -DECLARE_ISR(219) -DECLARE_ISR(220) -DECLARE_ISR(221) -DECLARE_ISR(222) -DECLARE_ISR(223) -DECLARE_ISR(224) -DECLARE_ISR(225) -DECLARE_ISR(226) -DECLARE_ISR(227) -DECLARE_ISR(228) -DECLARE_ISR(229) -DECLARE_ISR(230) -DECLARE_ISR(231) -DECLARE_ISR(232) -DECLARE_ISR(233) -DECLARE_ISR(234) -DECLARE_ISR(235) -DECLARE_ISR(236) -DECLARE_ISR(237) -DECLARE_ISR(238) -DECLARE_ISR(239) -DECLARE_ISR(240) -DECLARE_ISR(241) -DECLARE_ISR(242) -DECLARE_ISR(243) -DECLARE_ISR(244) -DECLARE_ISR(245) -DECLARE_ISR(246) -DECLARE_ISR(247) -DECLARE_ISR(248) -DECLARE_ISR(249) -DECLARE_ISR(250) -DECLARE_ISR(251) -DECLARE_ISR(252) -DECLARE_ISR(253) -DECLARE_ISR(254) -DECLARE_ISR(255) - -void -exception_install_handler() -{ - ISR_INSTALL(_idt, 0, _asm_isr0, 0) - ISR_INSTALL(_idt, 1, _asm_isr1, 0) - ISR_INSTALL(_idt, 2, _asm_isr2, 0) - ISR_INSTALL(_idt, 3, _asm_isr3, 0) - ISR_INSTALL(_idt, 4, _asm_isr4, 0) - ISR_INSTALL(_idt, 5, _asm_isr5, 0) - ISR_INSTALL(_idt, 6, _asm_isr6, 0) - ISR_INSTALL(_idt, 7, _asm_isr7, 0) - ISR_INSTALL(_idt, 8, _asm_isr8, 0) - ISR_INSTALL(_idt, 9, _asm_isr9, 0) - ISR_INSTALL(_idt, 10, _asm_isr10, 0) - ISR_INSTALL(_idt, 11, _asm_isr11, 0) - ISR_INSTALL(_idt, 12, _asm_isr12, 0) - ISR_INSTALL(_idt, 13, _asm_isr13, 0) - ISR_INSTALL(_idt, 14, _asm_isr14, 0) - ISR_INSTALL(_idt, 15, _asm_isr15, 0) - ISR_INSTALL(_idt, 16, _asm_isr16, 0) - ISR_INSTALL(_idt, 17, _asm_isr17, 0) - ISR_INSTALL(_idt, 18, _asm_isr18, 0) - ISR_INSTALL(_idt, 19, _asm_isr19, 0) - ISR_INSTALL(_idt, 20, _asm_isr20, 0) - ISR_INSTALL(_idt, 21, _asm_isr21, 0) - ISR_INSTALL(_idt, 22, _asm_isr22, 0) - ISR_INSTALL(_idt, 23, _asm_isr23, 0) - ISR_INSTALL(_idt, 24, _asm_isr24, 0) - ISR_INSTALL(_idt, 25, _asm_isr25, 0) - ISR_INSTALL(_idt, 26, _asm_isr26, 0) - ISR_INSTALL(_idt, 27, _asm_isr27, 0) - ISR_INSTALL(_idt, 28, _asm_isr28, 0) - ISR_INSTALL(_idt, 29, _asm_isr29, 0) - ISR_INSTALL(_idt, 30, _asm_isr30, 0) - ISR_INSTALL(_idt, 31, _asm_isr31, 0) - ISR_INSTALL(_idt, 32, _asm_isr32, 0) - ISR_INSTALL(_idt, 33, _asm_isr33, 3) - ISR_INSTALL(_idt, 34, _asm_isr34, 0) - ISR_INSTALL(_idt, 35, _asm_isr35, 0) - ISR_INSTALL(_idt, 36, _asm_isr36, 0) - ISR_INSTALL(_idt, 37, _asm_isr37, 0) - ISR_INSTALL(_idt, 38, _asm_isr38, 0) - ISR_INSTALL(_idt, 39, _asm_isr39, 0) - ISR_INSTALL(_idt, 40, _asm_isr40, 0) - ISR_INSTALL(_idt, 41, _asm_isr41, 0) - ISR_INSTALL(_idt, 42, _asm_isr42, 0) - ISR_INSTALL(_idt, 43, _asm_isr43, 0) - ISR_INSTALL(_idt, 44, _asm_isr44, 0) - ISR_INSTALL(_idt, 45, _asm_isr45, 0) - ISR_INSTALL(_idt, 46, _asm_isr46, 0) - ISR_INSTALL(_idt, 47, _asm_isr47, 0) - ISR_INSTALL(_idt, 48, _asm_isr48, 0) - ISR_INSTALL(_idt, 49, _asm_isr49, 0) - ISR_INSTALL(_idt, 50, _asm_isr50, 0) - ISR_INSTALL(_idt, 51, _asm_isr51, 0) - ISR_INSTALL(_idt, 52, _asm_isr52, 0) - ISR_INSTALL(_idt, 53, _asm_isr53, 0) - ISR_INSTALL(_idt, 54, _asm_isr54, 0) - ISR_INSTALL(_idt, 55, _asm_isr55, 0) - ISR_INSTALL(_idt, 56, _asm_isr56, 0) - ISR_INSTALL(_idt, 57, _asm_isr57, 0) - ISR_INSTALL(_idt, 58, _asm_isr58, 0) - ISR_INSTALL(_idt, 59, _asm_isr59, 0) - ISR_INSTALL(_idt, 60, _asm_isr60, 0) - ISR_INSTALL(_idt, 61, _asm_isr61, 0) - ISR_INSTALL(_idt, 62, _asm_isr62, 0) - ISR_INSTALL(_idt, 63, _asm_isr63, 0) - ISR_INSTALL(_idt, 64, _asm_isr64, 0) - ISR_INSTALL(_idt, 65, _asm_isr65, 0) - ISR_INSTALL(_idt, 66, _asm_isr66, 0) - ISR_INSTALL(_idt, 67, _asm_isr67, 0) - ISR_INSTALL(_idt, 68, _asm_isr68, 0) - ISR_INSTALL(_idt, 69, _asm_isr69, 0) - ISR_INSTALL(_idt, 70, _asm_isr70, 0) - ISR_INSTALL(_idt, 71, _asm_isr71, 0) - ISR_INSTALL(_idt, 72, _asm_isr72, 0) - ISR_INSTALL(_idt, 73, _asm_isr73, 0) - ISR_INSTALL(_idt, 74, _asm_isr74, 0) - ISR_INSTALL(_idt, 75, _asm_isr75, 0) - ISR_INSTALL(_idt, 76, _asm_isr76, 0) - ISR_INSTALL(_idt, 77, _asm_isr77, 0) - ISR_INSTALL(_idt, 78, _asm_isr78, 0) - ISR_INSTALL(_idt, 79, _asm_isr79, 0) - ISR_INSTALL(_idt, 80, _asm_isr80, 0) - ISR_INSTALL(_idt, 81, _asm_isr81, 0) - ISR_INSTALL(_idt, 82, _asm_isr82, 0) - ISR_INSTALL(_idt, 83, _asm_isr83, 0) - ISR_INSTALL(_idt, 84, _asm_isr84, 0) - ISR_INSTALL(_idt, 85, _asm_isr85, 0) - ISR_INSTALL(_idt, 86, _asm_isr86, 0) - ISR_INSTALL(_idt, 87, _asm_isr87, 0) - ISR_INSTALL(_idt, 88, _asm_isr88, 0) - ISR_INSTALL(_idt, 89, _asm_isr89, 0) - ISR_INSTALL(_idt, 90, _asm_isr90, 0) - ISR_INSTALL(_idt, 91, _asm_isr91, 0) - ISR_INSTALL(_idt, 92, _asm_isr92, 0) - ISR_INSTALL(_idt, 93, _asm_isr93, 0) - ISR_INSTALL(_idt, 94, _asm_isr94, 0) - ISR_INSTALL(_idt, 95, _asm_isr95, 0) - ISR_INSTALL(_idt, 96, _asm_isr96, 0) - ISR_INSTALL(_idt, 97, _asm_isr97, 0) - ISR_INSTALL(_idt, 98, _asm_isr98, 0) - ISR_INSTALL(_idt, 99, _asm_isr99, 0) - ISR_INSTALL(_idt, 100, _asm_isr100, 0) - ISR_INSTALL(_idt, 101, _asm_isr101, 0) - ISR_INSTALL(_idt, 102, _asm_isr102, 0) - ISR_INSTALL(_idt, 103, _asm_isr103, 0) - ISR_INSTALL(_idt, 104, _asm_isr104, 0) - ISR_INSTALL(_idt, 105, _asm_isr105, 0) - ISR_INSTALL(_idt, 106, _asm_isr106, 0) - ISR_INSTALL(_idt, 107, _asm_isr107, 0) - ISR_INSTALL(_idt, 108, _asm_isr108, 0) - ISR_INSTALL(_idt, 109, _asm_isr109, 0) - ISR_INSTALL(_idt, 110, _asm_isr110, 0) - ISR_INSTALL(_idt, 111, _asm_isr111, 0) - ISR_INSTALL(_idt, 112, _asm_isr112, 0) - ISR_INSTALL(_idt, 113, _asm_isr113, 0) - ISR_INSTALL(_idt, 114, _asm_isr114, 0) - ISR_INSTALL(_idt, 115, _asm_isr115, 0) - ISR_INSTALL(_idt, 116, _asm_isr116, 0) - ISR_INSTALL(_idt, 117, _asm_isr117, 0) - ISR_INSTALL(_idt, 118, _asm_isr118, 0) - ISR_INSTALL(_idt, 119, _asm_isr119, 0) - ISR_INSTALL(_idt, 120, _asm_isr120, 0) - ISR_INSTALL(_idt, 121, _asm_isr121, 0) - ISR_INSTALL(_idt, 122, _asm_isr122, 0) - ISR_INSTALL(_idt, 123, _asm_isr123, 0) - ISR_INSTALL(_idt, 124, _asm_isr124, 0) - ISR_INSTALL(_idt, 125, _asm_isr125, 0) - ISR_INSTALL(_idt, 126, _asm_isr126, 0) - ISR_INSTALL(_idt, 127, _asm_isr127, 0) - ISR_INSTALL(_idt, 128, _asm_isr128, 0) - ISR_INSTALL(_idt, 129, _asm_isr129, 0) - ISR_INSTALL(_idt, 130, _asm_isr130, 0) - ISR_INSTALL(_idt, 131, _asm_isr131, 0) - ISR_INSTALL(_idt, 132, _asm_isr132, 0) - ISR_INSTALL(_idt, 133, _asm_isr133, 0) - ISR_INSTALL(_idt, 134, _asm_isr134, 0) - ISR_INSTALL(_idt, 135, _asm_isr135, 0) - ISR_INSTALL(_idt, 136, _asm_isr136, 0) - ISR_INSTALL(_idt, 137, _asm_isr137, 0) - ISR_INSTALL(_idt, 138, _asm_isr138, 0) - ISR_INSTALL(_idt, 139, _asm_isr139, 0) - ISR_INSTALL(_idt, 140, _asm_isr140, 0) - ISR_INSTALL(_idt, 141, _asm_isr141, 0) - ISR_INSTALL(_idt, 142, _asm_isr142, 0) - ISR_INSTALL(_idt, 143, _asm_isr143, 0) - ISR_INSTALL(_idt, 144, _asm_isr144, 0) - ISR_INSTALL(_idt, 145, _asm_isr145, 0) - ISR_INSTALL(_idt, 146, _asm_isr146, 0) - ISR_INSTALL(_idt, 147, _asm_isr147, 0) - ISR_INSTALL(_idt, 148, _asm_isr148, 0) - ISR_INSTALL(_idt, 149, _asm_isr149, 0) - ISR_INSTALL(_idt, 150, _asm_isr150, 0) - ISR_INSTALL(_idt, 151, _asm_isr151, 0) - ISR_INSTALL(_idt, 152, _asm_isr152, 0) - ISR_INSTALL(_idt, 153, _asm_isr153, 0) - ISR_INSTALL(_idt, 154, _asm_isr154, 0) - ISR_INSTALL(_idt, 155, _asm_isr155, 0) - ISR_INSTALL(_idt, 156, _asm_isr156, 0) - ISR_INSTALL(_idt, 157, _asm_isr157, 0) - ISR_INSTALL(_idt, 158, _asm_isr158, 0) - ISR_INSTALL(_idt, 159, _asm_isr159, 0) - ISR_INSTALL(_idt, 160, _asm_isr160, 0) - ISR_INSTALL(_idt, 161, _asm_isr161, 0) - ISR_INSTALL(_idt, 162, _asm_isr162, 0) - ISR_INSTALL(_idt, 163, _asm_isr163, 0) - ISR_INSTALL(_idt, 164, _asm_isr164, 0) - ISR_INSTALL(_idt, 165, _asm_isr165, 0) - ISR_INSTALL(_idt, 166, _asm_isr166, 0) - ISR_INSTALL(_idt, 167, _asm_isr167, 0) - ISR_INSTALL(_idt, 168, _asm_isr168, 0) - ISR_INSTALL(_idt, 169, _asm_isr169, 0) - ISR_INSTALL(_idt, 170, _asm_isr170, 0) - ISR_INSTALL(_idt, 171, _asm_isr171, 0) - ISR_INSTALL(_idt, 172, _asm_isr172, 0) - ISR_INSTALL(_idt, 173, _asm_isr173, 0) - ISR_INSTALL(_idt, 174, _asm_isr174, 0) - ISR_INSTALL(_idt, 175, _asm_isr175, 0) - ISR_INSTALL(_idt, 176, _asm_isr176, 0) - ISR_INSTALL(_idt, 177, _asm_isr177, 0) - ISR_INSTALL(_idt, 178, _asm_isr178, 0) - ISR_INSTALL(_idt, 179, _asm_isr179, 0) - ISR_INSTALL(_idt, 180, _asm_isr180, 0) - ISR_INSTALL(_idt, 181, _asm_isr181, 0) - ISR_INSTALL(_idt, 182, _asm_isr182, 0) - ISR_INSTALL(_idt, 183, _asm_isr183, 0) - ISR_INSTALL(_idt, 184, _asm_isr184, 0) - ISR_INSTALL(_idt, 185, _asm_isr185, 0) - ISR_INSTALL(_idt, 186, _asm_isr186, 0) - ISR_INSTALL(_idt, 187, _asm_isr187, 0) - ISR_INSTALL(_idt, 188, _asm_isr188, 0) - ISR_INSTALL(_idt, 189, _asm_isr189, 0) - ISR_INSTALL(_idt, 190, _asm_isr190, 0) - ISR_INSTALL(_idt, 191, _asm_isr191, 0) - ISR_INSTALL(_idt, 192, _asm_isr192, 0) - ISR_INSTALL(_idt, 193, _asm_isr193, 0) - ISR_INSTALL(_idt, 194, _asm_isr194, 0) - ISR_INSTALL(_idt, 195, _asm_isr195, 0) - ISR_INSTALL(_idt, 196, _asm_isr196, 0) - ISR_INSTALL(_idt, 197, _asm_isr197, 0) - ISR_INSTALL(_idt, 198, _asm_isr198, 0) - ISR_INSTALL(_idt, 199, _asm_isr199, 0) - ISR_INSTALL(_idt, 200, _asm_isr200, 0) - ISR_INSTALL(_idt, 201, _asm_isr201, 0) - ISR_INSTALL(_idt, 202, _asm_isr202, 0) - ISR_INSTALL(_idt, 203, _asm_isr203, 0) - ISR_INSTALL(_idt, 204, _asm_isr204, 0) - ISR_INSTALL(_idt, 205, _asm_isr205, 0) - ISR_INSTALL(_idt, 206, _asm_isr206, 0) - ISR_INSTALL(_idt, 207, _asm_isr207, 0) - ISR_INSTALL(_idt, 208, _asm_isr208, 0) - ISR_INSTALL(_idt, 209, _asm_isr209, 0) - ISR_INSTALL(_idt, 210, _asm_isr210, 0) - ISR_INSTALL(_idt, 211, _asm_isr211, 0) - ISR_INSTALL(_idt, 212, _asm_isr212, 0) - ISR_INSTALL(_idt, 213, _asm_isr213, 0) - ISR_INSTALL(_idt, 214, _asm_isr214, 0) - ISR_INSTALL(_idt, 215, _asm_isr215, 0) - ISR_INSTALL(_idt, 216, _asm_isr216, 0) - ISR_INSTALL(_idt, 217, _asm_isr217, 0) - ISR_INSTALL(_idt, 218, _asm_isr218, 0) - ISR_INSTALL(_idt, 219, _asm_isr219, 0) - ISR_INSTALL(_idt, 220, _asm_isr220, 0) - ISR_INSTALL(_idt, 221, _asm_isr221, 0) - ISR_INSTALL(_idt, 222, _asm_isr222, 0) - ISR_INSTALL(_idt, 223, _asm_isr223, 0) - ISR_INSTALL(_idt, 224, _asm_isr224, 0) - ISR_INSTALL(_idt, 225, _asm_isr225, 0) - ISR_INSTALL(_idt, 226, _asm_isr226, 0) - ISR_INSTALL(_idt, 227, _asm_isr227, 0) - ISR_INSTALL(_idt, 228, _asm_isr228, 0) - ISR_INSTALL(_idt, 229, _asm_isr229, 0) - ISR_INSTALL(_idt, 230, _asm_isr230, 0) - ISR_INSTALL(_idt, 231, _asm_isr231, 0) - ISR_INSTALL(_idt, 232, _asm_isr232, 0) - ISR_INSTALL(_idt, 233, _asm_isr233, 0) - ISR_INSTALL(_idt, 234, _asm_isr234, 0) - ISR_INSTALL(_idt, 235, _asm_isr235, 0) - ISR_INSTALL(_idt, 236, _asm_isr236, 0) - ISR_INSTALL(_idt, 237, _asm_isr237, 0) - ISR_INSTALL(_idt, 238, _asm_isr238, 0) - ISR_INSTALL(_idt, 239, _asm_isr239, 0) - ISR_INSTALL(_idt, 240, _asm_isr240, 0) - ISR_INSTALL(_idt, 241, _asm_isr241, 0) - ISR_INSTALL(_idt, 242, _asm_isr242, 0) - ISR_INSTALL(_idt, 243, _asm_isr243, 0) - ISR_INSTALL(_idt, 244, _asm_isr244, 0) - ISR_INSTALL(_idt, 245, _asm_isr245, 0) - ISR_INSTALL(_idt, 246, _asm_isr246, 0) - ISR_INSTALL(_idt, 247, _asm_isr247, 0) - ISR_INSTALL(_idt, 248, _asm_isr248, 0) - ISR_INSTALL(_idt, 249, _asm_isr249, 0) - ISR_INSTALL(_idt, 250, _asm_isr250, 0) - ISR_INSTALL(_idt, 251, _asm_isr251, 0) - ISR_INSTALL(_idt, 252, _asm_isr252, 0) - ISR_INSTALL(_idt, 253, _asm_isr253, 0) - ISR_INSTALL(_idt, 254, _asm_isr254, 0) - ISR_INSTALL(_idt, 255, _asm_isr255, 0) -} \ No newline at end of file diff --git a/lunaix-os/arch/i386/includes/sys/abi.h b/lunaix-os/arch/i386/includes/sys/abi.h deleted file mode 100644 index d847251..0000000 --- a/lunaix-os/arch/i386/includes/sys/abi.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef __LUNAIX_I386ABI_H -#define __LUNAIX_I386ABI_H - -#include "sys/x86_isa.h" - -#define stack_alignment 0xfffffff0 - -#ifndef __ASM__ -#define align_stack(ptr) ((ptr) & stack_alignment) -#define store_retval(retval) current_thread->hstate->registers.eax = (retval) - -#define store_retval_to(th, retval) (th)->hstate->registers.eax = (retval) - -static inline void must_inline -j_usr(ptr_t sp, ptr_t pc) -{ - asm volatile("movw %0, %%ax\n" - "movw %%ax, %%es\n" - "movw %%ax, %%ds\n" - "movw %%ax, %%fs\n" - "movw %%ax, %%gs\n" - "pushl %0\n" - "pushl %1\n" - "pushl %2\n" - "pushl %3\n" - "retf" ::"i"(UDATA_SEG), - "r"(sp), - "i"(UCODE_SEG), - "r"(pc) - : "eax", "memory"); -} - - -static inline void must_inline noret -switch_context() { - asm volatile("jmp do_switch\n"); - unreachable; -} - -#define push_arg1(stack_ptr, arg) *((typeof((arg))*)(stack_ptr)--) = arg -#define push_arg2(stack_ptr, arg1, arg2) \ - { \ - *((typeof((arg1))*)(stack_ptr)--) = arg1; \ - *((typeof((arg2))*)(stack_ptr)--) = arg2; \ - } -#define push_arg3(stack_ptr, arg1, arg2, arg3) \ - { \ - *((typeof((arg1))*)(stack_ptr)--) = arg1; \ - *((typeof((arg2))*)(stack_ptr)--) = arg2; \ - *((typeof((arg3))*)(stack_ptr)--) = arg3; \ - } -#define push_arg4(stack_ptr, arg1, arg2, arg3, arg4) \ - { \ - *((typeof((arg1))*)(stack_ptr)--) = arg1; \ - *((typeof((arg2))*)(stack_ptr)--) = arg2; \ - *((typeof((arg3))*)(stack_ptr)--) = arg3; \ - *((typeof((arg4))*)(stack_ptr)--) = arg4; \ - } - - -static inline ptr_t must_inline -abi_get_callframe() -{ - ptr_t val; - asm("movl %%ebp, %0" : "=r"(val)::); - return val; -} - -static inline ptr_t -abi_get_retaddr() -{ - return *((ptr_t*)abi_get_callframe() + 1); -} - -static inline ptr_t -abi_get_retaddrat(ptr_t fp) -{ - return *((ptr_t*)fp + 1); -} -#endif -#endif /* __LUNAIX_ABI_H */ diff --git a/lunaix-os/arch/i386/includes/sys/boot/bstage.h b/lunaix-os/arch/i386/includes/sys/boot/bstage.h deleted file mode 100644 index 0744481..0000000 --- a/lunaix-os/arch/i386/includes/sys/boot/bstage.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __LUNAIX_BSTAGE_H -#define __LUNAIX_BSTAGE_H - -#define boot_text __attribute__((section(".boot.text"))) -#define boot_data __attribute__((section(".boot.data"))) -#define boot_bss __attribute__((section(".boot.bss"))) - -#endif /* __LUNAIX_BSTAGE_H */ diff --git a/lunaix-os/arch/i386/includes/sys/i386_intr.h b/lunaix-os/arch/i386/includes/sys/i386_intr.h deleted file mode 100644 index bf78c35..0000000 --- a/lunaix-os/arch/i386/includes/sys/i386_intr.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __LUNAIX_I386_INTR_H -#define __LUNAIX_I386_INTR_H - -void -exception_install_handler(); - -void -intr_routine_init(); - -#endif /* __LUNAIX_I386_INTR_H */ diff --git a/lunaix-os/arch/i386/includes/sys/mm/mempart.h b/lunaix-os/arch/i386/includes/sys/mm/mempart.h deleted file mode 100644 index aac7f9c..0000000 --- a/lunaix-os/arch/i386/includes/sys/mm/mempart.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef __LUNAIX_MEMPART_H -#define __LUNAIX_MEMPART_H - -#define MEM_PAGE 0x1000UL -#define MEM_1M 0x100000UL -#define MEM_4M 0x400000UL -#define MEM_HUGE 0x400000UL -#define MEM_1G 0x40000000UL - -#define END_POINT(name) (name + name##_SIZE - 1) - -#define KSTACK_AREA 0x100000UL -#define KSTACK_AREA_SIZE 0x300000UL -#define KSTACK_AREA_END END_POINT(KSTACK_AREA) - -#define USR_EXEC 0x400000UL -#define USR_EXEC_SIZE 0x20000000UL -#define USR_EXEC_END END_POINT(USR_EXEC) - -#define USR_MMAP 0x20400000UL -#define USR_MMAP_SIZE 0x9fbc0000UL -#define USR_MMAP_END END_POINT(USR_MMAP) - -#define USR_STACK 0xbffc0000UL -#define USR_STACK_SIZE 0x40000UL -#define USR_STACK_END END_POINT(USR_STACK) - -#define KERNEL_IMG 0xc0000000UL -#define KERNEL_IMG_SIZE 0x4000000UL -#define KERNEL_IMG_END END_POINT(KERNEL_IMG) - -#define PG_MOUNT_1 0xc4000000UL -#define PG_MOUNT_1_SIZE 0x1000UL -#define PG_MOUNT_1_END END_POINT(PG_MOUNT_1) - -#define PG_MOUNT_2 0xc4001000UL -#define PG_MOUNT_2_SIZE 0x1000UL -#define PG_MOUNT_2_END END_POINT(PG_MOUNT_2) - -#define PG_MOUNT_3 0xc4002000UL -#define PG_MOUNT_3_SIZE 0x1000UL -#define PG_MOUNT_3_END END_POINT(PG_MOUNT_3) - -#define PG_MOUNT_4 0xc4003000UL -#define PG_MOUNT_4_SIZE 0x1000UL -#define PG_MOUNT_4_END END_POINT(PG_MOUNT_4) - -#define PG_MOUNT_VAR 0xc4004000UL -#define PG_MOUNT_VAR_SIZE 0x3fc000UL -#define PG_MOUNT_VAR_END END_POINT(PG_MOUNT_VAR) - -#define VMAP 0xc4400000UL -#define VMAP_SIZE 0x3b400000UL -#define VMAP_END END_POINT(VMAP) - -#define VMS_MOUNT_1 0xff800000UL -#define VMS_MOUNT_1_SIZE 0x400000UL -#define VMS_MOUNT_1_END END_POINT(VMS_MOUNT_1) - -#endif \ No newline at end of file diff --git a/lunaix-os/arch/i386/includes/sys/x86_isa.h b/lunaix-os/arch/i386/includes/sys/x86_isa.h deleted file mode 100644 index 7db8807..0000000 --- a/lunaix-os/arch/i386/includes/sys/x86_isa.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef __LUNAIX_I386_ASM_H -#define __LUNAIX_I386_ASM_H - -#define KCODE_SEG 0x08 -#define KDATA_SEG 0x10 -#define UCODE_SEG 0x1B -#define UDATA_SEG 0x23 -#define TSS_SEG 0x28 - -#define tss_esp0_off 4 - -#ifndef __ASM__ -#include - -#define IRQ_TRIG_EDGE 0b0 -#define IRQ_TRIG_LEVEL 0b1 - -#define IRQ_TYPE_FIXED (0b01 << 1) -#define IRQ_TYPE_NMI (0b11 << 1) -#define IRQ_TYPE (0b11 << 1) - -#define IRQ_VE_HI (0b1 << 3) -#define IRQ_VE_LO (0b0 << 3) - -#define IRQ_DEFAULT (IRQ_TRIG_EDGE | IRQ_TYPE_FIXED | IRQ_VE_HI) - - -struct x86_tss -{ - u32_t link; - u32_t esp0; - u16_t ss0; - u8_t __padding[94]; -} __attribute__((packed)); - -void tss_update_esp(u32_t esp0); - -struct x86_intc -{ - char* name; - void* data; - - void (*irq_attach)(struct x86_intc*, - int irq, - int iv, - cpu_t dest, - u32_t flags); - void (*notify_eoi)(struct x86_intc*, cpu_t id, int iv); -}; - - -#endif - -#endif /* __LUNAIX_I386_ASM_H */ diff --git a/lunaix-os/arch/i386/klib/fast_str.c b/lunaix-os/arch/i386/klib/fast_str.c deleted file mode 100644 index 46dcf28..0000000 --- a/lunaix-os/arch/i386/klib/fast_str.c +++ /dev/null @@ -1,26 +0,0 @@ -#include - -void* -memcpy(void* dest, const void* src, unsigned long num) -{ - if (!num) - return dest; - - asm volatile("movl %1, %%edi\n" - "rep movsb\n" ::"S"(src), - "r"(dest), - "c"(num) - : "edi", "memory"); - return dest; -} - -void* -memset(void* ptr, int value, unsigned long num) -{ - asm volatile("movl %1, %%edi\n" - "rep stosb\n" ::"c"(num), - "r"(ptr), - "a"(value) - : "edi", "memory"); - return ptr; -} \ No newline at end of file diff --git a/lunaix-os/arch/i386/trace.c b/lunaix-os/arch/i386/trace.c deleted file mode 100644 index 71c3229..0000000 --- a/lunaix-os/arch/i386/trace.c +++ /dev/null @@ -1,49 +0,0 @@ -#include - -void -trace_print_transistion_short(struct hart_state* hstate) -{ - trace_log(" trigger: iv=%d, ecause=%p", - hart_vector_stamp(hstate), - hart_ecause(hstate)); -} - -void -trace_print_transition_full(struct hart_state* hstate) -{ - trace_log("hart state transition"); - trace_log(" vector=%d, ecause=0x%x", - hart_vector_stamp(hstate), - hart_ecause(hstate)); - trace_log(" eflags=0x%x", hstate->execp->eflags); - trace_log(" sp=%p, [seg_sel=0x%04x]", - hstate->execp->esp, - hstate->execp->esp); - trace_log(" ip=%p, seg_sel=0x%04x", - hstate->execp->eip, - hstate->execp->cs); -} - -void -trace_dump_state(struct hart_state* hstate) -{ - struct regcontext* rh = &hstate->registers; - struct exec_param* ep = hstate->execp; - trace_log("hart state dump (depth=%d)", hstate->depth); - trace_log(" eax=0x%08x, ebx=0x%08x, ecx=0x%08x", - rh->eax, rh->ebx, rh->ecx); - trace_log(" edx=0x%08x, ebp=0x%08x", - rh->edx, rh->ebp); - trace_log(" ds=0x%04x, edi=0x%08x", - rh->ds, rh->edi); - trace_log(" es=0x%04x, esi=0x%08x", - rh->es, rh->esi); - trace_log(" fs=0x%04x, gs=0x%x", - rh->fs, rh->gs); - trace_log(" cs=0x%04x, ip=0x%08x", - ep->cs, ep->eip); - trace_log(" [ss=0x%04x],sp=0x%08x", - ep->ss, ep->eip); - trace_log(" eflags=0x%08x", - ep->eflags); -} \ No newline at end of file diff --git a/lunaix-os/arch/x86/LBuild b/lunaix-os/arch/x86/LBuild new file mode 100644 index 0000000..7d50ca3 --- /dev/null +++ b/lunaix-os/arch/x86/LBuild @@ -0,0 +1,82 @@ +use("hal") + +sources([ + "exceptions/interrupts.c", + "exceptions/isrdef.c", + "exceptions/intr_routines.c", + "exceptions/isrm.c", + "exceptions/intrhnds.S", +]) + +sources([ + "boot/mb_parser.c", + "boot/kpt_setup.c", + "boot/boot_helper.c" +]) + +sources([ + "mm/fault.c", + "mm/tlb.c", + "mm/pmm.c", + "mm/gdt.c", + "mm/vmutils.c" +]) + +sources([ + "klib/fast_crc.c", + "klib/fast_str.c", + "exec/exec.c", + "hart.c", + "arch.c", + "gdbstub.c", + "trace.c", + "hart.c", + "failsafe.S" +]) + +sources({ + config("arch"): { + "x86_64": [ + "hart64.c", + "syscall64.S", + "exceptions/interrupt64.S", + "boot/x86_64/boot64.S", + "boot/x86_64/init64.c", + "boot/x86_64/prologue64.S", + "boot/x86_64/kremap64.c", + "exec/elf64.c" + ], + "i386": [ + "hart32.c", + "syscall32.S", + "exceptions/interrupt32.S", + "boot/i386/boot32.S", + "boot/i386/init32.c", + "boot/i386/prologue32.S", + "boot/i386/kremap32.c", + "exec/elf32.c" + ] + } +}) + +headers([ + "includes" +]) + + +if config("arch") == "x86_64": + compile_opts([ + "-m64", + "-fno-unwind-tables", + "-fno-asynchronous-unwind-tables", + "-mcmodel=large" + ]) + linking_opts([ + "-m64", + ]) +else: + compile_opts("-m32") + linking_opts("-m32") + +if not config("x86_enable_sse_feature"): + compile_opts("-mno-sse") \ No newline at end of file diff --git a/lunaix-os/arch/x86/LConfig b/lunaix-os/arch/x86/LConfig new file mode 100644 index 0000000..7580a36 --- /dev/null +++ b/lunaix-os/arch/x86/LConfig @@ -0,0 +1,34 @@ + +@Group +def x86_configurations(): + + add_to_collection(architecture_support) + + @Term + def x86_enable_sse_feature(): + """ + Config whether to allow using SSE feature for certain + optimization + """ + + type(bool) + default(False) + + + @Term + def x86_bl(): + """ + Select the bootloader interface + + Supported interface + mb: multiboot compliant + mb2: multiboot2 compliant + none: do not use any interface + """ + + type(["mb"]) + # type(["mb", "mb2", "none"]) + default("mb") + + + return v(arch) in ["i386", "x86_64"] \ No newline at end of file diff --git a/lunaix-os/arch/i386/arch.c b/lunaix-os/arch/x86/arch.c similarity index 69% rename from lunaix-os/arch/i386/arch.c rename to lunaix-os/arch/x86/arch.c index 5ad6cd7..988f976 100644 --- a/lunaix-os/arch/i386/arch.c +++ b/lunaix-os/arch/x86/arch.c @@ -2,8 +2,10 @@ #include #include +#include -#include "sys/i386_intr.h" +#include "sys/int_handler.h" +#include "sys/x86_isa.h" #include "sys/hart.h" #include "hal/apic_timer.h" @@ -40,4 +42,15 @@ select_platform_timer() // TODO select alternatives... panick("no timer to use."); +} + +void +update_tss() +{ + extern struct x86_tss _tss; +#ifdef CONFIG_ARCH_X86_64 + _tss.rsps[0] = (ptr_t)current_thread->hstate; +#else + _tss.esp0 = (u32_t)current_thread->hstate; +#endif } \ No newline at end of file diff --git a/lunaix-os/arch/x86/boot/boot_helper.c b/lunaix-os/arch/x86/boot/boot_helper.c new file mode 100644 index 0000000..c5f0c46 --- /dev/null +++ b/lunaix-os/arch/x86/boot/boot_helper.c @@ -0,0 +1,46 @@ +#include +#include + +#include "sys/mm/mm_defs.h" + +#ifdef CONFIG_ARCH_X86_64 + +void +boot_begin_arch_reserve(struct boot_handoff* bhctx) +{ + return; +} + + +void +boot_clean_arch_reserve(struct boot_handoff* bhctx) +{ + return; +} + +#else + +#include + +void +boot_begin_arch_reserve(struct boot_handoff* bhctx) +{ + // Identity-map the first 3GiB address spaces + pte_t* ptep = mkl0tep(mkptep_va(VMS_SELF, 0)); + pte_t pte = mkpte_prot(KERNEL_DATA); + size_t count = page_count(KERNEL_RESIDENT, L0T_SIZE); + + vmm_set_ptes_contig(ptep, pte_mkhuge(pte), L0T_SIZE, count); +} + + +void +boot_clean_arch_reserve(struct boot_handoff* bhctx) +{ + pte_t* ptep = mkl0tep(mkptep_va(VMS_SELF, 0)); + size_t count = page_count(KERNEL_RESIDENT, L0T_SIZE); + vmm_unset_ptes(ptep, count); +} + + +#endif \ No newline at end of file diff --git a/lunaix-os/arch/i386/boot/boot.S b/lunaix-os/arch/x86/boot/i386/boot32.S similarity index 74% rename from lunaix-os/arch/i386/boot/boot.S rename to lunaix-os/arch/x86/boot/i386/boot32.S index 2f48bbc..b969104 100644 --- a/lunaix-os/arch/i386/boot/boot.S +++ b/lunaix-os/arch/x86/boot/i386/boot32.S @@ -1,13 +1,8 @@ -#define __ASM__ 1 -#include +#define __ASM__ -#define MB_FLAGS (MULTIBOOT_MEMORY_INFO | MULTIBOOT_PAGE_ALIGN) -#define KPG_SIZE 10*4096 - -.section .multiboot - .long MULTIBOOT_MAGIC - .long MB_FLAGS - .long CHECKSUM(MB_FLAGS) +#if defined(CONFIG_X86_BL_MB) || defined(CONFIG_X86_BL_MB2) +#include "sys/boot/multiboot.S.inc" +#endif .section .boot.bss /* 根据System V ABI,栈地址必须16字节对齐 */ diff --git a/lunaix-os/arch/i386/boot/init32.c b/lunaix-os/arch/x86/boot/i386/init32.c similarity index 78% rename from lunaix-os/arch/i386/boot/init32.c rename to lunaix-os/arch/x86/boot/i386/init32.c index 1b908f8..d9cc249 100644 --- a/lunaix-os/arch/i386/boot/init32.c +++ b/lunaix-os/arch/x86/boot/i386/init32.c @@ -1,6 +1,6 @@ -#include "archinit.h" -#include -#include +#include "sys/boot/archinit.h" +#include "sys/crx.h" +#include "sys/cpu.h" void boot_text x86_init(struct multiboot_info* mb) diff --git a/lunaix-os/arch/i386/boot/kpt_setup.c b/lunaix-os/arch/x86/boot/i386/kremap32.c similarity index 67% rename from lunaix-os/arch/i386/boot/kpt_setup.c rename to lunaix-os/arch/x86/boot/i386/kremap32.c index c353d77..c73c2a3 100644 --- a/lunaix-os/arch/i386/boot/kpt_setup.c +++ b/lunaix-os/arch/x86/boot/i386/kremap32.c @@ -6,15 +6,17 @@ #include #include -// Provided by linker (see linker.ld) -extern u8_t __kexec_start[]; -extern u8_t __kexec_end[]; -extern u8_t __kexec_text_start[]; -extern u8_t __kexec_text_end[]; -extern u8_t __kboot_start[]; -extern u8_t __kboot_end[]; +bridge_farsym(__kexec_start); +bridge_farsym(__kexec_end); +bridge_farsym(__kexec_text_start); +bridge_farsym(__kexec_text_end); // define the initial page table layout +struct kernel_map; + +static struct kernel_map kernel_pt __section(".kpg"); +export_symbol(debug, boot, kernel_pt); + struct kernel_map { pte_t l0t[_PAGE_LEVEL_SIZE]; pte_t pg_mnt[_PAGE_LEVEL_SIZE]; @@ -24,17 +26,14 @@ struct kernel_map { } kernel_lfts[16]; } align(4); -static struct kernel_map kernel_pt __section(".kpg"); -export_symbol(debug, boot, kernel_pt); - - -void boot_text -_init_page() +static void boot_text +do_remap() { struct kernel_map* kpt_pa = (struct kernel_map*)to_kphysical(&kernel_pt); - - pte_t* kl0tep = (pte_t*) &kpt_pa->l0t[pfn_at(KERNEL_RESIDENT, L0T_SIZE)]; - pte_t* kl1tep = (pte_t*) kpt_pa->kernel_lfts; + + size_t mia_casa_i = pfn_at(KERNEL_RESIDENT, L0T_SIZE); + pte_t* klptep = (pte_t*) &kpt_pa->l0t[mia_casa_i]; + pte_t* ktep = (pte_t*) kpt_pa->kernel_lfts; pte_t* boot_l0tep = (pte_t*) kpt_pa; set_pte(boot_l0tep, pte_mkhuge(mkpte_prot(KERNEL_DATA))); @@ -42,18 +41,18 @@ _init_page() // --- 将内核重映射至高半区 --- // Hook the kernel reserved LFTs onto L0T - pte_t pte = mkpte((ptr_t)kl1tep, KERNEL_DATA); + pte_t pte = mkpte((ptr_t)ktep, KERNEL_DATA); for (u32_t i = 0; i < KEXEC_RSVD; i++) { pte = pte_setpaddr(pte, (ptr_t)&kpt_pa->kernel_lfts[i]); - set_pte(kl0tep, pte); + set_pte(klptep, pte); - kl0tep++; + klptep++; } // Ensure the size of kernel is within the reservation pfn_t kimg_pagecount = - pfn((ptr_t)__kexec_end - (ptr_t)__kexec_start); + pfn(__far(__kexec_end) - __far(__kexec_start)); if (kimg_pagecount > KEXEC_RSVD * _PAGE_LEVEL_SIZE) { // ERROR: require more pages // here should do something else other than head into blocking @@ -62,27 +61,27 @@ _init_page() // Now, map the kernel - pfn_t kimg_end = pfn(to_kphysical(__kexec_end)); - pfn_t i = pfn(to_kphysical(__kexec_text_start)); - kl1tep += i; + pfn_t kimg_end = pfn(to_kphysical(__far(__kexec_end))); + pfn_t i = pfn(to_kphysical(__far(__kexec_text_start))); + ktep += i; // kernel .text pte = pte_setprot(pte, KERNEL_EXEC); - pfn_t ktext_end = pfn(to_kphysical(__kexec_text_end)); + pfn_t ktext_end = pfn(to_kphysical(__far(__kexec_text_end))); for (; i < ktext_end; i++) { pte = pte_setpaddr(pte, page_addr(i)); - set_pte(kl1tep, pte); + set_pte(ktep, pte); - kl1tep++; + ktep++; } // all remaining kernel sections pte = pte_setprot(pte, KERNEL_DATA); for (; i < kimg_end; i++) { pte = pte_setpaddr(pte, page_addr(i)); - set_pte(kl1tep, pte); + set_pte(ktep, pte); - kl1tep++; + ktep++; } // XXX: Mapping the kernel .rodata section? @@ -92,19 +91,21 @@ _init_page() set_pte(kmntep, mkpte((ptr_t)kpt_pa->pg_mnt, KERNEL_DATA)); // Build up self-reference + int level = (VMS_SELF / L0T_SIZE) & _PAGE_LEVEL_MASK; + pte = mkpte_root((ptr_t)kpt_pa, KERNEL_DATA); - set_pte(boot_l0tep + _PAGE_LEVEL_MASK, pte); + set_pte(&boot_l0tep[level], pte); } ptr_t boot_text -kpg_init() +remap_kernel() { ptr_t kmap_pa = to_kphysical(&kernel_pt); for (size_t i = 0; i < sizeof(kernel_pt); i++) { ((u8_t*)kmap_pa)[i] = 0; } - _init_page(); + do_remap(); return kmap_pa; } \ No newline at end of file diff --git a/lunaix-os/arch/i386/boot/prologue.S b/lunaix-os/arch/x86/boot/i386/prologue32.S similarity index 82% rename from lunaix-os/arch/i386/boot/prologue.S rename to lunaix-os/arch/x86/boot/i386/prologue32.S index dc17242..b8b4866 100644 --- a/lunaix-os/arch/i386/boot/prologue.S +++ b/lunaix-os/arch/x86/boot/i386/prologue32.S @@ -11,12 +11,7 @@ __kinit_stack_end: .skip 2048, 0 __kinit_stack_top: - # TODO - # This stack was too small that corrupt the ambient kernel structures. - # (took me days to figure this out!) - # We should spent more time to implement a good strategy to detect such - # run-over (we can check these invariants when we trapped in some non-recoverable - # state and provide good feedback to user) + .section .text .global hhk_entry_ @@ -56,7 +51,7 @@ movw %cx, %ss /* 更新 CS:EIP */ - pushw $KCODE_SEG + pushl $KCODE_SEG pushl $_after_gdt retf diff --git a/lunaix-os/arch/x86/boot/kpt_setup.c b/lunaix-os/arch/x86/boot/kpt_setup.c new file mode 100644 index 0000000..ebcbc0e --- /dev/null +++ b/lunaix-os/arch/x86/boot/kpt_setup.c @@ -0,0 +1,14 @@ +#define __BOOT_CODE__ + +#include +#include + +#include +#include + + +ptr_t boot_text +kpg_init() +{ + return remap_kernel(); +} \ No newline at end of file diff --git a/lunaix-os/arch/i386/boot/mb_parser.c b/lunaix-os/arch/x86/boot/mb_parser.c similarity index 89% rename from lunaix-os/arch/i386/boot/mb_parser.c rename to lunaix-os/arch/x86/boot/mb_parser.c index aa9a5f0..b01ed19 100644 --- a/lunaix-os/arch/i386/boot/mb_parser.c +++ b/lunaix-os/arch/x86/boot/mb_parser.c @@ -6,6 +6,8 @@ #include #define BHCTX_ALLOC 4096 +#define MEM_1M 0x100000UL + u8_t bhctx_buffer[BHCTX_ALLOC] boot_bss; @@ -72,7 +74,7 @@ mb_parse_mmap(struct boot_handoff* bhctx, void* buffer) { struct multiboot_mmap_entry* mb_mmap = - (struct multiboot_mmap_entry*)mb->mmap_addr; + (struct multiboot_mmap_entry*)__ptr(mb->mmap_addr); size_t mmap_len = mb->mmap_length / sizeof(struct multiboot_mmap_entry); struct boot_mmapent* bmmap = (struct boot_mmapent*)buffer; @@ -110,16 +112,19 @@ mb_parse_mods(struct boot_handoff* bhctx, } struct boot_modent* modents = (struct boot_modent*)buffer; - struct multiboot_mod_list* mods = (struct multiboot_mod_list*)mb->mods_addr; + struct multiboot_mod_list* mods = + (struct multiboot_mod_list*)__ptr(mb->mods_addr); - ptr_t mod_str_ptr = (ptr_t)&modents[mb->mods_count]; + ptr_t mod_str_ptr = __ptr(&modents[mb->mods_count]); for (size_t i = 0; i < mb->mods_count; i++) { struct multiboot_mod_list* mod = &mods[i]; modents[i] = (struct boot_modent){ .start = mod->mod_start, .end = mod->mod_end, .str = (char*)mod_str_ptr }; - mod_str_ptr += mb_strcpy((char*)mod_str_ptr, (char*)mod->cmdline); + + mod_str_ptr += mb_strcpy((char*)mod_str_ptr, + (char*)__ptr(mod->cmdline)); } bhctx->mods.mods_num = mb->mods_count; @@ -159,7 +164,7 @@ mb_parse(struct multiboot_info* mb) /* Parse cmdline */ if ((mb->flags & MULTIBOOT_INFO_CMDLINE)) { bhctx_ex += - mb_parse_cmdline(bhctx, (void*)bhctx_ex, (char*)mb->cmdline); + mb_parse_cmdline(bhctx, (void*)bhctx_ex, (char*)__ptr(mb->cmdline)); bhctx_ex = align_addr(bhctx_ex); } diff --git a/lunaix-os/arch/x86/boot/x86_64/boot64.S b/lunaix-os/arch/x86/boot/x86_64/boot64.S new file mode 100644 index 0000000..b7c82e3 --- /dev/null +++ b/lunaix-os/arch/x86/boot/x86_64/boot64.S @@ -0,0 +1,133 @@ +#define __ASM__ + +#if defined(CONFIG_X86_BL_MB) || defined(CONFIG_X86_BL_MB2) +#include "sys/boot/multiboot.S.inc" +#endif + +#include "sys/mm/mempart64.h" + +.section .boot.bss + .align 8 + __tmp_gdt: + .long 0x0 + .long 0x0 + .long 0x0000ffff + .long 0x00ef9a00 + .long 0x0000ffff + .long 0x00cf9200 + +.section .boot.bss + + .align 16 + .skip 512, 0 + __boot_stack_top: + +.section .boot.bss + + .align 4096 + _tmp_l0: + .skip 4096 + _tmp_l1: + .skip 4096 + +.section .boot.text + .global start_ + .type start_, @function + + start_: + .code32 + cld + cli + + movl $__boot_stack_top, %esp + pushl $0 + pushl %ebx + + # first, setup a simple initial page table + # to enable transition to IA32e + + # L0 linkage to L1, RWX + movl $0x3, %eax + movl $_tmp_l1, %ebx + orl %eax, %ebx + movl %ebx, _tmp_l0 + xorl %ebx, %ebx + movl %ebx, _tmp_l0 + 4 + + # Entry 0 + orl $(1 << 7), %eax + movl %eax, _tmp_l1 + movl %ebx, _tmp_l1 + 4 + + # Entry 1 + addl $0x40000000, %eax + movl %eax, _tmp_l1 + 8 + movl %ebx, _tmp_l1 + 12 + + # Entry 2 + addl $0x40000000, %eax + movl %eax, _tmp_l1 + 16 + movl %ebx, _tmp_l1 + 20 + + # Entry 3 + addl $0x40000000, %eax + movl %eax, _tmp_l1 + 24 + movl %ebx, _tmp_l1 + 28 + + movl $_tmp_l0, %eax + movl %eax, %cr3 + + # now, commencing transition + + movl %cr4, %eax + orl $(1 << 5), %eax # PAE + movl %eax, %cr4 + + movl $0xc0000080, %ecx + rdmsr + orl $(1 << 8), %eax # IA32_EFER.LME + orl $(1 << 11), %eax # IA32_EFER.NXE + wrmsr + + movl %cr0, %eax + orl $(1 << 31), %eax # PG + movl %eax, %cr0 + + jmp _ia32e_compat + + # clear the pipeline, + # although cpu might already cleared for us upon mode switching + .nop + .nop + .nop + .nop + + # x86_64 compatibility mode + # load a temporary gdt for getting into long mode + _ia32e_compat: + .code32 + subl $16, %esp + movl $__tmp_gdt, 2(%esp) + movw $23, (%esp) + lgdtl (%esp) + + addl $16, %esp + + # do a far jump to switch cs + pushl $0x08 + pushl $_ia32e + retf + + _ia32e: + .code64 + movw $0x10, %cx + movw %cx, %ds + movw %cx, %ss + + popq %rbx + movq %rbx, %rdi + call x86_init + + movabsq $hhk_entry_, %rax + pushq %rax + retq \ No newline at end of file diff --git a/lunaix-os/arch/x86/boot/x86_64/init64.c b/lunaix-os/arch/x86/boot/x86_64/init64.c new file mode 100644 index 0000000..bab0173 --- /dev/null +++ b/lunaix-os/arch/x86/boot/x86_64/init64.c @@ -0,0 +1,17 @@ +#include "sys/boot/archinit.h" +#include "sys/crx.h" +#include "sys/cpu.h" + +void boot_text +x86_init(struct multiboot_info* mb) +{ + mb_parse(mb); + + cr4_setfeature(CR4_PCIDE); + + ptr_t pagetable = kpg_init(); + cpu_chvmspace(pagetable); + + cr0_unsetfeature(CR0_WP | CR0_EM); + cr0_setfeature(CR0_MP); +} \ No newline at end of file diff --git a/lunaix-os/arch/x86/boot/x86_64/kremap64.c b/lunaix-os/arch/x86/boot/x86_64/kremap64.c new file mode 100644 index 0000000..ee9d298 --- /dev/null +++ b/lunaix-os/arch/x86/boot/x86_64/kremap64.c @@ -0,0 +1,188 @@ +#define __BOOT_CODE__ + +#include +#include + +#include +#include + +#define RSVD_PAGES 32 + +bridge_farsym(__kexec_start); +bridge_farsym(__kexec_end); +bridge_farsym(__kexec_text_start); +bridge_farsym(__kexec_text_end); + +// define the initial page table layout +struct kernel_map; + +static struct kernel_map kpt __section(".kpg"); +export_symbol(debug, boot, kpt); + +struct kernel_map { + pte_t l0t[_PAGE_LEVEL_SIZE]; // root table + pte_t l1t_rsvd[_PAGE_LEVEL_SIZE]; // 0~4G reservation + + struct { + pte_t _lft[_PAGE_LEVEL_SIZE]; + } krsvd[RSVD_PAGES]; +} align(8); + +struct allocator +{ + struct kernel_map* kpt_pa; + int pt_usage; +}; + +static inline ptr_t +alloc_rsvd_page(struct allocator* _alloc) +{ + if (_alloc->pt_usage >= KEXEC_RSVD) { + asm ("ud2"); + } + + return __ptr(&_alloc->kpt_pa->krsvd[_alloc->pt_usage++]); +} + +static pte_t* boot_text +prealloc_pt(struct allocator* _allc, ptr_t va, + pte_attr_t prot, size_t to_gran) +{ + int lvl_i; + pte_t *ptep, pte; + size_t gran = L0T_SIZE; + + ptep = (pte_t*)&_allc->kpt_pa->l0t[0]; + + for (int i = 0; i < _PTW_LEVEL && gran > to_gran; i++) + { + lvl_i = va_level_index(va, gran); + ptep = &ptep[lvl_i]; + pte = pte_at(ptep); + + gran = gran >> _PAGE_LEVEL_SHIFT; + + if (pte_isnull(pte)) { + pte = mkpte(alloc_rsvd_page(_allc), KERNEL_DATA); + if (to_gran == gran) { + pte = pte_setprot(pte, prot); + } + + set_pte(ptep, pte); + } + ptep = (pte_t*) pte_paddr(pte); + } + + return ptep; +} + +static void boot_text +do_remap() +{ + struct kernel_map* kpt_pa = (struct kernel_map*)to_kphysical(&kpt); + + pte_t* boot_l0tep = (pte_t*) kpt_pa; + pte_t *klptep, pte; + + // identity map the first 4G for legacy compatibility + pte_t* l1_rsvd = (pte_t*) kpt_pa->l1t_rsvd; + pte_t id_map = pte_mkhuge(mkpte_prot(KERNEL_DATA)); + + set_pte(boot_l0tep, mkpte((ptr_t)l1_rsvd, KERNEL_DATA)); + + for (int i = 0; i < 4; i++, l1_rsvd++) + { + id_map = pte_setpaddr(id_map, (ptr_t)i << 30); + set_pte(l1_rsvd, id_map); + } + + // Remap the kernel to -2GiB + + int table_usage = 0; + unsigned int lvl_i = 0; + struct allocator alloc = { + .kpt_pa = kpt_pa, + .pt_usage = 0 + }; + + prealloc_pt(&alloc, VMAP, KERNEL_DATA, L1T_SIZE); + + prealloc_pt(&alloc, PG_MOUNT_1, KERNEL_DATA, LFT_SIZE); + + + ptr_t kstart = page_aligned(__far(__kexec_text_start)); + +#if LnT_ENABLED(3) + size_t gran = L3T_SIZE; +#else + size_t gran = L2T_SIZE; +#endif + + prealloc_pt(&alloc, PMAP, KERNEL_DATA, gran); + klptep = prealloc_pt(&alloc, kstart, KERNEL_DATA, gran); + klptep += va_level_index(kstart, gran); + + pte = mkpte(0, KERNEL_DATA); + for (int i = alloc.pt_usage; i < KEXEC_RSVD; i++) + { + pte = pte_setpaddr(pte, (ptr_t)&kpt_pa->krsvd[i]); + set_pte(klptep++, pte); + } + + // this is the first LFT we hooked on. + // all these LFT are contig in physical address + klptep = (pte_t*) &kpt_pa->krsvd[alloc.pt_usage]; + + // Ensure the size of kernel is within the reservation + int remain = KEXEC_RSVD - table_usage; + pfn_t kimg_pagecount = + pfn(__far(__kexec_end) - __far(__kexec_start)); + if (kimg_pagecount > remain * _PAGE_LEVEL_SIZE) { + // ERROR: require more pages + // here should do something else other than head into blocking + asm("ud2"); + } + + // kernel .text + pfn_t ktext_end = pfn(to_kphysical(__far(__kexec_text_end))); + pfn_t i = pfn(to_kphysical(kstart)); + + klptep += i; + pte = pte_setprot(pte, KERNEL_EXEC); + for (; i < ktext_end; i++) { + pte = pte_setpaddr(pte, page_addr(i)); + set_pte(klptep, pte); + + klptep++; + } + + pfn_t kimg_end = pfn(to_kphysical(__far(__kexec_end))); + + // all remaining kernel sections + pte = pte_setprot(pte, KERNEL_DATA); + for (; i < kimg_end; i++) { + pte = pte_setpaddr(pte, page_addr(i)); + set_pte(klptep, pte); + + klptep++; + } + + // Build up self-reference + lvl_i = va_level_index(VMS_SELF, L0T_SIZE); + pte = mkpte_root(__ptr(kpt_pa), KERNEL_DATA); + set_pte(boot_l0tep + lvl_i, pte); +} + + +ptr_t boot_text +remap_kernel() +{ + ptr_t kmap_pa = to_kphysical(&kpt); + for (size_t i = 0; i < sizeof(kpt); i++) { + ((u8_t*)kmap_pa)[i] = 0; + } + + do_remap(); + + return kmap_pa; +} \ No newline at end of file diff --git a/lunaix-os/arch/x86/boot/x86_64/prologue64.S b/lunaix-os/arch/x86/boot/x86_64/prologue64.S new file mode 100644 index 0000000..06b2b94 --- /dev/null +++ b/lunaix-os/arch/x86/boot/x86_64/prologue64.S @@ -0,0 +1,73 @@ +/* 高半核入口点 - 0xC0000000 */ + +#define __ASM__ +#include +#include + +.section .bss.kstack + .global __kinit_stack_end + + .align 16 + __kinit_stack_end: + .skip 2048, 0 + __kinit_stack_top: + + +.section .text + .global hhk_entry_ + hhk_entry_: + + movq $__kinit_stack_top, %rsp + andq $stack_alignment, %rsp + + movq $__kinit_stack_end, %rax + movl $STACK_SANITY, (%rax) + movl $STACK_SANITY, 4(%rax) + movl $STACK_SANITY, 8(%rax) + movl $STACK_SANITY, 12(%rax) + + andq $stack_alignment, %rsp + subq $16, %rsp + + # replace the temporary gdt + call _init_gdt + + movq $_gdt, 2(%rsp) + movw _gdt_limit, %ax + movw %ax, (%rsp) + lgdt (%rsp) + + # do a far jump to switch cs + pushq $KCODE_SEG + pushq $_after_gdt + retfq + + _after_gdt: + + # initialize segment registers + # we will not touch them again in x86_64 + movw $KDATA_SEG, %cx + movw %cx, %es + movw %cx, %ds + movw %cx, %ss + + # perform arch-specific initialization before diving into kernel + call arch_preinit + + # 加载 IDT + movq $_idt, 2(%rsp) + movw _idt_limit, %ax + movw %ax, (%rsp) + lidt (%rsp) + + /* 加载TSS段选择器 */ + movw $TSS_SEG, %ax + ltr %ax + + xorq %rbp, %rbp + movq $bhctx_buffer, %rdi # mb_parser.c + call kernel_bootstrap + + 1: + hlt + jmp 1b \ No newline at end of file diff --git a/lunaix-os/arch/i386/exceptions/interrupt.S b/lunaix-os/arch/x86/exceptions/interrupt32.S similarity index 97% rename from lunaix-os/arch/i386/exceptions/interrupt.S rename to lunaix-os/arch/x86/exceptions/interrupt32.S index 8d82d10..58c033a 100644 --- a/lunaix-os/arch/i386/exceptions/interrupt.S +++ b/lunaix-os/arch/x86/exceptions/interrupt32.S @@ -1,10 +1,11 @@ #define __ASM__ #include #include -#include +#include #include +#define tss_esp0_off 4 #define __ASM_INTR_DIAGNOSIS #ifdef __ASM_INTR_DIAGNOSIS @@ -38,7 +39,7 @@ interrupt_wrapper: cld - subl $4, %esp + subl $4, %esp # prealloc slot for parent linkage pushl %esp subl $16, %esp @@ -195,9 +196,10 @@ 由于这中间没有进行地址空间的交换,所以第二次跳转使用的是同一个内核栈,而之前默认tss.esp0的值是永远指向最顶部 这样一来就有可能会覆盖更早的上下文信息(比如嵌套的信号捕获函数) */ - movl thread_hstate(%ebx), %ecx # __current->hstate - movl %ecx, (tss_esp0_off + _tss) + pushl %eax + call update_tss + popl %eax jmp handle_signal 1: diff --git a/lunaix-os/arch/x86/exceptions/interrupt64.S b/lunaix-os/arch/x86/exceptions/interrupt64.S new file mode 100644 index 0000000..2b15410 --- /dev/null +++ b/lunaix-os/arch/x86/exceptions/interrupt64.S @@ -0,0 +1,204 @@ +#define __ASM__ +#include +#include +#include + +#include + +.section .bss + .align 16 + tmp_store: + .skip 8 + lo_tmp_stack: + .skip 256 + tmp_stack: + + +/* + This perhaps the ugliest part in the project. + It contains code to handle arbitrary depth of + nested interrupt and all those corner cases and + nasty gotchas. + + Be aware the twists, offsets and hidden dependencies! + +*/ + +.section .text + .type interrupt_wrapper, @function + .global interrupt_wrapper + interrupt_wrapper: + cld + + subq $8, %rsp + pushq %rsp + + pushq %r15 + pushq %r14 + pushq %r13 + pushq %r12 + pushq %r11 + pushq %r10 + pushq %r9 + pushq %r8 + + pushq %rsi + pushq %rbp + pushq %rdi + pushq %rdx + pushq %rcx + pushq %rbx + pushq %rax + + pushq $0 // placeholder for depth accounting + + movq ics(%rsp), %rax /* 取出 %cs */ + andq $0x3, %rax /* 判断 RPL */ + jz 1f + + /* crossing the user/kernel boundary */ + # x86_64 ignore {d,e}s, Lunaix does not use {f,g}s + + movq current_thread, %rbx + movq iursp(%rsp), %rax + + # Save x87 context to user stack, rather than kernel's memory. + # XXX what will happen if we triggered a page fault during fxsave? + # FIXME I think we should defer this to scheduler, and pratice lazy save/load + # Doing this will also make it safe from nested interrupt due to potential + # page fault when saving + # FIXME Also, generalise it to any FPU context, without constraining it to x87. + + #andl $stack_alignment, %eax + #subl $512, %eax + #fxsave (%eax) + + # 保存用户栈顶指针。因为我们允许同级中断的产生,所以需要该手段跟踪用户栈的地址。 + movq %rax, thread_ustack_top(%rbx) # 存入__current->ustack_top + + /* kernel space same-level switch */ + 1: + movq %rsp, %rax + andq $stack_alignment, %rsp + + movq %rax, %rdi + + xorq %rbp, %rbp # marks the boundary of stack walking + call intr_handler + + .global soft_iret + soft_iret: + movq %rax, %rsp + + movq ics(%rsp), %rax + andq $3, %rax + jz 1f + + # # FIXME x87 fpu context + # movl current_thread, %eax + # movl thread_ustack_top(%eax), %eax + # test %eax, %eax + # jz 1f + # fxrstor (%eax) + +1: + popq %rax # discard struct hart_state::depth + + popq %rax + popq %rbx + popq %rcx + popq %rdx + popq %rdi + popq %rbp + popq %rsi + + popq %r8 + popq %r9 + popq %r10 + popq %r11 + popq %r12 + popq %r13 + popq %r14 + popq %r15 + + popq %rsp + + movq %rax, tmp_store + movq current_thread, %rax + + # nested intr: restore saved context + popq thread_hstate(%rax) + + movq tmp_store, %rax + + addq $16, %rsp # skip: err_code and vector + + # calculate stack after iretq + # Thank god they finally make things consistent in x86_64 + addq $40, %rsp + movq %rsp, (_tss + rsp_0) + subq $40, %rsp + + iretq + + .type do_switch, @function + .global do_switch + do_switch: + # Assumption: __current already hold the target process + + call proc_vmroot + + movq %rax, %rbx + movq %cr3, %rax + xorq %rbx, %rax # avoid setting cr3 if just local thread switch. + jz 1f + + movq %rbx, %cr3 + + 1: + # the address space could be changed. A temporary stack + # is required to prevent corrupt existing stack + movq $tmp_stack, %rsp + + call signal_dispatch # kernel/signal.c + + movq current_thread, %rbx + test %rax, %rax # do we have signal to handle? + jz 1f + + /* + 将tss.esp0设置为上次调度前的esp值。 + 当处理信号时,上下文信息是不会恢复的,而是保存在用户栈中,然后直接跳转进位于用户空间的sig_wrapper进行 + 信号的处理。当用户自定义的信号处理函数返回时,sigreturn的系统调用才开始进行上下文的恢复(或者说是进行 + 另一次调度。 + 由于这中间没有进行地址空间的交换,所以第二次跳转使用的是同一个内核栈,而之前默认tss.esp0的值是永远指向最顶部 + 这样一来就有可能会覆盖更早的上下文信息(比如嵌套的信号捕获函数) + */ + pushq %rax + call update_tss + + popq %rax + jmp handle_signal + + 1: + movq thread_hstate(%rbx), %rax + jmp soft_iret + + .type handle_signal, @function + .global handle_signal + handle_signal: + # 注意1:任何对proc_sig的布局改动,都须及时的保证这里的一致性! + # 注意2:handle_signal在调用之前,须确保proc_sig已经写入用户栈! + # arg1 in %rax: addr of proc_sig structure in user stack + movq psig_saved_hstate(%rax), %rbx # %rbx = &proc_sig->saved_hstate + + pushq $UDATA_SEG + pushq %rax # esp + + movq iexecp(%rbx), %rbx + pushq exrflags(%rbx) # proc_sig->saved_hstate->execp->eflags + + pushq $UCODE_SEG # cs + pushq psig_sigact(%rax) # %rip = proc_sig->sigact + + iretq \ No newline at end of file diff --git a/lunaix-os/arch/i386/exceptions/interrupts.c b/lunaix-os/arch/x86/exceptions/interrupts.c similarity index 82% rename from lunaix-os/arch/i386/exceptions/interrupts.c rename to lunaix-os/arch/x86/exceptions/interrupts.c index d7eced3..9d127ba 100644 --- a/lunaix-os/arch/i386/exceptions/interrupts.c +++ b/lunaix-os/arch/x86/exceptions/interrupts.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include "sys/x86_isa.h" @@ -29,7 +29,7 @@ update_thread_context(struct hart_state* state) } } -void +struct hart_state* intr_handler(struct hart_state* state) { update_thread_context(state); @@ -41,17 +41,11 @@ intr_handler(struct hart_state* state) goto done; } - ERROR("INT %u: (%x) [%p: %p] Unknown", - execp->vector, - execp->err_code, - execp->cs, - execp->eip); - done: if (execp->vector > IV_BASE_END) { isrm_notify_eoi(0, execp->vector); } - return; + return state; } \ No newline at end of file diff --git a/lunaix-os/arch/i386/exceptions/intr_routines.c b/lunaix-os/arch/x86/exceptions/intr_routines.c similarity index 93% rename from lunaix-os/arch/i386/exceptions/intr_routines.c rename to lunaix-os/arch/x86/exceptions/intr_routines.c index ddd06a8..05f547e 100644 --- a/lunaix-os/arch/i386/exceptions/intr_routines.c +++ b/lunaix-os/arch/x86/exceptions/intr_routines.c @@ -11,7 +11,7 @@ #include #include "sys/apic.h" -#include +#include LOG_MODULE("INTR") @@ -42,7 +42,11 @@ intr_routine_general_protection(const struct hart_state* state) void intr_routine_sys_panic(const struct hart_state* state) { +#ifdef CONFIG_ARCH_X86_64 + __print_panic_msg((char*)(state->registers.rdi), state); +#else __print_panic_msg((char*)(state->registers.edi), state); +#endif } void diff --git a/lunaix-os/arch/i386/exceptions/intrhnds.S b/lunaix-os/arch/x86/exceptions/intrhnds.S similarity index 96% rename from lunaix-os/arch/i386/exceptions/intrhnds.S rename to lunaix-os/arch/x86/exceptions/intrhnds.S index e5fe775..f46e58d 100644 --- a/lunaix-os/arch/i386/exceptions/intrhnds.S +++ b/lunaix-os/arch/x86/exceptions/intrhnds.S @@ -1,9 +1,11 @@ -/* Generated from i386_intrhnds.S.j2. Do NOT modify */ +/* Generated from int_handlerhnds.S.j2. Do NOT modify */ #define __ASM__ +#ifdef CONFIG_ARCH_I386 .macro isr_template vector, no_error_code=1 .global _asm_isr\vector .type _asm_isr\vector, @function + .align 16 _asm_isr\vector: .if \no_error_code pushl $0x0 @@ -11,6 +13,20 @@ pushl $\vector jmp interrupt_wrapper .endm +#else +.macro isr_template vector, no_error_code=1 + .global _asm_isr\vector + .type _asm_isr\vector, @function + .align 16 + _asm_isr\vector: + .if \no_error_code + pushq $0x0 + .endif + pushq $\vector + jmp interrupt_wrapper +.endm +#endif + .section .text isr_template 0, no_error_code=1 isr_template 1, no_error_code=1 diff --git a/lunaix-os/arch/x86/exceptions/isrdef.c b/lunaix-os/arch/x86/exceptions/isrdef.c new file mode 100644 index 0000000..23c80b0 --- /dev/null +++ b/lunaix-os/arch/x86/exceptions/isrdef.c @@ -0,0 +1,67 @@ +/* Generated from i386_isrdef.c.j2. Do NOT modify */ + +#include +#include "sys/int_handler.h" +#include "sys/vectors.h" +#include "sys/x86_isa.h" + +#define IDT_INTERRUPT 0x70 +#define IDT_ATTR(dpl, type) (((type) << 5) | ((dpl & 3) << 13) | (1 << 15)) +#define IDT_ENTRY 256 + +#define __expand_iv(iv) _asm_isr##iv() +#define DECLARE_ISR(iv) extern void __expand_iv(iv); + +#ifndef CONFIG_ARCH_X86_64 + +static inline void +install_idte(struct x86_sysdesc* idt, int iv, ptr_t isr, int dpl) +{ + struct x86_sysdesc* idte = &idt[iv]; + + idte->hi = ((ptr_t)isr & 0xffff0000) | IDT_ATTR(dpl, IDT_INTERRUPT); + idte->lo = (KCODE_SEG << 16) | ((ptr_t)isr & 0x0000ffff); +} +struct x86_sysdesc _idt[IDT_ENTRY]; +u16_t _idt_limit = sizeof(_idt) - 1; + +#else + +static inline must_inline void +install_idte(struct x86_sysdesc* idt, int iv, ptr_t isr, int dpl) +{ + struct x86_sysdesc* idte = &idt[iv]; + + idte->hi = isr >> 32; + + idte->lo = (isr & 0xffff0000UL) | IDT_ATTR(dpl, IDT_INTERRUPT); + + idte->lo <<= 32; + idte->lo |= (KCODE_SEG << 16) | (isr & 0x0000ffffUL); +} + +struct x86_sysdesc _idt[IDT_ENTRY]; +u16_t _idt_limit = sizeof(_idt) - 1; + +#endif + +DECLARE_ISR(0) +DECLARE_ISR(33) + +void +exception_install_handler() +{ + ptr_t start = (ptr_t)_asm_isr0; + + for (int i = 0; i < 256; i++) { + install_idte(_idt, i, start, 0); + start += 16; + } + + install_idte(_idt, 33, (ptr_t)_asm_isr33, 3); + +#ifdef CONFIG_ARCH_X86_64 + // TODO set different IST to some exception so it can get a + // better and safe stack to work with +#endif +} \ No newline at end of file diff --git a/lunaix-os/arch/i386/exceptions/i386_isrm.c b/lunaix-os/arch/x86/exceptions/isrm.c similarity index 100% rename from lunaix-os/arch/i386/exceptions/i386_isrm.c rename to lunaix-os/arch/x86/exceptions/isrm.c diff --git a/lunaix-os/arch/x86/exec/elf32.c b/lunaix-os/arch/x86/exec/elf32.c new file mode 100644 index 0000000..f3bd47f --- /dev/null +++ b/lunaix-os/arch/x86/exec/elf32.c @@ -0,0 +1,13 @@ +#include + +#define EM_386 3 + +int +elf_check_arch(const struct elf* elf) +{ + const struct elf_ehdr* ehdr = &elf->eheader; + + return *(u32_t*)(ehdr->e_ident) == ELFMAGIC_LE && + ehdr->e_ident[EI_CLASS] == ELFCLASS32 && + ehdr->e_ident[EI_DATA] == ELFDATA2LSB && ehdr->e_machine == EM_386; +} \ No newline at end of file diff --git a/lunaix-os/arch/x86/exec/elf64.c b/lunaix-os/arch/x86/exec/elf64.c new file mode 100644 index 0000000..4bc9058 --- /dev/null +++ b/lunaix-os/arch/x86/exec/elf64.c @@ -0,0 +1,14 @@ +#include + +#define EM_X86_64 62 + +int +elf_check_arch(const struct elf* elf) +{ + const struct elf_ehdr* ehdr = &elf->eheader; + + return *(u32_t*)(ehdr->e_ident) == ELFMAGIC_LE && + ehdr->e_ident[EI_CLASS] == ELFCLASS64 && + ehdr->e_ident[EI_DATA] == ELFDATA2LSB && + ehdr->e_machine == EM_X86_64; +} \ No newline at end of file diff --git a/lunaix-os/arch/x86/exec/exec.c b/lunaix-os/arch/x86/exec/exec.c new file mode 100644 index 0000000..81ad0ec --- /dev/null +++ b/lunaix-os/arch/x86/exec/exec.c @@ -0,0 +1,23 @@ +#include +#include +#include + +int +exec_arch_prepare_entry(struct thread* thread, struct exec_host* container) +{ + struct hart_state* hstate; + + hstate = thread->hstate; + +#ifdef CONFIG_ARCH_X86_64 + hstate->execp->rip = container->exe.entry; + hstate->execp->rsp = container->stack_top; + +#else + hstate->execp->eip = container->exe.entry; + hstate->execp->esp = container->stack_top; + +#endif + + return 0; +} \ No newline at end of file diff --git a/lunaix-os/arch/i386/failsafe.S b/lunaix-os/arch/x86/failsafe.S similarity index 100% rename from lunaix-os/arch/i386/failsafe.S rename to lunaix-os/arch/x86/failsafe.S diff --git a/lunaix-os/arch/i386/gdbstub.c b/lunaix-os/arch/x86/gdbstub.c similarity index 92% rename from lunaix-os/arch/i386/gdbstub.c rename to lunaix-os/arch/x86/gdbstub.c index 78c3165..d7d131a 100644 --- a/lunaix-os/arch/i386/gdbstub.c +++ b/lunaix-os/arch/x86/gdbstub.c @@ -21,11 +21,12 @@ void arch_gdbstub_save_regs(struct gdb_state* state, struct hart_state* hstate) { /* Load Registers */ +#ifndef CONFIG_ARCH_X86_64 state->registers[GDB_CPU_I386_REG_EAX] = hstate->registers.eax; state->registers[GDB_CPU_I386_REG_ECX] = hstate->registers.ecx; state->registers[GDB_CPU_I386_REG_EDX] = hstate->registers.edx; state->registers[GDB_CPU_I386_REG_EBX] = hstate->registers.ebx; - state->registers[GDB_CPU_I386_REG_ESP] = hstate->esp; + state->registers[GDB_CPU_I386_REG_ESP] = hstate->sp; state->registers[GDB_CPU_I386_REG_EBP] = hstate->registers.ebp; state->registers[GDB_CPU_I386_REG_ESI] = hstate->registers.esi; state->registers[GDB_CPU_I386_REG_EDI] = hstate->registers.edi; @@ -37,17 +38,21 @@ arch_gdbstub_save_regs(struct gdb_state* state, struct hart_state* hstate) state->registers[GDB_CPU_I386_REG_ES] = hstate->registers.es; state->registers[GDB_CPU_I386_REG_FS] = hstate->registers.fs; state->registers[GDB_CPU_I386_REG_GS] = hstate->registers.gs; +#else + // TODO +#endif } void arch_gdbstub_restore_regs(struct gdb_state* state, struct hart_state* hstate) { /* Restore Registers */ +#ifndef CONFIG_ARCH_X86_64 hstate->registers.eax = state->registers[GDB_CPU_I386_REG_EAX]; hstate->registers.ecx = state->registers[GDB_CPU_I386_REG_ECX]; hstate->registers.edx = state->registers[GDB_CPU_I386_REG_EDX]; hstate->registers.ebx = state->registers[GDB_CPU_I386_REG_EBX]; - hstate->esp = state->registers[GDB_CPU_I386_REG_ESP]; + hstate->sp = state->registers[GDB_CPU_I386_REG_ESP]; hstate->registers.ebp = state->registers[GDB_CPU_I386_REG_EBP]; hstate->registers.esi = state->registers[GDB_CPU_I386_REG_ESI]; hstate->registers.edi = state->registers[GDB_CPU_I386_REG_EDI]; @@ -59,6 +64,9 @@ arch_gdbstub_restore_regs(struct gdb_state* state, struct hart_state* hstate) hstate->registers.es = state->registers[GDB_CPU_I386_REG_ES]; hstate->registers.fs = state->registers[GDB_CPU_I386_REG_FS]; hstate->registers.gs = state->registers[GDB_CPU_I386_REG_GS]; +#else + // TODO +#endif } diff --git a/lunaix-os/arch/i386/hal/LBuild b/lunaix-os/arch/x86/hal/LBuild similarity index 100% rename from lunaix-os/arch/i386/hal/LBuild rename to lunaix-os/arch/x86/hal/LBuild diff --git a/lunaix-os/arch/i386/hal/apic.c b/lunaix-os/arch/x86/hal/apic.c similarity index 100% rename from lunaix-os/arch/i386/hal/apic.c rename to lunaix-os/arch/x86/hal/apic.c diff --git a/lunaix-os/arch/i386/hal/apic_timer.c b/lunaix-os/arch/x86/hal/apic_timer.c similarity index 100% rename from lunaix-os/arch/i386/hal/apic_timer.c rename to lunaix-os/arch/x86/hal/apic_timer.c diff --git a/lunaix-os/arch/i386/hal/apic_timer.h b/lunaix-os/arch/x86/hal/apic_timer.h similarity index 100% rename from lunaix-os/arch/i386/hal/apic_timer.h rename to lunaix-os/arch/x86/hal/apic_timer.h diff --git a/lunaix-os/arch/i386/hal/cpu.c b/lunaix-os/arch/x86/hal/cpu.c similarity index 100% rename from lunaix-os/arch/i386/hal/cpu.c rename to lunaix-os/arch/x86/hal/cpu.c diff --git a/lunaix-os/arch/i386/hal/ioapic.c b/lunaix-os/arch/x86/hal/ioapic.c similarity index 100% rename from lunaix-os/arch/i386/hal/ioapic.c rename to lunaix-os/arch/x86/hal/ioapic.c diff --git a/lunaix-os/arch/i386/hal/mc146818a.c b/lunaix-os/arch/x86/hal/mc146818a.c similarity index 100% rename from lunaix-os/arch/i386/hal/mc146818a.c rename to lunaix-os/arch/x86/hal/mc146818a.c diff --git a/lunaix-os/arch/i386/hal/pic.h b/lunaix-os/arch/x86/hal/pic.h similarity index 100% rename from lunaix-os/arch/i386/hal/pic.h rename to lunaix-os/arch/x86/hal/pic.h diff --git a/lunaix-os/arch/i386/hal/ps2kbd.c b/lunaix-os/arch/x86/hal/ps2kbd.c similarity index 100% rename from lunaix-os/arch/i386/hal/ps2kbd.c rename to lunaix-os/arch/x86/hal/ps2kbd.c diff --git a/lunaix-os/arch/i386/hal/rngx86.c b/lunaix-os/arch/x86/hal/rngx86.c similarity index 64% rename from lunaix-os/arch/i386/hal/rngx86.c rename to lunaix-os/arch/x86/hal/rngx86.c index b108740..0d48d44 100644 --- a/lunaix-os/arch/i386/hal/rngx86.c +++ b/lunaix-os/arch/x86/hal/rngx86.c @@ -6,14 +6,31 @@ static inline void rng_fill(void* data, size_t len) { +#ifdef CONFIG_ARCH_X86_64 + asm volatile("1:\n" + "rdrand %%rax\n" + "movq %%rax, (%0)\n" + "addq $8, %%rax\n" + "subq $8, %1\n" + "jnz 1b" + :: + "r"((ptr_t)data), + "r"((len & ~0x7)) + : + "%eax"); +#else asm volatile("1:\n" "rdrand %%eax\n" "movl %%eax, (%0)\n" "addl $4, %%eax\n" "subl $4, %1\n" - "jnz 1b" ::"r"((ptr_t)data), + "jnz 1b" + :: + "r"((ptr_t)data), "r"((len & ~0x3)) - : "%eax"); + : + "%eax"); +#endif } static int @@ -26,9 +43,9 @@ __rand_rd_pg(struct device* dev, void* buf, size_t offset) static int __rand_rd(struct device* dev, void* buf, size_t offset, size_t len) { - if (unlikely(len < 4)) { + if (unlikely(len < sizeof(ptr_t))) { int tmp_buf = 0; - rng_fill(&tmp_buf, 4); + rng_fill(&tmp_buf, sizeof(ptr_t)); memcpy(buf, &tmp_buf, len); } else { rng_fill(buf, len); diff --git a/lunaix-os/arch/x86/hart.c b/lunaix-os/arch/x86/hart.c new file mode 100644 index 0000000..124ea6e --- /dev/null +++ b/lunaix-os/arch/x86/hart.c @@ -0,0 +1,22 @@ +#include +#include +#include + +#include + +bool +install_hart_transition(ptr_t vm_mnt, struct hart_transition* ht) +{ + pte_t pte; + if (!vmm_lookupat(vm_mnt, ht->inject, &pte)) { + return false; + } + + mount_page(PG_MOUNT_4, pte_paddr(pte)); + + ptr_t mount_inject = PG_MOUNT_4 + va_offset(ht->inject); + memcpy((void*)mount_inject, &ht->transfer, sizeof(ht->transfer)); + + unmount_page(PG_MOUNT_4); + return true; +} \ No newline at end of file diff --git a/lunaix-os/arch/i386/hart.c b/lunaix-os/arch/x86/hart32.c similarity index 79% rename from lunaix-os/arch/i386/hart.c rename to lunaix-os/arch/x86/hart32.c index 09bd2b3..7c34573 100644 --- a/lunaix-os/arch/i386/hart.c +++ b/lunaix-os/arch/x86/hart32.c @@ -1,3 +1,5 @@ +#ifdef CONFIG_ARCH_I386 + #include #include #include @@ -10,23 +12,6 @@ volatile struct x86_tss _tss = { .link = 0, .esp0 = 0, .ss0 = KDATA_SEG }; -bool -install_hart_transition(ptr_t vm_mnt, struct hart_transition* ht) -{ - pte_t pte; - if (!vmm_lookupat(vm_mnt, ht->inject, &pte)) { - return false; - } - - mount_page(PG_MOUNT_4, pte_paddr(pte)); - - ptr_t mount_inject = PG_MOUNT_4 + va_offset(ht->inject); - memcpy((void*)mount_inject, &ht->transfer, sizeof(ht->transfer)); - - unmount_page(PG_MOUNT_4); - return true; -} - void hart_prepare_transition(struct hart_transition* ht, ptr_t kstack_tp, ptr_t ustack_pt, @@ -57,4 +42,6 @@ hart_prepare_transition(struct hart_transition* ht, .ss = data_seg, .esp = align_stack(ustack_pt), .eflags = mstate }; -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/lunaix-os/arch/x86/hart64.c b/lunaix-os/arch/x86/hart64.c new file mode 100644 index 0000000..af9da33 --- /dev/null +++ b/lunaix-os/arch/x86/hart64.c @@ -0,0 +1,44 @@ +#ifdef CONFIG_ARCH_X86_64 + +#include +#include +#include +#include + +#include +#include + +volatile struct x86_tss _tss = { }; + +void +hart_prepare_transition(struct hart_transition* ht, + ptr_t kstack_tp, ptr_t ustack_pt, + ptr_t entry, bool to_user) +{ + ptr_t stack = ustack_pt; + ptr_t offset = (ptr_t)&ht->transfer.eret - (ptr_t)&ht->transfer; + ht->inject = align_stack(kstack_tp - sizeof(ht->transfer)); + + ht->transfer.state = (struct hart_state){ + .registers = { }, + .execp = (struct exec_param*)(ht->inject + offset) + }; + + int code_seg = KCODE_SEG, data_seg = KDATA_SEG; + int mstate = cpu_ldstate(); + if (to_user) { + code_seg = UCODE_SEG, data_seg = UDATA_SEG; + mstate |= 0x200; // enable interrupt + } + else { + stack = kstack_tp; + } + + ht->transfer.eret = (struct exec_param) { + .cs = code_seg, .rip = entry, + .ss = data_seg, .rsp = align_stack(stack), + .rflags = mstate + }; +} + +#endif \ No newline at end of file diff --git a/lunaix-os/arch/x86/includes/linking/base_defs.ld.inc b/lunaix-os/arch/x86/includes/linking/base_defs.ld.inc new file mode 100644 index 0000000..cb74045 --- /dev/null +++ b/lunaix-os/arch/x86/includes/linking/base_defs.ld.inc @@ -0,0 +1,18 @@ +#ifndef __LUNAIX_BASE_DEFS_LD_INC +#define __LUNAIX_BASE_DEFS_LD_INC + +#define __LD__ +#include + +#define KEXEC_BASE KERNEL_IMG +#define PAGE_GRAN 4K + +#define ENTRY_POINT start_ + +#ifdef CONFIG_X86_BL_MB +# define LOAD_OFF 0x100000 +#else +# error "unknown boot option, can't infer load_off" +#endif + +#endif /* __LUNAIX_BASE_DEFS_LD_INC */ diff --git a/lunaix-os/arch/x86/includes/linking/boot_secs.ldx b/lunaix-os/arch/x86/includes/linking/boot_secs.ldx new file mode 100644 index 0000000..3c71be1 --- /dev/null +++ b/lunaix-os/arch/x86/includes/linking/boot_secs.ldx @@ -0,0 +1,29 @@ +#ifndef __LUNAIX_BOOT_SECS_LD_INC +#define __LUNAIX_BOOT_SECS_LD_INC + +#include "base_defs.ld.inc" + +__kboot_start = .; + +.boot.text BLOCK(PAGE_GRAN) : +{ +#if defined(CONFIG_X86_BL_MB) || defined(CONFIG_X86_BL_MB2) + *(.multiboot) +#endif + + *(.boot.text) +} + +.boot.bss BLOCK(PAGE_GRAN) : +{ + *(.boot.bss) +} + +.boot.data BLOCK(PAGE_GRAN) : +{ + *(.boot.data) +} + +__kboot_end = ALIGN(PAGE_GRAN); + +#endif /* __LUNAIX_BOOT_SECS_LD_INC */ diff --git a/lunaix-os/arch/x86/includes/sys/abi.h b/lunaix-os/arch/x86/includes/sys/abi.h new file mode 100644 index 0000000..bfa93a7 --- /dev/null +++ b/lunaix-os/arch/x86/includes/sys/abi.h @@ -0,0 +1,33 @@ +#ifndef __LUNAIX_I386ABI_H +#define __LUNAIX_I386ABI_H + +#ifdef CONFIG_ARCH_X86_64 +# include "abi64.h" +#else +# include "abi32.h" +#endif + +#ifndef __ASM__ +#define align_stack(ptr) ((ptr) & stack_alignment) + +static inline void must_inline noret +switch_context() { + asm volatile("jmp do_switch\n"); + unreachable; +} + + +static inline ptr_t +abi_get_retaddr() +{ + return *((ptr_t*)abi_get_callframe() + 1); +} + +static inline ptr_t +abi_get_retaddrat(ptr_t fp) +{ + return *((ptr_t*)fp + 1); +} + +#endif +#endif /* __LUNAIX_ABI_H */ diff --git a/lunaix-os/arch/x86/includes/sys/abi32.h b/lunaix-os/arch/x86/includes/sys/abi32.h new file mode 100644 index 0000000..a5d3db7 --- /dev/null +++ b/lunaix-os/arch/x86/includes/sys/abi32.h @@ -0,0 +1,41 @@ +#ifndef __LUNAIX_ARCH_ABI32_H +#define __LUNAIX_ARCH_ABI32_H + +#include "sys/x86_isa.h" + +#define stack_alignment 0xfffffff0 + +#ifndef __ASM__ +#define store_retval(retval) current_thread->hstate->registers.eax = (retval) + +#define store_retval_to(th, retval) (th)->hstate->registers.eax = (retval) + +static inline void must_inline +j_usr(ptr_t sp, ptr_t pc) +{ + asm volatile("movw %0, %%ax\n" + "movw %%ax, %%es\n" + "movw %%ax, %%ds\n" + "movw %%ax, %%fs\n" + "movw %%ax, %%gs\n" + "pushl %0\n" + "pushl %1\n" + "pushl %2\n" + "pushl %3\n" + "retf" ::"i"(UDATA_SEG), + "r"(sp), + "i"(UCODE_SEG), + "r"(pc) + : "eax", "memory"); +} + +static inline ptr_t must_inline +abi_get_callframe() +{ + ptr_t val; + asm("movl %%ebp, %0" : "=r"(val)::); + return val; +} + +#endif +#endif /* __LUNAIX_ARCH_ABI32_H */ diff --git a/lunaix-os/arch/x86/includes/sys/abi64.h b/lunaix-os/arch/x86/includes/sys/abi64.h new file mode 100644 index 0000000..1c93cc1 --- /dev/null +++ b/lunaix-os/arch/x86/includes/sys/abi64.h @@ -0,0 +1,40 @@ +#ifndef __LUNAIX_ARCH_ABI64_H +#define __LUNAIX_ARCH_ABI64_H + +#include "sys/x86_isa.h" + +#define stack_alignment 0xfffffffffffffff0UL + +#ifndef __ASM__ +#define store_retval(retval) current_thread->hstate->registers.rax = (retval) + +#define store_retval_to(th, retval) (th)->hstate->registers.rax = (retval) + +static inline void must_inline +j_usr(ptr_t sp, ptr_t pc) +{ + asm volatile( + "pushq %0\n" + "pushq %1\n" + "pushq %2\n" + "pushq %3\n" + "retfq" + :: + "i"(UDATA_SEG), + "r"(sp), + "i"(UCODE_SEG), + "r"(pc) + : + "memory"); +} + +static inline ptr_t must_inline +abi_get_callframe() +{ + ptr_t val; + asm("movq %%rbp, %0" : "=r"(val)::); + return val; +} + +#endif +#endif /* __LUNAIX_ARCH_ABI64_H */ diff --git a/lunaix-os/arch/i386/includes/sys/apic.h b/lunaix-os/arch/x86/includes/sys/apic.h similarity index 100% rename from lunaix-os/arch/i386/includes/sys/apic.h rename to lunaix-os/arch/x86/includes/sys/apic.h diff --git a/lunaix-os/arch/i386/boot/archinit.h b/lunaix-os/arch/x86/includes/sys/boot/archinit.h similarity index 77% rename from lunaix-os/arch/i386/boot/archinit.h rename to lunaix-os/arch/x86/includes/sys/boot/archinit.h index b936ca1..5ac58ca 100644 --- a/lunaix-os/arch/i386/boot/archinit.h +++ b/lunaix-os/arch/x86/includes/sys/boot/archinit.h @@ -2,8 +2,8 @@ #define __LUNAIX_ARCHINIT_H #include -#include -#include +#include "bstage.h" +#include "multiboot.h" ptr_t boot_text kpg_init(); diff --git a/lunaix-os/arch/x86/includes/sys/boot/bstage.h b/lunaix-os/arch/x86/includes/sys/boot/bstage.h new file mode 100644 index 0000000..589f2a5 --- /dev/null +++ b/lunaix-os/arch/x86/includes/sys/boot/bstage.h @@ -0,0 +1,37 @@ +#ifndef __LUNAIX_BSTAGE_H +#define __LUNAIX_BSTAGE_H +#include + +#define boot_text __attribute__((section(".boot.text"))) +#define boot_data __attribute__((section(".boot.data"))) +#define boot_bss __attribute__((section(".boot.bss"))) + +/* + Bridge the far symbol to the vicinity. + + Which is a workaround for relocation + issue where symbol define in kernel + code is too far away from the boot code. +*/ +#ifdef CONFIG_ARCH_X86_64 +#define bridge_farsym(far_sym) \ + asm( \ + ".section .boot.bss\n" \ + ".align 8\n" \ + ".globl __lc_" #far_sym "\n" \ + "__lc_" #far_sym ":\n" \ + ".8byte " #far_sym "\n" \ + ".previous\n" \ + ); \ + extern unsigned long __lc_##far_sym[]; +#define __far(far_sym) (__lc_##far_sym[0]) + +#else +#define bridge_farsym(far_sym) extern u8_t far_sym[]; +#define __far(far_sym) ((ptr_t)far_sym) + +#endif + +ptr_t remap_kernel(); + +#endif /* __LUNAIX_BSTAGE_H */ diff --git a/lunaix-os/arch/i386/includes/sys/boot/multiboot.h b/lunaix-os/arch/x86/includes/sys/boot/mb.h similarity index 97% rename from lunaix-os/arch/i386/includes/sys/boot/multiboot.h rename to lunaix-os/arch/x86/includes/sys/boot/mb.h index aca8f43..6dab643 100644 --- a/lunaix-os/arch/i386/includes/sys/boot/multiboot.h +++ b/lunaix-os/arch/x86/includes/sys/boot/mb.h @@ -1,11 +1,8 @@ -#ifndef MULTIBOOT_HEADER -#define MULTIBOOT_HEADER 1 +#ifndef LUNAIX_MULTIBOOT_HEADER +#define LUNAIX_MULTIBOOT_HEADER 1 // References https://www.gnu.org/software/grub/manual/multiboot/multiboot.html -#define MULTIBOOT_MAGIC 0x1BADB002 -#define CHECKSUM(flags) -(MULTIBOOT_MAGIC + flags) - /* This should be in %eax. */ #define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 @@ -227,6 +224,5 @@ struct multiboot_apm_info }; #define MB_MMAP_ENTRY_SIZE sizeof(multiboot_memory_map_t) - #endif -#endif \ No newline at end of file +#endif diff --git a/lunaix-os/arch/x86/includes/sys/boot/mb2.h b/lunaix-os/arch/x86/includes/sys/boot/mb2.h new file mode 100644 index 0000000..390d451 --- /dev/null +++ b/lunaix-os/arch/x86/includes/sys/boot/mb2.h @@ -0,0 +1,414 @@ +/* multiboot2.h - Multiboot 2 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 LUNAIX_MULTIBOOT_HEADER +#define LUNAIX_MULTIBOOT_HEADER 1 + +/* How many bytes from the start of the file we search for the header. */ +#define MULTIBOOT_SEARCH 32768 +#define MULTIBOOT_HEADER_ALIGN 8 + +/* This should be in %eax. */ +#define MULTIBOOT_BOOTLOADER_MAGIC 0x36d76289 + +/* Alignment of multiboot modules. */ +#define MULTIBOOT_MOD_ALIGN 0x00001000 + +/* Alignment of the multiboot info structure. */ +#define MULTIBOOT_INFO_ALIGN 0x00000008 + +/* Flags set in the ’flags’ member of the multiboot header. */ + +#define MULTIBOOT_TAG_ALIGN 8 +#define MULTIBOOT_TAG_TYPE_END 0 +#define MULTIBOOT_TAG_TYPE_CMDLINE 1 +#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2 +#define MULTIBOOT_TAG_TYPE_MODULE 3 +#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4 +#define MULTIBOOT_TAG_TYPE_BOOTDEV 5 +#define MULTIBOOT_TAG_TYPE_MMAP 6 +#define MULTIBOOT_TAG_TYPE_VBE 7 +#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8 +#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9 +#define MULTIBOOT_TAG_TYPE_APM 10 +#define MULTIBOOT_TAG_TYPE_EFI32 11 +#define MULTIBOOT_TAG_TYPE_EFI64 12 +#define MULTIBOOT_TAG_TYPE_SMBIOS 13 +#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14 +#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15 +#define MULTIBOOT_TAG_TYPE_NETWORK 16 +#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17 +#define MULTIBOOT_TAG_TYPE_EFI_BS 18 +#define MULTIBOOT_TAG_TYPE_EFI32_IH 19 +#define MULTIBOOT_TAG_TYPE_EFI64_IH 20 +#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21 + +#define MULTIBOOT_HEADER_TAG_END 0 +#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1 +#define MULTIBOOT_HEADER_TAG_ADDRESS 2 +#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3 +#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4 +#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5 +#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6 +#define MULTIBOOT_HEADER_TAG_EFI_BS 7 +#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 8 +#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9 +#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10 + +#define MULTIBOOT_ARCHITECTURE_I386 0 +#define MULTIBOOT_ARCHITECTURE_MIPS32 4 +#define MULTIBOOT_HEADER_TAG_OPTIONAL 1 + +#define MULTIBOOT_LOAD_PREFERENCE_NONE 0 +#define MULTIBOOT_LOAD_PREFERENCE_LOW 1 +#define MULTIBOOT_LOAD_PREFERENCE_HIGH 2 + +#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1 +#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2 + +#ifndef __ASM__ + +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; + + /* ISA */ + multiboot_uint32_t architecture; + + /* Total header length. */ + multiboot_uint32_t header_length; + + /* The above fields plus this one must equal 0 mod 2^32. */ + multiboot_uint32_t checksum; +}; + +struct multiboot_header_tag +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; +}; + +struct multiboot_header_tag_information_request +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t requests[0]; +}; + +struct multiboot_header_tag_address +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t header_addr; + multiboot_uint32_t load_addr; + multiboot_uint32_t load_end_addr; + multiboot_uint32_t bss_end_addr; +}; + +struct multiboot_header_tag_entry_address +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t entry_addr; +}; + +struct multiboot_header_tag_console_flags +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t console_flags; +}; + +struct multiboot_header_tag_framebuffer +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t width; + multiboot_uint32_t height; + multiboot_uint32_t depth; +}; + +struct multiboot_header_tag_module_align +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; +}; + +struct multiboot_header_tag_relocatable +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t min_addr; + multiboot_uint32_t max_addr; + multiboot_uint32_t align; + multiboot_uint32_t preference; +}; + +struct multiboot_color +{ + multiboot_uint8_t red; + multiboot_uint8_t green; + multiboot_uint8_t blue; +}; + +struct multiboot_mmap_entry +{ + 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; + multiboot_uint32_t zero; +}; +typedef struct multiboot_mmap_entry multiboot_memory_map_t; + +struct multiboot_tag +{ + multiboot_uint32_t type; + multiboot_uint32_t size; +}; + +struct multiboot_tag_string +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + char string[0]; +}; + +struct multiboot_tag_module +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t mod_start; + multiboot_uint32_t mod_end; + char cmdline[0]; +}; + +struct multiboot_tag_basic_meminfo +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t mem_lower; + multiboot_uint32_t mem_upper; +}; + +struct multiboot_tag_bootdev +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t biosdev; + multiboot_uint32_t slice; + multiboot_uint32_t part; +}; + +struct multiboot_tag_mmap +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t entry_size; + multiboot_uint32_t entry_version; + struct multiboot_mmap_entry entries[0]; +}; + +struct multiboot_vbe_info_block +{ + multiboot_uint8_t external_specification[512]; +}; + +struct multiboot_vbe_mode_info_block +{ + multiboot_uint8_t external_specification[256]; +}; + +struct multiboot_tag_vbe +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + + multiboot_uint16_t vbe_mode; + multiboot_uint16_t vbe_interface_seg; + multiboot_uint16_t vbe_interface_off; + multiboot_uint16_t vbe_interface_len; + + struct multiboot_vbe_info_block vbe_control_info; + struct multiboot_vbe_mode_info_block vbe_mode_info; +}; + +struct multiboot_tag_framebuffer_common +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + + 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; + multiboot_uint16_t reserved; +}; + +struct multiboot_tag_framebuffer +{ + struct multiboot_tag_framebuffer_common common; + + union + { + struct + { + multiboot_uint16_t framebuffer_palette_num_colors; + struct multiboot_color framebuffer_palette[0]; + }; + 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; + }; + }; +}; + +struct multiboot_tag_elf_sections +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t num; + multiboot_uint32_t entsize; + multiboot_uint32_t shndx; + char sections[0]; +}; + +struct multiboot_tag_apm +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + 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; +}; + +struct multiboot_tag_efi32 +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t pointer; +}; + +struct multiboot_tag_efi64 +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint64_t pointer; +}; + +struct multiboot_tag_smbios +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t major; + multiboot_uint8_t minor; + multiboot_uint8_t reserved[6]; + multiboot_uint8_t tables[0]; +}; + +struct multiboot_tag_old_acpi +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t rsdp[0]; +}; + +struct multiboot_tag_new_acpi +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t rsdp[0]; +}; + +struct multiboot_tag_network +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t dhcpack[0]; +}; + +struct multiboot_tag_efi_mmap +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t descr_size; + multiboot_uint32_t descr_vers; + multiboot_uint8_t efi_mmap[0]; +}; + +struct multiboot_tag_efi32_ih +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t pointer; +}; + +struct multiboot_tag_efi64_ih +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint64_t pointer; +}; + +struct multiboot_tag_load_base_addr +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t load_base_addr; +}; + +#endif /* ! __ASM__ */ + +#endif /* ! MULTIBOOT_HEADER */ \ No newline at end of file diff --git a/lunaix-os/arch/x86/includes/sys/boot/multiboot.S.inc b/lunaix-os/arch/x86/includes/sys/boot/multiboot.S.inc new file mode 100644 index 0000000..061680d --- /dev/null +++ b/lunaix-os/arch/x86/includes/sys/boot/multiboot.S.inc @@ -0,0 +1,39 @@ +#define __ASM__ + +#include "multiboot.h" + +.section .multiboot +__mb_start: + .4byte MULTIBOOT_MAGIC + +#ifdef CONFIG_X86_BL_MB + #define MB_FLAGS (MULTIBOOT_MEMORY_INFO | MULTIBOOT_PAGE_ALIGN) + .4byte MB_FLAGS + .4byte -(MULTIBOOT_MAGIC + MB_FLAGS) + +#elif CONFIG_X86_BL_MB2 + #define HDR_LEN (__mb_end - __mb_start) + + .4byte 0 + .4byte HDR_LEN + .4byte -(MULTIBOOT_MAGIC + HDR_LEN) + + .align MULTIBOOT_TAG_ALIGN + __mbir_tag_start: + .2byte MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST + .2byte 0 + .4byte __mbir_tag_end - __mbir_tag_start + .4byte MULTIBOOT_TAG_TYPE_CMDLINE + .4byte MULTIBOOT_TAG_TYPE_MMAP + .4byte MULTIBOOT_TAG_TYPE_BASIC_MEMINFO + .4byte MULTIBOOT_TAG_TYPE_MODULE + __mbir_tag_end: + + .align MULTIBOOT_TAG_ALIGN + .2byte MULTIBOOT_HEADER_TAG_END + .2byte 0 + .4byte 8 + +#endif + +__mb_end: \ No newline at end of file diff --git a/lunaix-os/arch/x86/includes/sys/boot/multiboot.h b/lunaix-os/arch/x86/includes/sys/boot/multiboot.h new file mode 100644 index 0000000..72e83fc --- /dev/null +++ b/lunaix-os/arch/x86/includes/sys/boot/multiboot.h @@ -0,0 +1,14 @@ +#ifndef LUNAIX_MULTIBOOT_H +#define LUNAIX_MULTIBOOT_H 1 + +#ifdef CONFIG_X86_BL_MB +# include "mb.h" +# define MULTIBOOT_MAGIC 0x1BADB002 +#elif CONFIG_X86_BL_MB2 +# include "mb2.h" +# define MULTIBOOT_MAGIC 0xe85250d6 +#else +#error "Multiboot interfacing is not enabled" +#endif + +#endif \ No newline at end of file diff --git a/lunaix-os/arch/i386/includes/sys/cpu.h b/lunaix-os/arch/x86/includes/sys/cpu.h similarity index 77% rename from lunaix-os/arch/i386/includes/sys/cpu.h rename to lunaix-os/arch/x86/includes/sys/cpu.h index ca7080a..2889234 100644 --- a/lunaix-os/arch/i386/includes/sys/cpu.h +++ b/lunaix-os/arch/x86/includes/sys/cpu.h @@ -3,6 +3,14 @@ #include +#ifdef CONFIG_ARCH_X86_64 +# define _POP "popq " +# define _MOV "movq " +#else +# define _POP "popl " +# define _MOV "movl " +#endif + /** * @brief Get processor ID string * @@ -17,7 +25,6 @@ cpu_trap_sched(); void cpu_trap_panic(char* message); - /** * @brief Load current processor state * @@ -28,7 +35,7 @@ cpu_ldstate() { ptr_t val; asm volatile("pushf\n" - "popl %0\n" + _POP "%0\n" : "=r"(val)::); return val; } @@ -42,7 +49,7 @@ static inline reg_t cpu_ldconfig() { reg_t val; - asm volatile("movl %%cr0,%0" : "=r"(val)); + asm volatile(_MOV "%%cr0,%0" : "=r"(val)); return val; } @@ -54,7 +61,7 @@ cpu_ldconfig() static inline void cpu_chconfig(reg_t val) { - asm("mov %0, %%cr0" ::"r"(val)); + asm(_MOV "%0, %%cr0" ::"r"(val)); } /** @@ -65,9 +72,23 @@ cpu_chconfig(reg_t val) static inline void cpu_chvmspace(reg_t val) { - asm("mov %0, %%cr3" ::"r"(val)); + asm(_MOV "%0, %%cr3" ::"r"(val)); +} + +/** + * @brief Read exeception address + * + * @return ptr_t + */ +static inline ptr_t +cpu_ldeaddr() +{ + ptr_t val; + asm volatile(_MOV "%%cr2,%0" : "=r"(val)); + return val; } + static inline void cpu_enable_interrupt() { @@ -86,17 +107,4 @@ cpu_wait() asm("hlt"); } -/** - * @brief Read exeception address - * - * @return ptr_t - */ -static inline ptr_t -cpu_ldeaddr() -{ - ptr_t val; - asm volatile("movl %%cr2,%0" : "=r"(val)); - return val; -} - #endif /* __LUNAIX_CPU_H */ diff --git a/lunaix-os/arch/i386/includes/sys/crx.h b/lunaix-os/arch/x86/includes/sys/crx.h similarity index 69% rename from lunaix-os/arch/i386/includes/sys/crx.h rename to lunaix-os/arch/x86/includes/sys/crx.h index 270a897..4eb56e0 100644 --- a/lunaix-os/arch/i386/includes/sys/crx.h +++ b/lunaix-os/arch/x86/includes/sys/crx.h @@ -13,6 +13,28 @@ #define CR0_EM ( 1UL << 2 ) #define CR0_MP ( 1UL << 1 ) +#ifdef CONFIG_ARCH_X86_64 + +#define crx_addflag(crx, flag) \ + asm( \ + "movq %%" #crx ", %%rax\n" \ + "orq %0, %%rax\n" \ + "movq %%rax, %%" #crx "\n" \ + ::"r"(flag) \ + :"rax" \ + ); + +#define crx_rmflag(crx, flag) \ + asm( \ + "movq %%" #crx ", %%rax\n" \ + "andq %0, %%rax\n" \ + "movq %%rax, %%" #crx "\n" \ + ::"r"(~(flag)) \ + :"rax" \ + ); + +#else + #define crx_addflag(crx, flag) \ asm( \ "movl %%" #crx ", %%eax\n" \ @@ -31,6 +53,8 @@ :"eax" \ ); +#endif + static inline void cr4_setfeature(unsigned long feature) { diff --git a/lunaix-os/arch/x86/includes/sys/exebi/elf.h b/lunaix-os/arch/x86/includes/sys/exebi/elf.h new file mode 100644 index 0000000..1ccf84a --- /dev/null +++ b/lunaix-os/arch/x86/includes/sys/exebi/elf.h @@ -0,0 +1,69 @@ +#ifndef __LUNAIX_ARCH_ELF_H +#define __LUNAIX_ARCH_ELF_H + +#include + +#define ELFCLASS32 1 +#define ELFCLASS64 2 + +#define ELFDATA2LSB 1 +#define ELFDATA2MSB 2 + +#ifdef CONFIG_ARCH_X86_64 +typedef unsigned long elf_ptr_t; +typedef unsigned short elf_hlf_t; +typedef unsigned long elf_off_t; +typedef int elf_swd_t; +typedef unsigned int elf_wrd_t; +typedef unsigned long elf_xwrd_t; +typedef long elf_sxwrd_t; +#else +typedef unsigned int elf_ptr_t; +typedef unsigned short elf_hlf_t; +typedef unsigned int elf_off_t; +typedef unsigned int elf_swd_t; +typedef unsigned int elf_wrd_t; +#endif + +struct elf_ehdr +{ + u8_t e_ident[16]; + elf_hlf_t e_type; + elf_hlf_t e_machine; + elf_wrd_t e_version; + elf_ptr_t e_entry; + elf_off_t e_phoff; + elf_off_t e_shoff; + elf_wrd_t e_flags; + elf_hlf_t e_ehsize; + elf_hlf_t e_phentsize; + elf_hlf_t e_phnum; + elf_hlf_t e_shentsize; + elf_hlf_t e_shnum; + elf_hlf_t e_shstrndx; +}; + +struct elf_phdr +{ +#ifdef CONFIG_ARCH_X86_64 + elf_wrd_t p_type; + elf_wrd_t p_flags; + elf_off_t p_offset; + elf_ptr_t p_va; + elf_ptr_t p_pa; + elf_xwrd_t p_filesz; + elf_xwrd_t p_memsz; + elf_xwrd_t p_align; +#else + elf_wrd_t p_type; + elf_off_t p_offset; + elf_ptr_t p_va; + elf_ptr_t p_pa; + elf_wrd_t p_filesz; + elf_wrd_t p_memsz; + elf_wrd_t p_flags; + elf_wrd_t p_align; +#endif +}; + +#endif /* __LUNAIX_ARCH_ELF_H */ diff --git a/lunaix-os/arch/i386/includes/sys/failsafe.h b/lunaix-os/arch/x86/includes/sys/failsafe.h similarity index 73% rename from lunaix-os/arch/i386/includes/sys/failsafe.h rename to lunaix-os/arch/x86/includes/sys/failsafe.h index 149efd2..bf96d35 100644 --- a/lunaix-os/arch/i386/includes/sys/failsafe.h +++ b/lunaix-os/arch/x86/includes/sys/failsafe.h @@ -22,7 +22,22 @@ static inline void must_inline noret failsafe_diagnostic() { // asm ("jmp __fatal_state"); extern int failsafe_stack_top[]; - asm ( +#ifdef CONFIG_ARCH_X86_64 + asm ( + "movq %%rsp, %%rax\n" + "movq %%rbp, %%rbx\n" + + "movq %0, %%rsp\n" + + "pushq %%rax\n" + "pushq %%rbx\n" + + "call do_failsafe_unrecoverable\n" + ::"r"(failsafe_stack_top) + :"memory" + ); +#else + asm ( "movl %%esp, %%eax\n" "movl %%ebp, %%ebx\n" @@ -35,6 +50,7 @@ failsafe_diagnostic() { ::"r"(failsafe_stack_top) :"memory" ); +#endif unreachable; } diff --git a/lunaix-os/arch/i386/includes/sys/gdbstub.h b/lunaix-os/arch/x86/includes/sys/gdbstub.h similarity index 100% rename from lunaix-os/arch/i386/includes/sys/gdbstub.h rename to lunaix-os/arch/x86/includes/sys/gdbstub.h diff --git a/lunaix-os/arch/i386/includes/sys/hart.h b/lunaix-os/arch/x86/includes/sys/hart.h similarity index 61% rename from lunaix-os/arch/i386/includes/sys/hart.h rename to lunaix-os/arch/x86/includes/sys/hart.h index 9a6381a..ac3801e 100644 --- a/lunaix-os/arch/i386/includes/sys/hart.h +++ b/lunaix-os/arch/x86/includes/sys/hart.h @@ -7,8 +7,43 @@ #include #include -struct exec_param; +struct hart_state; + +#ifdef CONFIG_ARCH_X86_64 +struct regcontext +{ + reg_t rax; + reg_t rbx; + reg_t rcx; + reg_t rdx; + reg_t rdi; + reg_t rbp; + reg_t rsi; + reg_t r8; + reg_t r9; + reg_t r10; + reg_t r11; + reg_t r12; + reg_t r13; + reg_t r14; + reg_t r15; +} compact; + +struct exec_param +{ + struct hart_state* parent_state; + reg_t vector; + reg_t err_code; + reg_t rip; + reg_t cs; + reg_t rflags; + reg_t rsp; + reg_t ss; +} compact; + + +#else struct regcontext { reg_t eax; @@ -24,17 +59,6 @@ struct regcontext reg_t gs; } compact; -struct hart_state -{ - unsigned int depth; - struct regcontext registers; - union - { - reg_t esp; - volatile struct exec_param* execp; - }; -} compact; - struct exec_param { struct hart_state* parent_state; @@ -47,24 +71,54 @@ struct exec_param reg_t ss; } compact; +#endif + + +struct hart_state +{ + reg_t depth; + struct regcontext registers; + union + { + reg_t sp; + volatile struct exec_param* execp; + }; +} compact; + +static inline int +hart_vector_stamp(struct hart_state* hstate) { + return hstate->execp->vector; +} + +static inline unsigned int +hart_ecause(struct hart_state* hstate) { + return hstate->execp->err_code; +} + +static inline struct hart_state* +hart_parent_state(struct hart_state* hstate) +{ + return hstate->execp->parent_state; +} static inline void -hart_flow_redirect(struct hart_state* hstate, ptr_t pc, ptr_t sp) +hart_push_state(struct hart_state* p_hstate, struct hart_state* hstate) { - hstate->execp->eip = pc; - hstate->execp->esp = sp; + hstate->execp->parent_state = p_hstate; } + +#ifdef CONFIG_ARCH_X86_64 static inline ptr_t hart_pc(struct hart_state* hstate) { - return hstate->execp->eip; + return hstate->execp->rip; } static inline ptr_t hart_sp(struct hart_state* hstate) { - return hstate->execp->esp; + return hstate->execp->rsp; } static inline bool @@ -76,31 +130,36 @@ kernel_context(struct hart_state* hstate) static inline ptr_t hart_stack_frame(struct hart_state* hstate) { - return hstate->registers.ebp; + return hstate->registers.rbp; } -static inline int -hart_vector_stamp(struct hart_state* hstate) { - return hstate->execp->vector; +#else +static inline ptr_t +hart_pc(struct hart_state* hstate) +{ + return hstate->execp->eip; } -static inline unsigned int -hart_ecause(struct hart_state* hstate) { - return hstate->execp->err_code; +static inline ptr_t +hart_sp(struct hart_state* hstate) +{ + return hstate->execp->esp; } -static inline struct hart_state* -hart_parent_state(struct hart_state* hstate) +static inline bool +kernel_context(struct hart_state* hstate) { - return hstate->execp->parent_state; + return !((hstate->execp->cs) & 0b11); } -static inline void -hart_push_state(struct hart_state* p_hstate, struct hart_state* hstate) +static inline ptr_t +hart_stack_frame(struct hart_state* hstate) { - hstate->execp->parent_state = p_hstate; + return hstate->registers.ebp; } #endif +#endif + #endif /* __LUNAIX_ARCH_HART_H */ diff --git a/lunaix-os/arch/x86/includes/sys/int_handler.h b/lunaix-os/arch/x86/includes/sys/int_handler.h new file mode 100644 index 0000000..aac99d9 --- /dev/null +++ b/lunaix-os/arch/x86/includes/sys/int_handler.h @@ -0,0 +1,10 @@ +#ifndef __LUNAIX_INT_HANDLER_H +#define __LUNAIX_INT_HANDLER_H + +void +exception_install_handler(); + +void +intr_routine_init(); + +#endif /* __LUNAIX_INT_HANDLER_H */ diff --git a/lunaix-os/arch/i386/includes/sys/interrupt.S.inc b/lunaix-os/arch/x86/includes/sys/interrupt32.S.inc similarity index 100% rename from lunaix-os/arch/i386/includes/sys/interrupt.S.inc rename to lunaix-os/arch/x86/includes/sys/interrupt32.S.inc diff --git a/lunaix-os/arch/x86/includes/sys/interrupt64.S.inc b/lunaix-os/arch/x86/includes/sys/interrupt64.S.inc new file mode 100644 index 0000000..befb702 --- /dev/null +++ b/lunaix-os/arch/x86/includes/sys/interrupt64.S.inc @@ -0,0 +1,107 @@ + +#define regsize 8 +#define regsize32 4 + +/* stack layout: saved interrupt context */ + .struct 0 +idepth: + .struct idepth + regsize +irax: + .struct irax + regsize +irbx: + .struct irbx + regsize +ircx: + .struct ircx + regsize +irdx: + .struct irdx + regsize +irdi: + .struct irdi + regsize +irbp: + .struct irbp + regsize +irsi: + .struct irsi + regsize +ir8: + .struct ir8 + regsize +ir9: + .struct ir9 + regsize +ir10: + .struct ir10 + regsize +ir11: + .struct ir11 + regsize +ir12: + .struct ir12 + regsize +ir13: + .struct ir13 + regsize +ir14: + .struct ir14 + regsize +ir15: + .struct ir15 + regsize +iexecp: +irsp: + .struct irsp + regsize +isave_parent: + .struct isave_parent + regsize +ivec: + .struct ivec + regsize +iecode: + .struct iecode + regsize +irip: + .struct irip + regsize +ics: + .struct ics + regsize +irflags: + .struct irflags + regsize +iursp: + .struct iursp + regsize +iuss: + + +/* stack layout: execution (flow-control) state context */ + .struct 0 +exsave_prev: + .struct exsave_prev + regsize +exvec: + .struct exvec + regsize +execode: + .struct execode + regsize +exrip: + .struct exrip + regsize +excs: + .struct excs + regsize +exrflags: + .struct exrflags + regsize +exursp: + .struct exursp + regsize +exuss: + +/* struct layout: critical section of struct proc_info */ + .struct 0 +thread_hstate: + .struct thread_hstate + regsize +thread_ustack_top: + +/* struct layout: proc_sig */ + .struct 0 +psig_signum: + .struct psig_signum + regsize32 +psig_sigact: + .struct psig_sigact + regsize +psig_sighand: + .struct psig_sighand + regsize +psig_saved_hstate: + +/* struct layout: x86_tss */ + .struct 0 + .struct regsize32 +rsp_0: + .struct rsp_0 + regsize +rsp_1: + .struct rsp_1 + regsize +rsp_2: + .struct rsp_2 + regsize +rsp_3: + .struct rsp_3 + regsize +ist_null: + .struct ist_null + regsize +ist_1: + diff --git a/lunaix-os/arch/i386/includes/sys/ioapic.h b/lunaix-os/arch/x86/includes/sys/ioapic.h similarity index 100% rename from lunaix-os/arch/i386/includes/sys/ioapic.h rename to lunaix-os/arch/x86/includes/sys/ioapic.h diff --git a/lunaix-os/arch/i386/includes/sys/mm/memory.h b/lunaix-os/arch/x86/includes/sys/mm/memory.h similarity index 87% rename from lunaix-os/arch/i386/includes/sys/mm/memory.h rename to lunaix-os/arch/x86/includes/sys/mm/memory.h index a89d90a..cf9f91d 100644 --- a/lunaix-os/arch/i386/includes/sys/mm/memory.h +++ b/lunaix-os/arch/x86/includes/sys/mm/memory.h @@ -16,8 +16,8 @@ translate_vmr_prot(unsigned int vmr_prot) _pte_prot |= _PTE_W; } - if ((vmr_prot & PROT_EXEC)) { - _pte_prot |= _PTE_X; + if (!(vmr_prot & PROT_EXEC)) { + _pte_prot |= _PTE_NX; } return _pte_prot; diff --git a/lunaix-os/arch/x86/includes/sys/mm/mempart.h b/lunaix-os/arch/x86/includes/sys/mm/mempart.h new file mode 100644 index 0000000..a3ad646 --- /dev/null +++ b/lunaix-os/arch/x86/includes/sys/mm/mempart.h @@ -0,0 +1,10 @@ +#ifndef __LUNAIX_MEMPART_H +#define __LUNAIX_MEMPART_H + +#ifdef CONFIG_ARCH_X86_64 +# include "mempart64.h" +#else +# include "mempart32.h" +#endif + +#endif \ No newline at end of file diff --git a/lunaix-os/arch/x86/includes/sys/mm/mempart32.h b/lunaix-os/arch/x86/includes/sys/mm/mempart32.h new file mode 100644 index 0000000..9a81d37 --- /dev/null +++ b/lunaix-os/arch/x86/includes/sys/mm/mempart32.h @@ -0,0 +1,67 @@ +#ifndef __LUNAIX_MEMPART32_H +#define __LUNAIX_MEMPART32_H + +#define END_POINT(name) (name + name##_SIZE - 1) + +#ifdef __LD__ +#define __ulong(val) val +#else +#define __ulong(val) val##UL +#endif + +#define KSTACK_AREA __ulong(0x100000) +#define KSTACK_AREA_SIZE __ulong(0x300000) +#define KSTACK_AREA_END END_POINT(KSTACK_AREA) + +#define USR_EXEC __ulong(0x400000) +#define USR_EXEC_SIZE __ulong(0x20000000) +#define USR_EXEC_END END_POINT(USR_EXEC) + +#define USR_MMAP __ulong(0x20400000) +#define USR_MMAP_SIZE __ulong(0x9fbc0000) +#define USR_MMAP_END END_POINT(USR_MMAP) + +#define USR_STACK __ulong(0xbffc0000) +#define USR_STACK_SIZE __ulong(0x40000) +#define USR_STACK_SIZE_THREAD __ulong(0x40000) +#define USR_STACK_END END_POINT(USR_STACK) + +#define KERNEL_RESIDENT __ulong(0xc0000000) + +#define KERNEL_IMG KERNEL_RESIDENT +#define KERNEL_IMG_SIZE __ulong(0x4000000) +#define KERNEL_IMG_END END_POINT(KERNEL_IMG) + +#define PG_MOUNT_1 __ulong(0xc4000000) +#define PG_MOUNT_1_SIZE __ulong(0x1000) +#define PG_MOUNT_1_END END_POINT(PG_MOUNT_1) + +#define PG_MOUNT_2 __ulong(0xc4001000) +#define PG_MOUNT_2_SIZE __ulong(0x1000) +#define PG_MOUNT_2_END END_POINT(PG_MOUNT_2) + +#define PG_MOUNT_3 __ulong(0xc4002000) +#define PG_MOUNT_3_SIZE __ulong(0x1000) +#define PG_MOUNT_3_END END_POINT(PG_MOUNT_3) + +#define PG_MOUNT_4 __ulong(0xc4003000) +#define PG_MOUNT_4_SIZE __ulong(0x1000) +#define PG_MOUNT_4_END END_POINT(PG_MOUNT_4) + +#define PG_MOUNT_VAR __ulong(0xc4004000) +#define PG_MOUNT_VAR_SIZE __ulong(0x3fc000) +#define PG_MOUNT_VAR_END END_POINT(PG_MOUNT_VAR) + +#define VMAP __ulong(0xc4400000) +#define VMAP_SIZE __ulong(0x3b400000) +#define VMAP_END END_POINT(VMAP) + +#define PMAP VMAP + +#define VMS_MOUNT_1 __ulong(0xff800000) +#define VMS_MOUNT_1_SIZE __ulong(0x400000) +#define VMS_MOUNT_1_END END_POINT(VMS_MOUNT_1) + +#define VMS_SELF_MOUNT __ulong(0xffc00000) + +#endif /* __LUNAIX_MEMPART32_H */ diff --git a/lunaix-os/arch/x86/includes/sys/mm/mempart64.h b/lunaix-os/arch/x86/includes/sys/mm/mempart64.h new file mode 100644 index 0000000..9d3559a --- /dev/null +++ b/lunaix-os/arch/x86/includes/sys/mm/mempart64.h @@ -0,0 +1,71 @@ +#ifndef __LUNAIX_MEMPART64_H +#define __LUNAIX_MEMPART64_H + +#define END_POINT(name) (name + name##_SIZE - 1) + +#ifdef __LD__ +#define __ulong(val) val +#else +#define __ulong(val) val##UL +#endif + +#define KSTACK_AREA __ulong(0x0000000100000000) +#define KSTACK_AREA_SIZE __ulong(0x0000000040000000) +#define KSTACK_AREA_END END_POINT(KSTACK_AREA) + +#define USR_EXEC __ulong(0x0000008000000000) +#define USR_EXEC_SIZE __ulong(0x0000002000000000) +#define USR_EXEC_END END_POINT(USR_EXEC) + +#define USR_MMAP __ulong(0x0000010000000000) +#define USR_MMAP_SIZE __ulong(0x0000008000000000) +#define USR_MMAP_END END_POINT(USR_MMAP) + +#define USR_STACK __ulong(0x00007f8000000000) +#define USR_STACK_SIZE __ulong(0x0000001fc0000000) +#define USR_STACK_SIZE_THREAD __ulong(0x0000000000200000) +#define USR_STACK_END END_POINT(USR_STACK) + + +// la casa del kernel + +#define KERNEL_RESIDENT __ulong(0xfffffd8000000000) // -2.5T +#define VMAP KERNEL_RESIDENT // -2.5T +#define VMAP_SIZE __ulong(0x0000010000000000) +#define VMAP_END END_POINT(VMAP) + +#define VMS_MOUNT_1 __ulong(0xfffffe8000000000) // -1.5T +#define VMS_MOUNT_1_SIZE __ulong(0x0000008000000000) +#define VMS_MOUNT_1_END END_POINT(VMS_MOUNT_1) + +#define VMS_SELF_MOUNT __ulong(0xffffff0000000000) // -1T + +#define KMAP __ulong(0xffffff8000000000) +#define PG_MOUNT_1 KMAP // -512G +#define PG_MOUNT_1_SIZE __ulong(0x0000000000001000) +#define PG_MOUNT_1_END END_POINT(PG_MOUNT_1) + +#define PG_MOUNT_2 __ulong(0xffffff8000001000) +#define PG_MOUNT_2_SIZE __ulong(0x0000000000001000) +#define PG_MOUNT_2_END END_POINT(PG_MOUNT_2) + +#define PG_MOUNT_3 __ulong(0xffffff8000002000) +#define PG_MOUNT_3_SIZE __ulong(0x0000000000001000) +#define PG_MOUNT_3_END END_POINT(PG_MOUNT_3) + +#define PG_MOUNT_4 __ulong(0xffffff8000003000) +#define PG_MOUNT_4_SIZE __ulong(0x0000000000001000) +#define PG_MOUNT_4_END END_POINT(PG_MOUNT_4) + +#define PG_MOUNT_VAR __ulong(0xffffff8000004000) +#define PG_MOUNT_VAR_SIZE __ulong(0x000000003fffc000) +#define PG_MOUNT_VAR_END END_POINT(PG_MOUNT_VAR) + +#define PMAP __ulong(0xffffff8040000000) + +#define KERNEL_IMG __ulong(0xffffffff80000000) // -2G +#define KERNEL_IMG_SIZE __ulong(0x0000000080000000) +#define KERNEL_IMG_END END_POINT(KERNEL_IMG) + + +#endif \ No newline at end of file diff --git a/lunaix-os/arch/i386/includes/sys/mm/mm_defs.h b/lunaix-os/arch/x86/includes/sys/mm/mm_defs.h similarity index 56% rename from lunaix-os/arch/i386/includes/sys/mm/mm_defs.h rename to lunaix-os/arch/x86/includes/sys/mm/mm_defs.h index 5c098d3..40804d0 100644 --- a/lunaix-os/arch/i386/includes/sys/mm/mm_defs.h +++ b/lunaix-os/arch/x86/includes/sys/mm/mm_defs.h @@ -1,13 +1,9 @@ #ifndef __LUNAIX_MM_DEFS_H #define __LUNAIX_MM_DEFS_H - #include "mempart.h" #include "pagetable.h" -#define KSTACK_PAGES 3 -#define KSTACK_SIZE (KSTACK_PAGES * MEM_PAGE) - /* Regardless architecture we need to draw the line very carefully, and must take the size of VM into account. In general, we aims to achieve @@ -19,16 +15,26 @@ In light of upcomming x86_64 support (for Level 4&5 Paging): * #510 entry of PML4 (0x0000ff0000000000, ~512GiB) * #510 entry of PML5 (0x01fe000000000000, ~256TiB) + + + KERNEL_RESIDENT - a high-mem region, kernel should be + KSTACK_PAGES - kernel stack, pages allocated to + KEXEC_RSVD - page reserved for kernel images */ -// Where the kernel getting re-mapped. -#define KERNEL_RESIDENT 0xc0000000UL -// Pages reserved for kernel image -#define KEXEC_RSVD 16 +#ifdef CONFIG_ARCH_X86_64 +# define KSTACK_PAGES 4 +# define KEXEC_RSVD 32 +#else +# define KSTACK_PAGES 2 +# define KEXEC_RSVD 16 +#endif + +#define KSTACK_SIZE (KSTACK_PAGES * PAGE_SIZE) #define kernel_addr(addr) ((addr) >= KERNEL_RESIDENT || (addr) < USR_EXEC) -#define to_kphysical(k_va) ((ptr_t)(k_va) - KERNEL_RESIDENT) -#define to_kvirtual(k_pa) ((ptr_t)(k_pa) - KERNEL_RESIDENT) +#define to_kphysical(k_va) ((ptr_t)(k_va) - KERNEL_IMG) +#define to_kvirtual(k_pa) ((ptr_t)(k_pa) + KERNEL_IMG) #endif /* __LUNAIX_MM_DEFS_H */ diff --git a/lunaix-os/arch/i386/includes/sys/mm/pagetable.h b/lunaix-os/arch/x86/includes/sys/mm/pagetable.h similarity index 71% rename from lunaix-os/arch/i386/includes/sys/mm/pagetable.h rename to lunaix-os/arch/x86/includes/sys/mm/pagetable.h index 2b188cd..3888124 100644 --- a/lunaix-os/arch/i386/includes/sys/mm/pagetable.h +++ b/lunaix-os/arch/x86/includes/sys/mm/pagetable.h @@ -6,31 +6,15 @@ /* ******** Page Table Manipulation ******** */ -// Levels of page table to traverse for a single page walk -#define _PTW_LEVEL 2 +#ifdef CONFIG_ARCH_X86_64 -#define _PAGE_BASE_SHIFT 12 -#define _PAGE_BASE_SIZE ( 1UL << _PAGE_BASE_SHIFT ) -#define _PAGE_BASE_MASK ( _PAGE_BASE_SIZE - 1) +#include "pt_def64.h" -#define _PAGE_LEVEL_SHIFT 10 -#define _PAGE_LEVEL_SIZE ( 1UL << _PAGE_LEVEL_SHIFT ) -#define _PAGE_LEVEL_MASK ( _PAGE_LEVEL_SIZE - 1 ) -#define _PAGE_Ln_SIZE(n) ( 1UL << (_PAGE_BASE_SHIFT + _PAGE_LEVEL_SHIFT * (_PTW_LEVEL - (n) - 1)) ) +#else -// Note: we set VMS_SIZE = VMS_MASK as it is impossible -// to express 4Gi in 32bit unsigned integer +#include "pt_def32.h" -#define VMS_MASK ( -1UL ) -#define VMS_SIZE VMS_MASK - -/* General size of a LnT huge page */ - -#define L0T_SIZE _PAGE_Ln_SIZE(0) -#define L1T_SIZE _PAGE_Ln_SIZE(1) -#define L2T_SIZE _PAGE_Ln_SIZE(1) -#define L3T_SIZE _PAGE_Ln_SIZE(1) -#define LFT_SIZE _PAGE_Ln_SIZE(1) +#endif /* General mask to get page offset of a LnT huge page */ @@ -62,49 +46,28 @@ // max translation level supported #define MAX_LEVEL _PTW_LEVEL - -/* ******** PTE Manipulation ******** */ - -struct __pte { - unsigned int val; -} align(4); - #ifndef pte_t typedef struct __pte pte_t; #endif -typedef unsigned int pfn_t; -typedef unsigned int pte_attr_t; - -#define _PTE_P (1 << 0) -#define _PTE_W (1 << 1) -#define _PTE_U (1 << 2) -#define _PTE_WT (1 << 3) -#define _PTE_CD (1 << 4) -#define _PTE_A (1 << 5) -#define _PTE_D (1 << 6) -#define _PTE_PS (1 << 7) -#define _PTE_PAT (1 << 7) -#define _PTE_G (1 << 8) -#define _PTE_X (0) -#define _PTE_R (0) #define _PTE_PROT_MASK ( _PTE_W | _PTE_U | _PTE_X ) #define KERNEL_PAGE ( _PTE_P ) #define KERNEL_EXEC ( KERNEL_PAGE | _PTE_X ) -#define KERNEL_DATA ( KERNEL_PAGE | _PTE_W ) -#define KERNEL_RDONLY ( KERNEL_PAGE ) +#define KERNEL_DATA ( KERNEL_PAGE | _PTE_W | _PTE_NX ) +#define KERNEL_RDONLY ( KERNEL_PAGE | _PTE_NX ) +#define KERNEL_ROEXEC ( KERNEL_PAGE | _PTE_X ) #define USER_PAGE ( _PTE_P | _PTE_U ) #define USER_EXEC ( USER_PAGE | _PTE_X ) -#define USER_DATA ( USER_PAGE | _PTE_W ) -#define USER_RDONLY ( USER_PAGE ) +#define USER_DATA ( USER_PAGE | _PTE_W | _PTE_NX ) +#define USER_RDONLY ( USER_PAGE | _PTE_NX ) +#define USER_ROEXEC ( USER_PAGE | _PTE_X ) #define SELF_MAP ( KERNEL_DATA | _PTE_WT | _PTE_CD ) #define __mkpte_from(pte_val) ((pte_t){ .val = (pte_val) }) -#define __MEMGUARD 0xdeadc0deUL #define null_pte ( __mkpte_from(0) ) #define guard_pte ( __mkpte_from(__MEMGUARD) ) @@ -159,13 +122,13 @@ pte_setppfn(pte_t pte, pfn_t ppfn) static inline ptr_t pte_paddr(pte_t pte) { - return pte.val & ~_PAGE_BASE_MASK; + return __paddr(pte.val) & ~_PAGE_BASE_MASK; } static inline pfn_t pte_ppfn(pte_t pte) { - return pte.val >> _PAGE_BASE_SHIFT; + return __paddr(pte.val) >> _PAGE_BASE_SHIFT; } static inline pte_t @@ -273,19 +236,19 @@ pte_allow_user(pte_t pte) static inline pte_t pte_mkexec(pte_t pte) { - return __mkpte_from(pte.val | _PTE_X); + return __mkpte_from(pte.val & ~_PTE_NX); } static inline pte_t pte_mknonexec(pte_t pte) { - return __mkpte_from(pte.val & ~_PTE_X); + return __mkpte_from(pte.val | _PTE_NX); } static inline bool pte_isexec(pte_t pte) { - return !!(pte.val & _PTE_X); + return !(pte.val & _PTE_NX); } static inline pte_t diff --git a/lunaix-os/arch/i386/includes/sys/mm/physical.h b/lunaix-os/arch/x86/includes/sys/mm/physical.h similarity index 83% rename from lunaix-os/arch/i386/includes/sys/mm/physical.h rename to lunaix-os/arch/x86/includes/sys/mm/physical.h index a6528bd..722aa15 100644 --- a/lunaix-os/arch/i386/includes/sys/mm/physical.h +++ b/lunaix-os/arch/x86/includes/sys/mm/physical.h @@ -4,7 +4,7 @@ #include #include "mm_defs.h" -#define PPLIST_STARTVM VMAP +#define PPLIST_STARTVM PMAP struct ppage_arch { diff --git a/lunaix-os/arch/x86/includes/sys/mm/pt_def32.h b/lunaix-os/arch/x86/includes/sys/mm/pt_def32.h new file mode 100644 index 0000000..b8d30d4 --- /dev/null +++ b/lunaix-os/arch/x86/includes/sys/mm/pt_def32.h @@ -0,0 +1,64 @@ +#ifdef CONFIG_ARCH_I386 + +#ifndef __LUNAIX_PT_DEF32_H +#define __LUNAIX_PT_DEF32_H + +#define _PTW_LEVEL 2 + +#define _PAGE_BASE_SHIFT 12 +#define _PAGE_BASE_SIZE ( 1UL << _PAGE_BASE_SHIFT ) +#define _PAGE_BASE_MASK ( _PAGE_BASE_SIZE - 1) + +#define _PAGE_LEVEL_SHIFT 10 +#define _PAGE_LEVEL_SIZE ( 1UL << _PAGE_LEVEL_SHIFT ) +#define _PAGE_LEVEL_MASK ( _PAGE_LEVEL_SIZE - 1 ) +#define _PAGE_Ln_SIZE(n) ( 1UL << (_PAGE_BASE_SHIFT + _PAGE_LEVEL_SHIFT * (_PTW_LEVEL - (n) - 1)) ) + +// Note: we set VMS_SIZE = VMS_MASK as it is impossible +// to express 4Gi in 32bit unsigned integer + +#define VMS_BITS 32 +#define PMS_BITS 32 + +#define VMS_SIZE ( -1UL ) +#define VMS_MASK ( -1UL ) +#define PMS_SIZE ( -1UL ) +#define PMS_MASK ( -1UL ) + +/* General size of a LnT huge page */ + +#define L0T_SIZE _PAGE_Ln_SIZE(0) +#define L1T_SIZE _PAGE_Ln_SIZE(1) +#define L2T_SIZE _PAGE_Ln_SIZE(1) +#define L3T_SIZE _PAGE_Ln_SIZE(1) +#define LFT_SIZE _PAGE_Ln_SIZE(1) + +struct __pte { + unsigned int val; +} align(4); + +#define _PTE_P (1 << 0) +#define _PTE_W (1 << 1) +#define _PTE_U (1 << 2) +#define _PTE_WT (1 << 3) +#define _PTE_CD (1 << 4) +#define _PTE_A (1 << 5) +#define _PTE_D (1 << 6) +#define _PTE_PS (1 << 7) +#define _PTE_PAT (1 << 7) +#define _PTE_G (1 << 8) +#define _PTE_X (0) +#define _PTE_NX (0) +#define _PTE_R (0) + +#define __MEMGUARD 0xdeadc0deUL + +typedef unsigned int pte_attr_t; +typedef unsigned int pfn_t; + +#define __index(va) ( (va) & VMS_MASK ) +#define __vaddr(va) ( va ) +#define __paddr(pa) ( (pa) & PMS_MASK ) + +#endif /* __LUNAIX_PT_DEF32_H */ +#endif diff --git a/lunaix-os/arch/x86/includes/sys/mm/pt_def64.h b/lunaix-os/arch/x86/includes/sys/mm/pt_def64.h new file mode 100644 index 0000000..13eafa3 --- /dev/null +++ b/lunaix-os/arch/x86/includes/sys/mm/pt_def64.h @@ -0,0 +1,71 @@ +#ifdef CONFIG_ARCH_X86_64 +#ifndef __LUNAIX_PT_DEF64_H +#define __LUNAIX_PT_DEF64_H + +#include + +#define _PTW_LEVEL 4 + + +// Note: we set VMS_SIZE = VMS_MASK as it is impossible +// to express 4Gi in 32bit unsigned integer + +#define _PAGE_BASE_SHIFT 12 + +#define _PAGE_BASE_SIZE ( 1UL << _PAGE_BASE_SHIFT ) +#define _PAGE_BASE_MASK ( (_PAGE_BASE_SIZE - 1) & 0x000fffffffffffffUL ) + +#define _PAGE_LEVEL_SHIFT 9 +#define _PAGE_LEVEL_SIZE ( 1UL << _PAGE_LEVEL_SHIFT ) +#define _PAGE_LEVEL_MASK ( _PAGE_LEVEL_SIZE - 1 ) +#define _PAGE_Ln_SIZE(n) ( 1UL << (_PAGE_BASE_SHIFT + _PAGE_LEVEL_SHIFT * (_PTW_LEVEL - (n) - 1)) ) + +#define VMS_BITS 48 +#define PMS_BITS 52 + +#define VMS_SIZE ( 1UL << VMS_BITS) +#define VMS_MASK ( VMS_SIZE - 1 ) +#define PMS_SIZE ( 1UL << PMS_BITS ) +#define PMS_MASK ( PMS_SIZE - 1 ) + +/* General size of a LnT huge page */ + +#define L0T_SIZE _PAGE_Ln_SIZE(0) +#define L1T_SIZE _PAGE_Ln_SIZE(1) +#define L2T_SIZE _PAGE_Ln_SIZE(2) +#define L3T_SIZE _PAGE_Ln_SIZE(3) +#define LFT_SIZE _PAGE_Ln_SIZE(3) + + +struct __pte { + unsigned long val; +} align(8); + +#define _PTE_P (1UL << 0) +#define _PTE_W (1UL << 1) +#define _PTE_U (1UL << 2) +#define _PTE_WT (1UL << 3) +#define _PTE_CD (1UL << 4) +#define _PTE_A (1UL << 5) +#define _PTE_D (1UL << 6) +#define _PTE_PS (1UL << 7) +#define _PTE_PAT (1UL << 7) +#define _PTE_G (1UL << 8) +#define _PTE_NX (1UL << 63) +#define _PTE_X (0) +#define _PTE_R (0) + +#define __MEMGUARD 0xf0f0f0f0f0f0f0f0UL + +typedef unsigned long pte_attr_t; +typedef unsigned long pfn_t; + +// always do sign extend on x86_64 + +#define __index(va) ( (va) & VMS_MASK ) +#define __vaddr(va) \ + ( (__index(va) ^ ((VMS_MASK + 1) >> 1)) - ((VMS_MASK + 1) >> 1) ) +#define __paddr(pa) ( (pa) & PMS_MASK ) + +#endif /* __LUNAIX_PT_DEF64_H */ +#endif \ No newline at end of file diff --git a/lunaix-os/arch/i386/includes/sys/mm/tlb.h b/lunaix-os/arch/x86/includes/sys/mm/tlb.h similarity index 100% rename from lunaix-os/arch/i386/includes/sys/mm/tlb.h rename to lunaix-os/arch/x86/includes/sys/mm/tlb.h diff --git a/lunaix-os/arch/i386/includes/sys/muldiv64.h b/lunaix-os/arch/x86/includes/sys/muldiv64.h similarity index 91% rename from lunaix-os/arch/i386/includes/sys/muldiv64.h rename to lunaix-os/arch/x86/includes/sys/muldiv64.h index 940f7de..5905990 100644 --- a/lunaix-os/arch/i386/includes/sys/muldiv64.h +++ b/lunaix-os/arch/x86/includes/sys/muldiv64.h @@ -4,6 +4,7 @@ #include #include +#ifdef CONFIG_ARCH_I386 #define do_udiv64(n, base) \ ({ \ unsigned long __upper, __low, __high, __mod, __base; \ @@ -25,6 +26,13 @@ } \ __mod; \ }) +#else + #define do_udiv64(n, base) \ + ({ \ + n = (n) / (base); \ + (n) % (base); \ + }) +#endif static inline u64_t udiv64(u64_t n, unsigned int base) diff --git a/lunaix-os/arch/i386/includes/sys/pci_hba.h b/lunaix-os/arch/x86/includes/sys/pci_hba.h similarity index 100% rename from lunaix-os/arch/i386/includes/sys/pci_hba.h rename to lunaix-os/arch/x86/includes/sys/pci_hba.h diff --git a/lunaix-os/arch/i386/includes/sys/port_io.h b/lunaix-os/arch/x86/includes/sys/port_io.h similarity index 100% rename from lunaix-os/arch/i386/includes/sys/port_io.h rename to lunaix-os/arch/x86/includes/sys/port_io.h diff --git a/lunaix-os/arch/x86/includes/sys/syscall_utils.h b/lunaix-os/arch/x86/includes/sys/syscall_utils.h new file mode 100644 index 0000000..551626d --- /dev/null +++ b/lunaix-os/arch/x86/includes/sys/syscall_utils.h @@ -0,0 +1,17 @@ +#ifndef __LUNAIX_ARCH_SYSCALL_UTILS_H +#define __LUNAIX_ARCH_SYSCALL_UTILS_H + +#include +#include + +static inline void +convert_valist(va_list* ap_ref, sc_va_list syscall_ap) +{ +#ifdef CONFIG_ARCH_X86_64 + memcpy(ap_ref, syscall_ap, sizeof(va_list)); +#else + *ap_ref = *syscall_ap; +#endif +} + +#endif /* __LUNAIX_ARCH_SYSCALL_UTILS_H */ diff --git a/lunaix-os/arch/i386/includes/sys/trace.h b/lunaix-os/arch/x86/includes/sys/trace.h similarity index 100% rename from lunaix-os/arch/i386/includes/sys/trace.h rename to lunaix-os/arch/x86/includes/sys/trace.h diff --git a/lunaix-os/arch/i386/includes/sys/vectors.h b/lunaix-os/arch/x86/includes/sys/vectors.h similarity index 100% rename from lunaix-os/arch/i386/includes/sys/vectors.h rename to lunaix-os/arch/x86/includes/sys/vectors.h diff --git a/lunaix-os/arch/x86/includes/sys/x86_isa.h b/lunaix-os/arch/x86/includes/sys/x86_isa.h new file mode 100644 index 0000000..34510c8 --- /dev/null +++ b/lunaix-os/arch/x86/includes/sys/x86_isa.h @@ -0,0 +1,96 @@ +#ifndef __LUNAIX_I386_ASM_H +#define __LUNAIX_I386_ASM_H + +#define SEL_INDEX(i) ((i) << 3) +#define SEL_RPL(rpl) ((rpl) & 0b11) + +#define KCODE_SEG (SEL_INDEX(1) | SEL_RPL(0)) +#define UCODE_SEG (SEL_INDEX(2) | SEL_RPL(3)) + +#ifdef CONFIG_ARCH_I386 + #define KDATA_SEG (SEL_INDEX(3) | SEL_RPL(0)) + #define UDATA_SEG (SEL_INDEX(4) | SEL_RPL(3)) + #define TSS_SEG (SEL_INDEX(5) | SEL_RPL(0)) + +#else + #define KDATA_SEG (SEL_INDEX(3) | SEL_RPL(0)) + #define UDATA_SEG (SEL_INDEX(4) | SEL_RPL(3)) + #define TSS_SEG (SEL_INDEX(5) | SEL_RPL(0)) + +#endif + + +#ifndef __ASM__ +#include + +#define IRQ_TRIG_EDGE 0b0 +#define IRQ_TRIG_LEVEL 0b1 + +#define IRQ_TYPE_FIXED (0b01 << 1) +#define IRQ_TYPE_NMI (0b11 << 1) +#define IRQ_TYPE (0b11 << 1) + +#define IRQ_VE_HI (0b1 << 3) +#define IRQ_VE_LO (0b0 << 3) + +#define IRQ_DEFAULT (IRQ_TRIG_EDGE | IRQ_TYPE_FIXED | IRQ_VE_HI) + + +struct x86_intc +{ + char* name; + void* data; + + void (*irq_attach)(struct x86_intc*, + int irq, + int iv, + cpu_t dest, + u32_t flags); + void (*notify_eoi)(struct x86_intc*, cpu_t id, int iv); +}; + +#ifdef CONFIG_ARCH_X86_64 + +struct x86_tss +{ + u32_t rsvd_1; + ptr_t rsps[3]; + union { + struct { + ptr_t ist_null; + ptr_t valid_ists[7]; + }; + ptr_t ists[8]; + }; + + u8_t rsvd_3[12]; +} compact; + +struct x86_sysdesc { + u64_t lo; + u64_t hi; +} compact; + +typedef u64_t x86_segdesc_t; + +#else + +struct x86_tss +{ + u32_t link; + u32_t esp0; + u16_t ss0; + u8_t __padding[94]; +} compact; + +struct x86_sysdesc { + u32_t lo; + u32_t hi; +} compact; + +typedef struct x86_sysdesc x86_segdesc_t; + +#endif + +#endif +#endif /* __LUNAIX_I386_ASM_H */ diff --git a/lunaix-os/arch/i386/klib/fast_crc.c b/lunaix-os/arch/x86/klib/fast_crc.c similarity index 100% rename from lunaix-os/arch/i386/klib/fast_crc.c rename to lunaix-os/arch/x86/klib/fast_crc.c diff --git a/lunaix-os/arch/x86/klib/fast_str.c b/lunaix-os/arch/x86/klib/fast_str.c new file mode 100644 index 0000000..2704178 --- /dev/null +++ b/lunaix-os/arch/x86/klib/fast_str.c @@ -0,0 +1,56 @@ +#include + +#ifdef CONFIG_ARCH_X86_64 +void* +memcpy(void* dest, const void* src, unsigned long num) +{ + if (!num) + return dest; + + asm volatile("movq %1, %%rdi\n" + "rep movsb\n" ::"S"(src), + "r"(dest), + "c"(num) + : "rdi", "memory"); + return dest; +} + +void* +memset(void* ptr, int value, unsigned long num) +{ + asm volatile("movq %1, %%rdi\n" + "rep stosb\n" ::"c"(num), + "r"(ptr), + "a"(value) + : "rdi", "memory"); + return ptr; +} + +#else +void* +memcpy(void* dest, const void* src, unsigned long num) +{ + if (!num) + return dest; + + asm volatile("movl %1, %%edi\n" + "rep movsb\n" ::"S"(src), + "r"(dest), + "c"(num) + : "edi", "memory"); + return dest; +} + +void* +memset(void* ptr, int value, unsigned long num) +{ + asm volatile("movl %1, %%edi\n" + "rep stosb\n" ::"c"(num), + "r"(ptr), + "a"(value) + : "edi", "memory"); + return ptr; +} + +#endif + diff --git a/lunaix-os/arch/i386/mm/fault.c b/lunaix-os/arch/x86/mm/fault.c similarity index 91% rename from lunaix-os/arch/i386/mm/fault.c rename to lunaix-os/arch/x86/mm/fault.c index 4177147..62f9d80 100644 --- a/lunaix-os/arch/i386/mm/fault.c +++ b/lunaix-os/arch/x86/mm/fault.c @@ -17,7 +17,7 @@ __arch_prepare_fault_context(struct fault_context* fault) fault->fault_ptep = mkptep_va(VMS_SELF, ptr); fault->fault_data = ictx->execp->err_code; - fault->fault_instn = ictx->execp->eip; + fault->fault_instn = hart_pc(ictx); fault->fault_va = ptr; return true; diff --git a/lunaix-os/arch/i386/mm/gdt.c b/lunaix-os/arch/x86/mm/gdt.c similarity index 56% rename from lunaix-os/arch/i386/mm/gdt.c rename to lunaix-os/arch/x86/mm/gdt.c index 10b6bec..d1b3627 100644 --- a/lunaix-os/arch/i386/mm/gdt.c +++ b/lunaix-os/arch/x86/mm/gdt.c @@ -33,47 +33,106 @@ #define SEG_CODE_EXRDC 0x0E // Execute/Read, conforming #define SEG_CODE_EXRDCA 0x0F // Execute/Read, conforming, accessed +#define BIT64 (SD_64BITS(1) | SD_32BITS(0)) +#define BIT32 (SD_64BITS(0) | SD_32BITS(1)) + #define SEG_R0_CODE \ SD_TYPE(SEG_CODE_EXRD) | SD_CODE_DATA(1) | SD_DPL(0) | SD_PRESENT(1) | \ - SD_AVL(0) | SD_64BITS(0) | SD_32BITS(1) | SD_4K_GRAN(1) + SD_AVL(0) | SD_4K_GRAN(1) #define SEG_R0_DATA \ SD_TYPE(SEG_DATA_RDWR) | SD_CODE_DATA(1) | SD_DPL(0) | SD_PRESENT(1) | \ - SD_AVL(0) | SD_64BITS(0) | SD_32BITS(1) | SD_4K_GRAN(1) + SD_AVL(0) | SD_4K_GRAN(1) #define SEG_R3_CODE \ SD_TYPE(SEG_CODE_EXRD) | SD_CODE_DATA(1) | SD_DPL(3) | SD_PRESENT(1) | \ - SD_AVL(0) | SD_64BITS(0) | SD_32BITS(1) | SD_4K_GRAN(1) + SD_AVL(0) | SD_4K_GRAN(1) #define SEG_R3_DATA \ SD_TYPE(SEG_DATA_RDWR) | SD_CODE_DATA(1) | SD_DPL(3) | SD_PRESENT(1) | \ - SD_AVL(0) | SD_64BITS(0) | SD_32BITS(1) | SD_4K_GRAN(1) + SD_AVL(0) | SD_4K_GRAN(1) #define SEG_TSS SD_TYPE(9) | SD_DPL(0) | SD_PRESENT(1) -#define GDT_ENTRY 6 -u64_t _gdt[GDT_ENTRY]; +#ifdef CONFIG_ARCH_X86_64 + +x86_segdesc_t _gdt[8]; u16_t _gdt_limit = sizeof(_gdt) - 1; -void -_set_gdt_entry(u32_t index, u32_t base, u32_t limit, u32_t flags) +static inline void +_set_gdt_entry(int index, int dpl, unsigned int flags) { - _gdt[index] = + u64_t desc = 0; + desc |= flags | BIT64; + desc |= 0xf << 16; + desc = desc << 32; + desc |= 0xffff; + + _gdt[index] = desc; +} + +static inline void +_set_tss(int index, ptr_t base, size_t size) +{ + struct x86_sysdesc* tssd; + u32_t attr; + + size = size - 1; + tssd = (struct x86_sysdesc*)&_gdt[index]; + tssd->hi = base >> 32; + + attr = SD_4K_GRAN(1) | SD_PRESENT(1) | SD_TYPE(9) | SD_DPL(0); + attr |= (SEG_LIM_H(size) << 16); + + tssd->lo = (SEG_BASE_H(base) | attr | SEG_BASE_M(base)) << 32; + tssd->lo |= SEG_BASE_L(base) | SEG_LIM_L(size); +} + +#else + +x86_segdesc_t _gdt[6]; +u16_t _gdt_limit = sizeof(_gdt) - 1; + +static inline void +_set_gdt_entry(u32_t index, ptr_t base, u32_t limit, u32_t flags) +{ + x86_segdesc_t* gdte = &_gdt[index]; + + flags |= BIT32; + + gdte->hi = SEG_BASE_H(base) | flags | SEG_LIM_H(limit) | SEG_BASE_M(base); - _gdt[index] <<= 32; - _gdt[index] |= SEG_BASE_L(base) | SEG_LIM_L(limit); + gdte->lo |= SEG_BASE_L(base) | SEG_LIM_L(limit); } -extern struct x86_tss _tss; +static inline void +_set_tss(int index, ptr_t base, size_t size) +{ + _set_gdt_entry(index, base, size - 1, SEG_TSS); +} + +#endif + void _init_gdt() { + extern struct x86_tss _tss; + +#ifdef CONFIG_ARCH_X86_64 + _gdt[0] = 0; + _set_gdt_entry(1, 0, SEG_R0_CODE); // kernel code + _set_gdt_entry(2, 3, SEG_R3_CODE); // user code + _set_gdt_entry(3, 0, SEG_R0_DATA); // generic data + _set_gdt_entry(4, 4, SEG_R3_DATA); // generic data + _set_tss(5, (ptr_t)&_tss, sizeof(_tss)); +#else _set_gdt_entry(0, 0, 0, 0); _set_gdt_entry(1, 0, 0xfffff, SEG_R0_CODE); - _set_gdt_entry(2, 0, 0xfffff, SEG_R0_DATA); - _set_gdt_entry(3, 0, 0xfffff, SEG_R3_CODE); + _set_gdt_entry(2, 0, 0xfffff, SEG_R3_CODE); + _set_gdt_entry(3, 0, 0xfffff, SEG_R0_DATA); _set_gdt_entry(4, 0, 0xfffff, SEG_R3_DATA); - _set_gdt_entry(5, (u32_t)&_tss, sizeof(struct x86_tss) - 1, SEG_TSS); + _set_tss(5, (u32_t)&_tss, sizeof(struct x86_tss) - 1); +#endif } \ No newline at end of file diff --git a/lunaix-os/arch/i386/mm/pmm.c b/lunaix-os/arch/x86/mm/pmm.c similarity index 73% rename from lunaix-os/arch/i386/mm/pmm.c rename to lunaix-os/arch/x86/mm/pmm.c index 45b7e4e..aa35b86 100644 --- a/lunaix-os/arch/i386/mm/pmm.c +++ b/lunaix-os/arch/x86/mm/pmm.c @@ -31,7 +31,11 @@ found:; ptr_t kexec_end = to_kphysical(__kexec_end); ptr_t aligned_pplist = MAX(ent->start, kexec_end); +#ifdef CONFIG_ARCH_X86_64 + aligned_pplist = napot_upaligned(aligned_pplist, L2T_SIZE); +#else aligned_pplist = napot_upaligned(aligned_pplist, L0T_SIZE); +#endif if (aligned_pplist + pool_size > ent->start + ent->size) { return 0; @@ -44,18 +48,28 @@ found:; // regardless the actual physical memory size // anchor the pplist at vmap location (right after kernel) - memory->pplist = (struct ppage*)VMAP; + memory->pplist = (struct ppage*)PMAP; memory->list_len = ppfn_total; - pfn_t nhuge = page_count(pool_size, L0T_SIZE); - pte_t* ptep = mkl0tep_va(VMS_SELF, VMAP); + pfn_t nhuge; + pte_t* ptep; + pte_t pte = mkpte(aligned_pplist, KERNEL_DATA); - - vmm_set_ptes_contig(ptep, pte_mkhuge(pte), L0T_SIZE, nhuge); - tlb_flush_kernel(VMAP); - // shift the actual vmap start address +#ifdef CONFIG_ARCH_X86_64 + nhuge = page_count(pool_size, L2T_SIZE); + ptep = mkl2tep_va(VMS_SELF, PMAP); + vmm_set_ptes_contig(ptep, pte_mkhuge(pte), L2T_SIZE, nhuge); +#else + nhuge = page_count(pool_size, L0T_SIZE); + ptep = mkl0tep_va(VMS_SELF, PMAP); + + // since VMAP and PMAP share same address space + // we need to shift VMAP to make room vmap_set_start(VMAP + nhuge * L0T_SIZE); + vmm_set_ptes_contig(ptep, pte_mkhuge(pte), L0T_SIZE, nhuge); +#endif + tlb_flush_kernel(PMAP); return aligned_pplist; } \ No newline at end of file diff --git a/lunaix-os/arch/i386/mm/tlb.c b/lunaix-os/arch/x86/mm/tlb.c similarity index 100% rename from lunaix-os/arch/i386/mm/tlb.c rename to lunaix-os/arch/x86/mm/tlb.c diff --git a/lunaix-os/arch/i386/mm/vmutils.c b/lunaix-os/arch/x86/mm/vmutils.c similarity index 72% rename from lunaix-os/arch/i386/mm/vmutils.c rename to lunaix-os/arch/x86/mm/vmutils.c index c787892..df831c2 100644 --- a/lunaix-os/arch/i386/mm/vmutils.c +++ b/lunaix-os/arch/x86/mm/vmutils.c @@ -14,6 +14,15 @@ dup_leaflet(struct leaflet* leaflet) size_t cnt_wordsz = leaflet_size(new_leaflet) / sizeof(ptr_t); +#ifdef CONFIG_ARCH_X86_64 + asm volatile("movq %1, %%rdi\n" + "movq %2, %%rsi\n" + "rep movsq\n" ::"c"(cnt_wordsz), + "r"(dest_va), + "r"(src_va) + : "memory", "%edi", "%esi"); + +#else asm volatile("movl %1, %%edi\n" "movl %2, %%esi\n" "rep movsl\n" ::"c"(cnt_wordsz), @@ -21,6 +30,8 @@ dup_leaflet(struct leaflet* leaflet) "r"(src_va) : "memory", "%edi", "%esi"); +#endif + leaflet_unmount(leaflet); vunmap(dest_va, new_leaflet); diff --git a/lunaix-os/arch/i386/syscall.S b/lunaix-os/arch/x86/syscall32.S similarity index 72% rename from lunaix-os/arch/i386/syscall.S rename to lunaix-os/arch/x86/syscall32.S index 4682df4..4f0ad5b 100644 --- a/lunaix-os/arch/i386/syscall.S +++ b/lunaix-os/arch/x86/syscall32.S @@ -81,41 +81,41 @@ .type syscall_hndlr, @function .global syscall_hndlr syscall_hndlr: - pushl %ebp - movl %esp, %ebp - movl 8(%esp), %ebx // struct hart_state* + pushl %ebp + movl %esp, %ebp + movl 8(%esp), %ebx // struct hart_state* - addl $4, %ebx - movl (%ebx), %eax /* eax: call code as well as the return value from syscall */ - cmpl $__SYSCALL_MAX, %eax - jae 2f + addl $4, %ebx + movl (%ebx), %eax /* eax: call code as well as the return value from syscall */ + cmpl $__SYSCALL_MAX, %eax + jae 2f - shll $2, %eax - addl $syscall_table, %eax - cmpl $0, (%eax) - jne 1f + shll $2, %eax + addl $syscall_table, %eax + cmpl $0, (%eax) + jne 1f 2: - neg %eax - movl %ebp, %esp - popl %ebp + neg %eax + movl %ebp, %esp + popl %ebp ret 1: - pushl %ebx - pushl 24(%ebx) /* esi - #5 arg */ - pushl 16(%ebx) /* edi - #4 arg */ - pushl 12(%ebx) /* edx - #3 arg */ - pushl 8(%ebx) /* ecx - #2 arg */ - pushl 4(%ebx) /* ebx - #1 arg */ + pushl %ebx + pushl 24(%ebx) /* esi - #5 arg */ + pushl 16(%ebx) /* edi - #4 arg */ + pushl 12(%ebx) /* edx - #3 arg */ + pushl 8(%ebx) /* ecx - #2 arg */ + pushl 4(%ebx) /* ebx - #1 arg */ - call *(%eax) + call *(%eax) - addl $20, %esp /* remove the parameters from stack */ + addl $20, %esp /* remove the parameters from stack */ - popl %ebx - movl %eax, (%ebx) /* save the return value */ + popl %ebx + movl %eax, (%ebx) /* save the return value */ - movl %ebp, %esp - popl %ebp + movl %ebp, %esp + popl %ebp ret \ No newline at end of file diff --git a/lunaix-os/arch/x86/syscall64.S b/lunaix-os/arch/x86/syscall64.S new file mode 100644 index 0000000..f4ea8bd --- /dev/null +++ b/lunaix-os/arch/x86/syscall64.S @@ -0,0 +1,124 @@ +#define __ASM__ +#include +#include "sys/interrupt64.S.inc" + +.section .data + /* + 注意,这里的顺序非常重要。每个系统调用在这个地址表里的索引等于其调用号。 + */ + syscall_table: + 1: + .8byte 0 + .8byte __lxsys_fork /* 1 */ + .8byte __lxsys_yield + .8byte __lxsys_sbrk + .8byte __lxsys_brk + .8byte __lxsys_getpid /* 5 */ + .8byte __lxsys_getppid + .8byte __lxsys_sleep + .8byte __lxsys_exit + .8byte __lxsys_wait + .8byte __lxsys_waitpid /* 10 */ + .8byte __lxsys_sigreturn + .8byte __lxsys_sigprocmask + .8byte __lxsys_sys_sigaction + .8byte __lxsys_pause + .8byte __lxsys_kill /* 15 */ + .8byte __lxsys_alarm + .8byte __lxsys_sigpending + .8byte __lxsys_sigsuspend + .8byte __lxsys_open + .8byte __lxsys_close /* 20 */ + .8byte __lxsys_read + .8byte __lxsys_write + .8byte __lxsys_sys_readdir + .8byte __lxsys_mkdir + .8byte __lxsys_lseek /* 25 */ + .8byte __lxsys_geterrno + .8byte __lxsys_readlink + .8byte __lxsys_readlinkat + .8byte __lxsys_rmdir + .8byte __lxsys_unlink /* 30 */ + .8byte __lxsys_unlinkat + .8byte __lxsys_link + .8byte __lxsys_fsync + .8byte __lxsys_dup + .8byte __lxsys_dup2 /* 35 */ + .8byte __lxsys_realpathat + .8byte __lxsys_symlink + .8byte __lxsys_chdir + .8byte __lxsys_fchdir + .8byte __lxsys_getcwd /* 40 */ + .8byte __lxsys_rename + .8byte __lxsys_mount + .8byte __lxsys_unmount + .8byte __lxsys_getxattr + .8byte __lxsys_setxattr /* 45 */ + .8byte __lxsys_fgetxattr + .8byte __lxsys_fsetxattr + .8byte __lxsys_ioctl + .8byte __lxsys_getpgid + .8byte __lxsys_setpgid /* 50 */ + .8byte __lxsys_syslog + .8byte __lxsys_sys_mmap + .8byte __lxsys_munmap + .8byte __lxsys_execve + .8byte __lxsys_fstat /* 55 */ + .8byte __lxsys_pollctl + .8byte __lxsys_th_create + .8byte __lxsys_th_self + .8byte __lxsys_th_exit + .8byte __lxsys_th_join /* 60 */ + .8byte __lxsys_th_kill + .8byte __lxsys_th_detach + .8byte __lxsys_th_sigmask + 2: + .rept __SYSCALL_MAX - (2b - 1b) / 8 + .8byte 0 + .endr + + +.section .text + .type syscall_hndlr, @function + .global syscall_hndlr + syscall_hndlr: + pushq %rbp + movq %rsp, %rbp + pushq %rbx + + movq %rdi, %rbx // struct hart_state* + + movq irax(%rbx), %rax /* rax: call code as well as the return value from syscall */ + cmpq $__SYSCALL_MAX, %rax + jae 2f + + shlq $3, %rax // %rax * 8 + movabsq $syscall_table, %r8 + addq %r8, %rax + cmpq $0, (%rax) + jne 1f + 2: + negq %rax + popq %rbx + movq %rbp, %rsp + popq %rbp + + ret + + 1: + + movq irbx(%rbx), %rdi /* rbx -> rdi #1 arg */ + movq ircx(%rbx), %rsi /* rcx -> rsi #2 arg */ + movq irdx(%rbx), %rdx /* rdx -> rdx #3 arg */ + movq irdi(%rbx), %rcx /* rdi -> rcx #4 arg */ + movq irsi(%rbx), %r8 /* rsi -> r8 #5 arg */ + + call *(%rax) + + movq %rax, irax(%rbx) /* save the return value */ + + popq %rbx + movq %rbp, %rsp + popq %rbp + + ret \ No newline at end of file diff --git a/lunaix-os/arch/x86/trace.c b/lunaix-os/arch/x86/trace.c new file mode 100644 index 0000000..3e06895 --- /dev/null +++ b/lunaix-os/arch/x86/trace.c @@ -0,0 +1,102 @@ +#include + +void +trace_print_transistion_short(struct hart_state* hstate) +{ + trace_log(" trigger: iv=%d, ecause=%p", + hart_vector_stamp(hstate), + hart_ecause(hstate)); +} + +#ifdef CONFIG_ARCH_X86_64 + +void +trace_print_transition_full(struct hart_state* hstate) +{ + trace_log("hart state transition"); + trace_log(" vector=%d, ecause=0x%x", + hart_vector_stamp(hstate), + hart_ecause(hstate)); + + trace_log(" rflags=0x%016lx", hstate->execp->rflags); + trace_log(" sp=0x%016lx, seg_sel=0x%04x", + hstate->execp->rsp, + hstate->execp->ss); + trace_log(" ip=0x%016lx, seg_sel=0x%04x", + hstate->execp->rip, + hstate->execp->cs); +} + +void +trace_dump_state(struct hart_state* hstate) +{ + struct regcontext* rh = &hstate->registers; + struct exec_param* ep = hstate->execp; + trace_log("hart state dump (depth=%d)", hstate->depth); + trace_log(" rax=0x%016lx, rbx=0x%016lx", + rh->rax, rh->rbx); + trace_log(" rcx=0x%016lx, rdx=0x%016lx", + rh->rcx, rh->rdx); + trace_log(" rdi=0x%016lx, rsi=0x%016lx", + rh->rdi, rh->rsi); + + trace_log(" r8=0x%016lx, r9=0x%016lx", + rh->r8, rh->r9); + trace_log(" r10=0x%016lx, r11=0x%016lx", + rh->r10, rh->r11); + trace_log(" r12=0x%016lx, r13=0x%016lx", + rh->r12, rh->r13); + trace_log(" r14=0x%016lx, r15=0x%016lx", + rh->r14, rh->r15); + + trace_log(" cs=0x%04x, rip=0x%016lx", + ep->cs, ep->rip); + trace_log(" ss=0x%04x, rsp=0x%016lx", + ep->ss, ep->rsp); + trace_log(" rflags=0x%016lx", + ep->rflags); +} + +#else + +void +trace_print_transition_full(struct hart_state* hstate) +{ + trace_log("hart state transition"); + trace_log(" vector=%d, ecause=0x%x", + hart_vector_stamp(hstate), + hart_ecause(hstate)); + trace_log(" eflags=0x%x", hstate->execp->eflags); + trace_log(" sp=%p, [seg_sel=0x%04x]", + hstate->execp->esp, + hstate->execp->ss); + trace_log(" ip=%p, seg_sel=0x%04x", + hstate->execp->eip, + hstate->execp->cs); +} + +void +trace_dump_state(struct hart_state* hstate) +{ + struct regcontext* rh = &hstate->registers; + struct exec_param* ep = hstate->execp; + trace_log("hart state dump (depth=%d)", hstate->depth); + trace_log(" eax=0x%08x, ebx=0x%08x, ecx=0x%08x", + rh->eax, rh->ebx, rh->ecx); + trace_log(" edx=0x%08x, ebp=0x%08x", + rh->edx, rh->ebp); + trace_log(" ds=0x%04x, edi=0x%08x", + rh->ds, rh->edi); + trace_log(" es=0x%04x, esi=0x%08x", + rh->es, rh->esi); + trace_log(" fs=0x%04x, gs=0x%x", + rh->fs, rh->gs); + trace_log(" cs=0x%04x, ip=0x%08x", + ep->cs, ep->eip); + trace_log(" [ss=0x%04x],sp=0x%08x", + ep->ss, ep->esp); + trace_log(" eflags=0x%08x", + ep->eflags); +} + +#endif \ No newline at end of file diff --git a/lunaix-os/hal/acpi/acpi.c b/lunaix-os/hal/acpi/acpi.c index 5732ec8..bc90ba1 100644 --- a/lunaix-os/hal/acpi/acpi.c +++ b/lunaix-os/hal/acpi/acpi.c @@ -85,15 +85,14 @@ acpi_init(struct device_def* devdef) size_t entry_n = (rsdt->header.length - sizeof(acpi_sdthdr_t)) >> 2; for (size_t i = 0; i < entry_n; i++) { - acpi_sdthdr_t* sdthdr = - (acpi_sdthdr_t*)((acpi_apic_t**)&(rsdt->entry))[i]; + acpi_sdthdr_t* sdthdr = __acpi_sdthdr(rsdt->entry[i]); switch (sdthdr->signature) { case ACPI_MADT_SIG: - madt_parse((acpi_madt_t*)sdthdr, ctx); + madt_parse(__acpi_madt(sdthdr), ctx); break; case ACPI_FADT_SIG: // FADT just a plain structure, no need to parse. - ctx->fadt = *(acpi_fadt_t*)sdthdr; + ctx->fadt = *__acpi_fadt(sdthdr); break; case ACPI_MCFG_SIG: mcfg_parse(sdthdr, ctx); diff --git a/lunaix-os/hal/acpi/parser/madt_parser.c b/lunaix-os/hal/acpi/parser/madt_parser.c index 3c05de1..c0b059d 100644 --- a/lunaix-os/hal/acpi/parser/madt_parser.c +++ b/lunaix-os/hal/acpi/parser/madt_parser.c @@ -16,16 +16,16 @@ madt_parse(acpi_madt_t* madt, acpi_context* toc) size_t so_idx = 0; while (ics_start < ics_end) { - acpi_ics_hdr_t* entry = (acpi_ics_hdr_t*)ics_start; + acpi_ics_hdr_t* entry = __acpi_ics_hdr(ics_start); switch (entry->type) { case ACPI_MADT_LAPIC: - toc->madt.apic = (acpi_apic_t*)entry; + toc->madt.apic = __acpi_apic(entry); break; case ACPI_MADT_IOAPIC: - toc->madt.ioapic = (acpi_ioapic_t*)entry; + toc->madt.ioapic = __acpi_ioapic(entry); break; case ACPI_MADT_INTSO: { - acpi_intso_t* intso_tbl = (acpi_intso_t*)entry; + acpi_intso_t* intso_tbl = __acpi_intso(entry); toc->madt.irq_exception[intso_tbl->source] = intso_tbl; break; } diff --git a/lunaix-os/hal/acpi/parser/mcfg_parser.c b/lunaix-os/hal/acpi/parser/mcfg_parser.c index 9a9541d..cbd139e 100644 --- a/lunaix-os/hal/acpi/parser/mcfg_parser.c +++ b/lunaix-os/hal/acpi/parser/mcfg_parser.c @@ -7,8 +7,9 @@ LOG_MODULE("MCFG") void mcfg_parse(acpi_sdthdr_t* mcfg, acpi_context* toc) { - size_t alloc_num = (mcfg->length - sizeof(acpi_sdthdr_t) - 8) / - sizeof(struct acpi_mcfg_alloc); + size_t alloc_num = (mcfg->length - sizeof(acpi_sdthdr_t) - 8); + alloc_num = alloc_num / sizeof(struct acpi_mcfg_alloc); + struct acpi_mcfg_alloc* allocs = (struct acpi_mcfg_alloc*)((ptr_t)mcfg + (sizeof(acpi_sdthdr_t) + 8)); diff --git a/lunaix-os/hal/char/serial.c b/lunaix-os/hal/char/serial.c index 826b3a6..dea044f 100644 --- a/lunaix-os/hal/char/serial.c +++ b/lunaix-os/hal/char/serial.c @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include @@ -162,7 +162,7 @@ __serial_read_async(struct device* dev, void* buf, off_t fpos, size_t len) static int __serial_read_page(struct device* dev, void* buf, off_t fpos) { - return serial_readbuf(serial_device(dev), (u8_t*)buf, MEM_PAGE); + return serial_readbuf(serial_device(dev), (u8_t*)buf, PAGE_SIZE); } static int @@ -181,7 +181,7 @@ __serial_write_async(struct device* dev, void* buf, off_t fpos, size_t len) static int __serial_write_page(struct device* dev, void* buf, off_t fpos) { - return serial_writebuf(serial_device(dev), (u8_t*)buf, MEM_PAGE); + return serial_writebuf(serial_device(dev), (u8_t*)buf, PAGE_SIZE); } static int diff --git a/lunaix-os/hal/char/uart/16550.h b/lunaix-os/hal/char/uart/16550.h index ccee415..5b4040b 100644 --- a/lunaix-os/hal/char/uart/16550.h +++ b/lunaix-os/hal/char/uart/16550.h @@ -17,7 +17,6 @@ #define UART_rDLM 1 #define UART_INTRX 0x1 -#define UART_DLAB (1 << 7) #define UART_LOOP (1 << 4) #define UART_rIE_ERBFI 1 @@ -29,6 +28,7 @@ #define UART_rLC_PAREN (1 << 3) #define UART_rLC_PAREVN (1 << 4) #define UART_rLC_SETBRK (1 << 6) +#define UART_rLC_DLAB (1 << 7) #define UART_rLS_THRE (1 << 5) #define UART_rLS_DR 1 @@ -116,13 +116,13 @@ uart_baud_divisor(struct uart16550* uart, int div) { u32_t rlc = uart->read_reg(uart, UART_rLC); - uart->write_reg(uart, UART_rLC, UART_DLAB | rlc); + uart->write_reg(uart, UART_rLC, UART_rLC_DLAB | rlc); u8_t ls = (div & 0xff), ms = (div & 0xff00) >> 8; uart->write_reg(uart, UART_rLS, ls); uart->write_reg(uart, UART_rMS, ms); - uart->write_reg(uart, UART_rLC, rlc & ~UART_DLAB); + uart->write_reg(uart, UART_rLC, rlc & ~UART_rLC_DLAB); return 0; } diff --git a/lunaix-os/hal/char/uart/16550_base.c b/lunaix-os/hal/char/uart/16550_base.c index d78f3cf..a84e3d0 100644 --- a/lunaix-os/hal/char/uart/16550_base.c +++ b/lunaix-os/hal/char/uart/16550_base.c @@ -42,6 +42,12 @@ uart_general_tx(struct serial_dev* sdev, u8_t* data, size_t len) return RXTX_DONE; } +#define UART_LCR_RESET \ + (UART_rLC_STOPB | \ + UART_rLC_PAREN | \ + UART_rLC_PAREVN | \ + UART_rLC_DLAB | 0b11) + static void uart_set_control_mode(struct uart16550* uart, tcflag_t cflags) { @@ -50,7 +56,7 @@ uart_set_control_mode(struct uart16550* uart, tcflag_t cflags) uart->cntl_save.rie |= (!!(cflags & _CREAD)) * UART_rIE_ERBFI; uart_setie(uart); - uart->cntl_save.rlc &= ~(UART_rLC_STOPB | UART_rLC_PAREN | UART_rLC_PAREVN | 0b11); + uart->cntl_save.rlc &= ~UART_LCR_RESET; uart->cntl_save.rlc |= (!!(cflags & _CSTOPB)) * UART_rLC_STOPB; uart->cntl_save.rlc |= (!!(cflags & _CPARENB)) * UART_rLC_PAREN; uart->cntl_save.rlc |= (!(cflags & _CPARODD)) * UART_rLC_PAREVN; diff --git a/lunaix-os/includes/hal/acpi/fadt.h b/lunaix-os/includes/hal/acpi/fadt.h index 339486d..07359f0 100644 --- a/lunaix-os/includes/hal/acpi/fadt.h +++ b/lunaix-os/includes/hal/acpi/fadt.h @@ -70,6 +70,7 @@ typedef struct acpi_fadt u8_t time_info[3]; u16_t boot_arch; } ACPI_TABLE_PACKED acpi_fadt_t; +#define __acpi_fadt(acpi_ptr) ((acpi_fadt_t*)__ptr(acpi_ptr)) // TODO: FADT parser & support diff --git a/lunaix-os/includes/hal/acpi/madt.h b/lunaix-os/includes/hal/acpi/madt.h index 538e521..c12ab28 100644 --- a/lunaix-os/includes/hal/acpi/madt.h +++ b/lunaix-os/includes/hal/acpi/madt.h @@ -16,6 +16,7 @@ typedef struct u8_t type; u8_t length; } ACPI_TABLE_PACKED acpi_ics_hdr_t; +#define __acpi_ics_hdr(acpi_ptr) ((acpi_ics_hdr_t*)__ptr(acpi_ptr)) /** * @brief ACPI Processor Local APIC Structure (PLAS) @@ -30,6 +31,7 @@ typedef struct u8_t apic_id; u32_t flags; } ACPI_TABLE_PACKED acpi_apic_t; +#define __acpi_apic(acpi_ptr) ((acpi_apic_t*)__ptr(acpi_ptr)) /** * @brief ACPI IO APIC Structure (IOAS) @@ -48,6 +50,7 @@ typedef struct // for a slave IOAPIC) u32_t gis_offset; } ACPI_TABLE_PACKED acpi_ioapic_t; +#define __acpi_ioapic(acpi_ptr) ((acpi_ioapic_t*)__ptr(acpi_ptr)) /** * @brief ACPI Interrupt Source Override (INTSO) @@ -69,18 +72,20 @@ typedef struct u32_t gsi; u16_t flags; } ACPI_TABLE_PACKED acpi_intso_t; +#define __acpi_intso(acpi_ptr) ((acpi_intso_t*)__ptr(acpi_ptr)) typedef struct { acpi_sdthdr_t header; - void* apic_addr; + u32_t apic_addr; u32_t flags; // Here is a bunch of packed ICS reside here back-to-back. } ACPI_TABLE_PACKED acpi_madt_t; +#define __acpi_madt(acpi_ptr) ((acpi_madt_t*)__ptr(acpi_ptr)) typedef struct { - void* apic_addr; + u32_t apic_addr; acpi_apic_t* apic; acpi_ioapic_t* ioapic; acpi_intso_t** irq_exception; diff --git a/lunaix-os/includes/hal/acpi/sdt.h b/lunaix-os/includes/hal/acpi/sdt.h index b055aa3..de8dc7d 100644 --- a/lunaix-os/includes/hal/acpi/sdt.h +++ b/lunaix-os/includes/hal/acpi/sdt.h @@ -18,11 +18,12 @@ typedef struct acpi_sdthdr u32_t vendor_id; u32_t vendor_rev; } ACPI_TABLE_PACKED acpi_sdthdr_t; +#define __acpi_sdthdr(acpi_ptr) ((acpi_sdthdr_t*)__ptr(acpi_ptr)) typedef struct acpi_rsdt { acpi_sdthdr_t header; - acpi_sdthdr_t* entry; + u32_t entry[0]; } ACPI_TABLE_PACKED acpi_rsdt_t; #endif /* __LUNAIX_ACPI_SDT_H */ diff --git a/lunaix-os/includes/klibc/ia_utils.h b/lunaix-os/includes/klibc/ia_utils.h index df7704f..ef621e3 100644 --- a/lunaix-os/includes/klibc/ia_utils.h +++ b/lunaix-os/includes/klibc/ia_utils.h @@ -1,6 +1,6 @@ #ifndef __LUNAIX_IAUTILS_H #define __LUNAIX_IAUTILS_H -char* itoa(int value, char* str, int base); +char* itoa(long value, char* str, int base); #endif /* __LUNAIX_IAUTILS_H */ diff --git a/lunaix-os/includes/lunaix/blkpart_gpt.h b/lunaix-os/includes/lunaix/blkpart_gpt.h index fdce191..ec9c9be 100644 --- a/lunaix-os/includes/lunaix/blkpart_gpt.h +++ b/lunaix-os/includes/lunaix/blkpart_gpt.h @@ -31,7 +31,7 @@ struct gpt_header u32_t ent_size; u32_t ent_cksum; // reserved start here -} PACKED; +} compact; struct gpt_entry { @@ -41,7 +41,7 @@ struct gpt_entry u64_t end_lba; u64_t attr_flags; char name[72]; -} PACKED; +} compact; int blkpart_probegpt(struct device* master); diff --git a/lunaix-os/includes/lunaix/boot_generic.h b/lunaix-os/includes/lunaix/boot_generic.h index dca7b9a..cc6ea08 100644 --- a/lunaix-os/includes/lunaix/boot_generic.h +++ b/lunaix-os/includes/lunaix/boot_generic.h @@ -68,7 +68,10 @@ void boot_end(struct boot_handoff*); void -boot_cleanup(); +boot_begin_arch_reserve(struct boot_handoff*); + +void +boot_clean_arch_reserve(struct boot_handoff*); static inline bool free_memregion(struct boot_mmapent* mmapent) diff --git a/lunaix-os/includes/lunaix/compiler.h b/lunaix-os/includes/lunaix/compiler.h index 78387bd..28ae36e 100644 --- a/lunaix-os/includes/lunaix/compiler.h +++ b/lunaix-os/includes/lunaix/compiler.h @@ -14,6 +14,8 @@ #define unreachable __builtin_unreachable() #define no_inline __attribute__((noinline)) +#define defualt weak + #define clz(bits) __builtin_clz(bits) #define sadd_overflow(a, b, of) __builtin_sadd_overflow(a, b, of) #define umul_overflow(a, b, of) __builtin_umul_overflow(a, b, of) @@ -32,7 +34,8 @@ #define cacheline_align align(cacheline_size) #define export_symbol(domain, namespace, symbol)\ - typeof(symbol)* must_emit __SYMEXPORT_Z##domain##_N##namespace##_S##symbol = &(symbol) + typeof(symbol)* must_emit __SYMEXPORT_Z##domain##_N##namespace##_S##symbol \ + = &(symbol) inline static void noret spin() diff --git a/lunaix-os/includes/lunaix/exebi/elf.h b/lunaix-os/includes/lunaix/exebi/elf.h new file mode 100644 index 0000000..73a71e5 --- /dev/null +++ b/lunaix-os/includes/lunaix/exebi/elf.h @@ -0,0 +1,106 @@ +/** + * @file elf.h + * @author Lunaixsky (lunaxisky@qq.com) + * @brief + * @version 0.1 + * @date 2024-07-05 + * + * Define generic structure that described in Executable and Linking Format + * specification. + * + * Define interface on manipulate such structure + * + * @copyright Copyright (c) 2024 + * + */ + +#ifndef __LUNAIX_ELF32_H +#define __LUNAIX_ELF32_H + +#include +#include + +#define ET_EXEC 2 +#define ET_DYN 3 + +#define PT_LOAD 1 +#define PT_INTERP 3 + +#define PF_X 0x1 +#define PF_W 0x2 +#define PF_R 0x4 + +#define EV_CURRENT 1 + +// [0x7f, 'E', 'L', 'F'] +#define ELFMAGIC_LE 0x464c457fU + +#define EI_CLASS 4 +#define EI_DATA 5 + +#define NO_LOADER 0 +#define DEFAULT_LOADER "usr/ld" + +struct elf_ehdr; +struct elf_phdr; + +struct elf +{ + const void* elf_file; + struct elf_ehdr eheader; + struct elf_phdr* pheaders; +}; + +#define declare_elf32(elf, elf_vfile) \ + struct elf elf = { .elf_file = elf_vfile, .pheaders = (void*)0 } + +int +elf_check_exec(const struct elf* elf, int type); + +int +elf_check_arch(const struct elf* elf); + +int +elf_open(struct elf* elf, const char* path); + +int +elf_openat(struct elf* elf, void* elf_vfile); + +int +elf_static_linked(const struct elf* elf); + +int +elf_close(struct elf* elf); + +/** + * @brief Try to find the PT_INTERP section. If found, copy it's content to + * path_out + * + * @param elf Opened elf32 descriptor + * @param path_out + * @param len size of path_out buffer + * @return int + */ +int +elf_find_loader(const struct elf* elf, char* path_out, size_t len); + +int +elf_read_ehdr(struct elf* elf); + +int +elf_read_phdr(struct elf* elf); + +/** + * @brief Estimate how much memeory will be acquired if we load all loadable + * sections.、 + * + * @param elf + * @return size_t + */ +size_t +elf_loadable_memsz(const struct elf* elf); + +#define SIZE_EHDR sizeof(struct elf_ehdr) +#define SIZE_PHDR sizeof(struct elf_phdr) + +#endif /* __LUNAIX_ELF32_H */ diff --git a/lunaix-os/includes/lunaix/exebi/elf32.h b/lunaix-os/includes/lunaix/exebi/elf32.h deleted file mode 100644 index 1cda2c7..0000000 --- a/lunaix-os/includes/lunaix/exebi/elf32.h +++ /dev/null @@ -1,130 +0,0 @@ -#ifndef __LUNAIX_ELF32_H -#define __LUNAIX_ELF32_H - -#include - -typedef unsigned int elf32_ptr_t; -typedef unsigned short elf32_hlf_t; -typedef unsigned int elf32_off_t; -typedef unsigned int elf32_swd_t; -typedef unsigned int elf32_wrd_t; - -#define ET_NONE 0 -#define ET_EXEC 2 -#define ET_DYN 3 - -#define PT_LOAD 1 -#define PT_INTERP 3 - -#define PF_X 0x1 -#define PF_W 0x2 -#define PF_R 0x4 - -#define EM_NONE 0 -#define EM_386 3 - -#define EV_CURRENT 1 - -// [0x7f, 'E', 'L', 'F'] -#define ELFMAGIC 0x464c457fU -#define ELFCLASS32 1 -#define ELFCLASS64 2 -#define ELFDATA2LSB 1 -#define ELFDATA2MSB 2 - -#define EI_CLASS 4 -#define EI_DATA 5 - -#define NO_LOADER 0 -#define DEFAULT_LOADER "usr/ld" - -struct elf32_ehdr -{ - u8_t e_ident[16]; - elf32_hlf_t e_type; - elf32_hlf_t e_machine; - elf32_wrd_t e_version; - elf32_ptr_t e_entry; - elf32_off_t e_phoff; - elf32_off_t e_shoff; - elf32_wrd_t e_flags; - elf32_hlf_t e_ehsize; - elf32_hlf_t e_phentsize; - elf32_hlf_t e_phnum; - elf32_hlf_t e_shentsize; - elf32_hlf_t e_shnum; - elf32_hlf_t e_shstrndx; -}; - -struct elf32_phdr -{ - elf32_wrd_t p_type; - elf32_off_t p_offset; - elf32_ptr_t p_va; - elf32_ptr_t p_pa; - elf32_wrd_t p_filesz; - elf32_wrd_t p_memsz; - elf32_wrd_t p_flags; - elf32_wrd_t p_align; -}; - -struct elf32 -{ - const void* elf_file; - struct elf32_ehdr eheader; - struct elf32_phdr* pheaders; -}; - -#define declare_elf32(elf, elf_vfile) \ - struct elf32 elf = { .elf_file = elf_vfile, .pheaders = (void*)0 } - -int -elf32_check_exec(const struct elf32* elf, int type); - -int -elf32_check_arch(const struct elf32* elf); - -int -elf32_open(struct elf32* elf, const char* path); - -int -elf32_openat(struct elf32* elf, void* elf_vfile); - -int -elf32_static_linked(const struct elf32* elf); - -int -elf32_close(struct elf32* elf); - -/** - * @brief Try to find the PT_INTERP section. If found, copy it's content to - * path_out - * - * @param elf Opened elf32 descriptor - * @param path_out - * @param len size of path_out buffer - * @return int - */ -int -elf32_find_loader(const struct elf32* elf, char* path_out, size_t len); - -int -elf32_read_ehdr(struct elf32* elf); - -int -elf32_read_phdr(struct elf32* elf); - -/** - * @brief Estimate how much memeory will be acquired if we load all loadable - * sections.、 - * - * @param elf - * @return size_t - */ -size_t -elf32_loadable_memsz(const struct elf32* elf); - -#define SIZE_EHDR sizeof(struct elf32_ehdr) -#define SIZE_PHDR sizeof(struct elf32_phdr) - -#endif /* __LUNAIX_ELF32_H */ diff --git a/lunaix-os/includes/lunaix/exec.h b/lunaix-os/includes/lunaix/exec.h index a49845e..64e0f2d 100644 --- a/lunaix-os/includes/lunaix/exec.h +++ b/lunaix-os/includes/lunaix/exec.h @@ -5,14 +5,15 @@ #include #include +#define MAX_PARAM_LEN 1024 +#define MAX_PARAM_SIZE 4096 + #define MAX_VAR_PAGES 8 #define DEFAULT_HEAP_PAGES 16 -struct exec_context; - struct load_context { - struct exec_container* container; + struct exec_host* container; ptr_t base; ptr_t end; ptr_t mem_sz; @@ -20,17 +21,24 @@ struct load_context ptr_t entry; }; -struct exec_container +struct exec_arrptr +{ + unsigned int len; + unsigned int size; + ptr_t raw; + ptr_t copied; +}; + + +struct exec_host { struct proc_info* proc; ptr_t vms_mnt; struct load_context exe; - // argv prependums - const char* argv_pp[2]; - const char** argv; - const char** envp; + struct exec_arrptr argv; + struct exec_arrptr envp; ptr_t stack_top; @@ -45,24 +53,23 @@ struct uexec_param char** envp; } compact; -#ifndef __USR_WRAPPER__ +int +exec_arch_prepare_entry(struct thread* thread, struct exec_host* container); int -exec_load_byname(struct exec_container* container, const char* filename); +exec_load_byname(struct exec_host* container, const char* filename); int -exec_load(struct exec_container* container, struct v_file* executable); +exec_load(struct exec_host* container, struct v_file* executable); int exec_kexecve(const char* filename, const char* argv[], const char* envp[]); void -exec_init_container(struct exec_container* param, +exec_init_container(struct exec_host* param, struct thread* thread, ptr_t vms, const char** argv, const char** envp); -#endif - #endif /* __LUNAIX_LOADER_H */ diff --git a/lunaix-os/includes/lunaix/fs/iso9660.h b/lunaix-os/includes/lunaix/fs/iso9660.h index 6fbdbbc..99fc484 100644 --- a/lunaix-os/includes/lunaix/fs/iso9660.h +++ b/lunaix-os/includes/lunaix/fs/iso9660.h @@ -49,7 +49,7 @@ struct iso_vol u8_t type; u8_t std_id[5]; // CD001 u8_t version; -} PACKED; +} compact; struct iso_vol_boot { @@ -57,7 +57,7 @@ struct iso_vol_boot u8_t sys_id[32]; u8_t boot_id[32]; u8_t reserved; // align to data line width -} PACKED; +} compact; struct iso_datetime { @@ -69,21 +69,21 @@ struct iso_datetime u8_t sec[2]; u8_t ms[2]; u8_t gmt; -} PACKED; +} compact; // 32bits both-byte-order integer typedef struct iso_bbo32 { u32_t le; // little-endian u32_t be; // big-endian -} PACKED iso_bbo32_t; +} compact iso_bbo32_t; // 16bits both-byte-order integer typedef struct iso_bbo16 { u16_t le; // little-endian u16_t be; // big-endian -} PACKED iso_bbo16_t; +} compact iso_bbo16_t; // (8.4) Describe a primary volume space struct iso_vol_primary @@ -114,7 +114,7 @@ struct iso_vol_primary struct iso_datetime ex_time; // expiration struct iso_datetime ef_time; // effective u8_t fstruct_ver; // file structure version, don't care! -} PACKED; // size 1124 +} compact; // size 1124 // Layout for Supplementary Vol. is almost identical to primary vol. // We ignore it for now. (see section 8.5, table 6) @@ -128,14 +128,14 @@ struct iso_partition u8_t part_id[32]; iso_bbo32_t part_addr; iso_bbo32_t part_size; -} PACKED; +} compact; // (6.10.4) MDU with variable record struct iso_var_mdu { u8_t len; u8_t content[0]; -} PACKED; +} compact; struct iso_datetime2 { @@ -146,7 +146,7 @@ struct iso_datetime2 u8_t min; u8_t sec; u8_t gmt; -} PACKED; +} compact; // (9.1) Directory Record [Embedded into Variable MDU] struct iso_drecord @@ -160,7 +160,7 @@ struct iso_drecord u8_t gap_sz; // size of gap if FU is interleaved. iso_bbo16_t vol_seq; struct iso_var_mdu name; -} PACKED; +} compact; struct iso_xattr { @@ -183,7 +183,7 @@ struct iso_xattr u8_t payload[0]; // There is also a escape sequence after payload, // It however marked as optional, hence we ignore it. -} PACKED; +} compact; /// /// -------- IEEE P1281 SUSP --------- @@ -197,7 +197,7 @@ struct isosu_base u16_t signature; u8_t length; u8_t version; -} PACKED; +} compact; struct isosu_er { @@ -207,7 +207,7 @@ struct isosu_er u8_t src_len; u8_t ext_ver; u8_t id_des_src[0]; -} PACKED; +} compact; /// /// -------- Rock Ridge Extension -------- @@ -234,35 +234,35 @@ struct isorr_px iso_bbo32_t uid; iso_bbo32_t gid; iso_bbo32_t sn; -} PACKED; +} compact; struct isorr_pn { struct isosu_base header; iso_bbo32_t dev_hi; iso_bbo32_t dev_lo; -} PACKED; +} compact; struct isorr_sl { struct isosu_base header; u8_t flags; char symlink[0]; -} PACKED; +} compact; struct isorr_nm { struct isosu_base header; u8_t flags; char name[0]; -} PACKED; +} compact; struct isorr_tf { struct isosu_base header; u8_t flags; char times[0]; -} PACKED; +} compact; /// /// -------- VFS integration --------- diff --git a/lunaix-os/includes/lunaix/fs/twimap.h b/lunaix-os/includes/lunaix/fs/twimap.h index 7adbc53..c9d56a2 100644 --- a/lunaix-os/includes/lunaix/fs/twimap.h +++ b/lunaix-os/includes/lunaix/fs/twimap.h @@ -3,8 +3,8 @@ #include -#define twimap_index(twimap, type) ((type)((twimap)->index)) -#define twimap_data(twimap, type) ((type)((twimap)->data)) +#define twimap_index(twimap, type) ((type)__ptr((twimap)->index)) +#define twimap_data(twimap, type) ((type)__ptr((twimap)->data)) extern struct v_file_ops twimap_file_ops; diff --git a/lunaix-os/includes/lunaix/mm/mm.h b/lunaix-os/includes/lunaix/mm/mm.h index d5b8edd..d72c405 100644 --- a/lunaix-os/includes/lunaix/mm/mm.h +++ b/lunaix-os/includes/lunaix/mm/mm.h @@ -55,11 +55,11 @@ struct mm_region // mapped file offset off_t foff; // mapped file length - u32_t flen; // XXX it seems that we don't need this actually.. ptr_t start; ptr_t end; u32_t attr; + size_t flen; void** index; // fast reference, to accelerate access to this very region. diff --git a/lunaix-os/includes/lunaix/mm/mmap.h b/lunaix-os/includes/lunaix/mm/mmap.h index 36f8904..307610b 100644 --- a/lunaix-os/includes/lunaix/mm/mmap.h +++ b/lunaix-os/includes/lunaix/mm/mmap.h @@ -11,6 +11,7 @@ struct mmap_param struct proc_mm* pvms; // process vm off_t offset; // mapped file offset size_t mlen; // mapped memory length + size_t flen; // mapped file length u32_t proct; // protections u32_t flags; // other options u32_t type; // region type diff --git a/lunaix-os/includes/lunaix/mm/pagetable.h b/lunaix-os/includes/lunaix/mm/pagetable.h index f289b7a..843ad03 100644 --- a/lunaix-os/includes/lunaix/mm/pagetable.h +++ b/lunaix-os/includes/lunaix/mm/pagetable.h @@ -99,25 +99,34 @@ struct __pte; typedef struct __pte pte_t; +#include #include #include -#define _LnTEP_AT(vm_mnt, sz) ( ((vm_mnt) | L0T_MASK) & ~(sz) ) -#define _L0TEP_AT(vm_mnt) ( ((vm_mnt) | L0T_MASK) & ~LFT_MASK ) -#define _L1TEP_AT(vm_mnt) ( ((vm_mnt) | L0T_MASK) & ~L3T_MASK ) -#define _L2TEP_AT(vm_mnt) ( ((vm_mnt) | L0T_MASK) & ~L2T_MASK ) -#define _L3TEP_AT(vm_mnt) ( ((vm_mnt) | L0T_MASK) & ~L1T_MASK ) -#define _LFTEP_AT(vm_mnt) ( ((vm_mnt) | L0T_MASK) & ~L0T_MASK ) +#define VMS_SELF VMS_SELF_MOUNT +#define VMS_SELF_L0TI (__index(VMS_SELF_MOUNT) / L0T_SIZE) + +#define _LnT_LEVEL_SIZE(n) ( L##n##T_SIZE / PAGE_SIZE ) +#define _LFTEP_SELF ( __index(VMS_SELF) ) +#define _L3TEP_SELF ( _LFTEP_SELF | (_LFTEP_SELF / _LnT_LEVEL_SIZE(3)) ) +#define _L2TEP_SELF ( _L3TEP_SELF | (_LFTEP_SELF / _LnT_LEVEL_SIZE(2)) ) +#define _L1TEP_SELF ( _L2TEP_SELF | (_LFTEP_SELF / _LnT_LEVEL_SIZE(1)) ) +#define _L0TEP_SELF ( _L1TEP_SELF | (_LFTEP_SELF / _LnT_LEVEL_SIZE(0)) ) + +#define _L0TEP_AT(vm_mnt) ( ((vm_mnt) | (_L0TEP_SELF & L0T_MASK)) ) +#define _L1TEP_AT(vm_mnt) ( ((vm_mnt) | (_L1TEP_SELF & L0T_MASK)) ) +#define _L2TEP_AT(vm_mnt) ( ((vm_mnt) | (_L2TEP_SELF & L0T_MASK)) ) +#define _L3TEP_AT(vm_mnt) ( ((vm_mnt) | (_L3TEP_SELF & L0T_MASK)) ) +#define _LFTEP_AT(vm_mnt) ( ((vm_mnt) | (_LFTEP_SELF & L0T_MASK)) ) #define _VM_OF(ptep) ( (ptr_t)(ptep) & ~L0T_MASK ) #define _VM_PFN_OF(ptep) ( ((ptr_t)(ptep) & L0T_MASK) / sizeof(pte_t) ) -#define VMS_SELF ( ~L0T_MASK & VMS_MASK ) #define __LnTI_OF(ptep, n)\ - (_VM_PFN_OF(ptep) * LFT_SIZE / L##n##T_SIZE) + ( __index(_VM_PFN_OF(ptep) * LFT_SIZE / L##n##T_SIZE) ) #define __LnTEP(ptep, va, n)\ - ( (pte_t*)_L##n##TEP_AT(_VM_OF(ptep)) + (((va) & VMS_MASK) / L##n##T_SIZE) ) + ( (pte_t*)_L##n##TEP_AT(_VM_OF(ptep)) + (__index(va) / L##n##T_SIZE) ) #define __LnTEP_OF(ptep, n)\ ( (pte_t*)_L##n##TEP_AT(_VM_OF(ptep)) + __LnTI_OF(ptep, n)) @@ -128,12 +137,6 @@ typedef struct __pte pte_t; #define _has_LnT(n) (L##n##T_SIZE != LFT_SIZE) #define LnT_ENABLED(n) _has_LnT(n) -#define ptep_with_level(ptep, lvl_size) \ - ({ \ - ptr_t __p = _LnTEP_AT(_VM_OF(ptep), lvl_size); \ - ((ptr_t)(ptep) & __p) == __p; \ - }) - extern pte_t alloc_kpage_at(pte_t* ptep, pte_t pte, int order); @@ -185,13 +188,13 @@ ptep_vfn(pte_t* ptep) static inline ptr_t ptep_va(pte_t* ptep, size_t lvl_size) { - return ((ptr_t)ptep) / sizeof(pte_t) * lvl_size; + return __vaddr(ptep_pfn(ptep) * lvl_size); } static inline ptr_t ptep_vm_mnt(pte_t* ptep) { - return _VM_OF(ptep); + return __vaddr(_VM_OF(ptep)); } /** @@ -408,7 +411,7 @@ l3te_index(pte_t* ptep) { static inline pfn_t pfn(ptr_t addr) { - return (addr / PAGE_SIZE) & VMS_MASK; + return __index(addr) / PAGE_SIZE; } static inline size_t @@ -428,7 +431,7 @@ va_offset(ptr_t addr) { static inline ptr_t page_addr(ptr_t pfn) { - return pfn * PAGE_SIZE; + return __vaddr(pfn * PAGE_SIZE); } static inline ptr_t @@ -465,7 +468,7 @@ mkptep_pn(ptr_t vm_mnt, ptr_t pn) static inline pfn_t pfn_at(ptr_t va, size_t lvl_size) { - return va / lvl_size; + return __index(va) / lvl_size; } @@ -508,6 +511,24 @@ mkl0tep_va(ptr_t mnt, ptr_t va) return mkl0tep(mkptep_va(mnt, va)); } +static inline pte_t* +mkl1tep_va(ptr_t mnt, ptr_t va) +{ + return mkl1tep(mkptep_va(mnt, va)); +} + +static inline pte_t* +mkl2tep_va(ptr_t mnt, ptr_t va) +{ + return mkl2tep(mkptep_va(mnt, va)); +} + +static inline pte_t* +mkl3tep_va(ptr_t mnt, ptr_t va) +{ + return mkl3tep(mkptep_va(mnt, va)); +} + static inline bool pt_last_level(int level) { @@ -517,13 +538,45 @@ pt_last_level(int level) static inline ptr_t va_mntpoint(ptr_t va) { - return _VM_OF(va); + return __vaddr(_VM_OF(va)); } -static inline ptr_t -va_actual(ptr_t va) +static inline unsigned int +va_level_index(ptr_t va, size_t lvl_size) +{ + return (va / lvl_size) & _PAGE_LEVEL_MASK; +} + +static inline bool +l0tep_implie(pte_t* ptep, ptr_t addr) +{ + return ptep_va(ptep, L0T_SIZE) == __vaddr(addr); +} + +static inline bool +is_ptep(ptr_t addr) +{ + ptr_t mnt = va_mntpoint(addr); + return mnt == VMS_MOUNT_1 || mnt == VMS_SELF; +} + +static inline bool +vmnt_packed(pte_t* ptep) +{ + return is_ptep(__ptr(ptep)); +} + +static inline bool +active_vms(ptr_t vmnt) +{ + return vmnt == VMS_SELF; +} + +static inline bool +l0tep_impile_vmnts(pte_t* ptep) { - return page_addr(_VM_OF(va) ^ va); + return l0tep_implie(ptep, VMS_SELF) || + l0tep_implie(ptep, VMS_MOUNT_1); } #endif /* __LUNAIX_PAGETABLE_H */ diff --git a/lunaix-os/includes/lunaix/process.h b/lunaix-os/includes/lunaix/process.h index fe33fa2..92b9407 100644 --- a/lunaix-os/includes/lunaix/process.h +++ b/lunaix-os/includes/lunaix/process.h @@ -76,7 +76,7 @@ struct thread { /* Any change to *critical section*, including layout, size - must be reflected in arch/i386/interrupt.S.inc to avoid + must be reflected in arch/x86/interrupt.S.inc to avoid disaster! */ struct diff --git a/lunaix-os/includes/lunaix/signal.h b/lunaix-os/includes/lunaix/signal.h index e983846..556823b 100644 --- a/lunaix-os/includes/lunaix/signal.h +++ b/lunaix-os/includes/lunaix/signal.h @@ -1,6 +1,7 @@ #ifndef __LUNAIX_SIGNAL_H #define __LUNAIX_SIGNAL_H +#include #include #define _SIG_NUM 16 diff --git a/lunaix-os/includes/lunaix/syscall_utils.h b/lunaix-os/includes/lunaix/syscall_utils.h index 640e386..d29056d 100644 --- a/lunaix-os/includes/lunaix/syscall_utils.h +++ b/lunaix-os/includes/lunaix/syscall_utils.h @@ -3,8 +3,10 @@ #include #include +#include -#define DO_STATUS(errno) SYSCALL_ESTATUS(syscall_result(errno)) -#define DO_STATUS_OR_RETURN(errno) ({ errno < 0 ? DO_STATUS(errno) : errno; }) +#define DO_STATUS(errno) SYSCALL_ESTATUS(syscall_result(errno)) +#define DO_STATUS_OR_RETURN(errno) \ + ({ errno < 0 ? DO_STATUS(errno) : errno; }) #endif /* __LUNAIX_SYSCALL_UTILS_H */ diff --git a/lunaix-os/includes/lunaix/types.h b/lunaix-os/includes/lunaix/types.h index 9aff5ab..52faac3 100644 --- a/lunaix-os/includes/lunaix/types.h +++ b/lunaix-os/includes/lunaix/types.h @@ -5,8 +5,6 @@ #include #include -#define PACKED __attribute__((packed)) - // TODO: WTERMSIG // TODO: replace the integer type with these. To make thing more portable. @@ -14,10 +12,15 @@ typedef unsigned char u8_t; typedef unsigned short u16_t; typedef unsigned int u32_t; -typedef unsigned long long u64_t; typedef unsigned long ptr_t; typedef unsigned long reg_t; +#ifndef CONFIG_ARCH_BITS_64 +typedef unsigned long long u64_t; +#else +typedef unsigned long u64_t; +#endif + typedef int pid_t; typedef signed long ssize_t; @@ -43,4 +46,8 @@ typedef int bool; (ptr) ? (type*)((char*)__mptr - offsetof(type, member)) : 0; \ }) +#define __ptr(val) ((ptr_t)(val)) + +typedef va_list* sc_va_list; + #endif /* __LUNAIX_TYPES_H */ diff --git a/lunaix-os/includes/usr/lunaix/mann_flags.h b/lunaix-os/includes/usr/lunaix/mann_flags.h index cf99def..dcd3a34 100644 --- a/lunaix-os/includes/usr/lunaix/mann_flags.h +++ b/lunaix-os/includes/usr/lunaix/mann_flags.h @@ -30,4 +30,14 @@ #define MS_INVALIDATE 0x4 #define MS_INVALIDATE_ALL 0x8 +struct usr_mmap_param +{ + void* addr; + unsigned long length; + int proct; + int flags; + int fd; + unsigned long offset; +}; + #endif /* __LUNAIX_MANN_FLAGS_H */ diff --git a/lunaix-os/includes/usr/lunaix/syscallid.h b/lunaix-os/includes/usr/lunaix/syscallid.h index ce55519..7e995f1 100644 --- a/lunaix-os/includes/usr/lunaix/syscallid.h +++ b/lunaix-os/includes/usr/lunaix/syscallid.h @@ -74,6 +74,6 @@ #define __SYSCALL_th_detach 62 #define __SYSCALL_th_sigmask 63 -#define __SYSCALL_MAX 0x100 +#define __SYSCALL_MAX 0x200 #endif /* __LUNAIX_SYSCALLID_H */ diff --git a/lunaix-os/includes/usr/lunaix/threads.h b/lunaix-os/includes/usr/lunaix/threads.h index a5d322e..a20b52f 100644 --- a/lunaix-os/includes/usr/lunaix/threads.h +++ b/lunaix-os/includes/usr/lunaix/threads.h @@ -3,9 +3,9 @@ #include "types.h" -struct uthread_info { - void* th_stack_top; - size_t th_stack_sz; +struct uthread_param { + void* th_handler; + void* arg1; }; #endif /* __LUNAIX_USR_THREADS_H */ diff --git a/lunaix-os/kernel.mk b/lunaix-os/kernel.mk index 86f4668..69a16db 100644 --- a/lunaix-os/kernel.mk +++ b/lunaix-os/kernel.mk @@ -1,7 +1,7 @@ -include os.mkinc include toolchain.mkinc +include lunabuild.mkinc -include .builder/lbuild.mkinc +include $(lbuild_mkinc) kbin_dir := $(BUILD_DIR) kbin := $(BUILD_NAME) @@ -10,16 +10,19 @@ ksrc_objs := $(addsuffix .o,$(_LBUILD_SRCS)) ksrc_deps := $(addsuffix .d,$(_LBUILD_SRCS)) khdr_opts := $(addprefix -include ,$(_LBUILD_HDRS)) kinc_opts := $(addprefix -I,$(_LBUILD_INCS)) -config_h += -include.builder/configs.h +config_h += -include $(lbuild_config_h) tmp_kbin := $(BUILD_DIR)/tmpk.bin ksymtable := lunaix_ksyms.o +klinking := link/lunaix.ld CFLAGS += $(khdr_opts) $(kinc_opts) $(config_h) -MMD -MP -include $(ksrc_deps) -%.S.o: %.S kernel.mk +all_linkable = $(filter-out $(klinking),$(1)) + +%.S.o: %.S $(khdr_files) kernel.mk $(call status_,AS,$<) @$(CC) $(CFLAGS) -c $< -o $@ @@ -27,25 +30,42 @@ CFLAGS += $(khdr_opts) $(kinc_opts) $(config_h) -MMD -MP $(call status_,CC,$<) @$(CC) $(CFLAGS) -c $< -o $@ -$(tmp_kbin): $(ksrc_objs) + +$(klinking): link/lunaix.ldx + $(call status_,PP,$<) + @$(CC) $(CFLAGS) -x c -E -P $< -o $@ + + +$(tmp_kbin): $(klinking) $(ksrc_objs) $(call status_,LD,$@) - @$(CC) -T link/linker.ld $(config_h) $(LDFLAGS) -o $@ $^ + + @$(CC) -T $(klinking) $(config_h) $(LDFLAGS) -o $@ \ + $(call all_linkable,$^) + $(ksymtable): $(tmp_kbin) $(call status_,KSYM,$@) @scripts/gen_ksymtable.sh DdRrTtAGg $< > .lunaix_ksymtable.S + @$(CC) $(CFLAGS) -c .lunaix_ksymtable.S -o $@ + .PHONY: __do_relink -__do_relink: $(ksrc_objs) $(ksymtable) +__do_relink: $(klinking) $(ksrc_objs) $(ksymtable) $(call status_,LD,$(kbin)) - @$(CC) -T link/linker.ld $(config_h) $(LDFLAGS) -o $(kbin) $^ + + @$(CC) -T $(klinking) $(config_h) $(LDFLAGS) -o $(kbin) \ + $(call all_linkable,$^) + @rm $(tmp_kbin) + .PHONY: all all: __do_relink + clean: @rm -f $(ksrc_objs) @rm -f $(ksrc_deps) + @rm -f $(klinking) @rm -f .lunaix_ksymtable.S $(ksymtable) \ No newline at end of file diff --git a/lunaix-os/kernel/boot_helper.c b/lunaix-os/kernel/boot_helper.c index 7f324e4..3652959 100644 --- a/lunaix-os/kernel/boot_helper.c +++ b/lunaix-os/kernel/boot_helper.c @@ -17,14 +17,9 @@ void boot_begin(struct boot_handoff* bhctx) { bhctx->prepare(bhctx); - - // Identity-map the first 3GiB address spaces - pte_t* ptep = mkl0tep(mkptep_va(VMS_SELF, 0)); - pte_t pte = mkpte_prot(KERNEL_DATA); - size_t count = page_count(KERNEL_RESIDENT, L0T_SIZE); - - vmm_set_ptes_contig(ptep, pte_mkhuge(pte), L0T_SIZE, count); + boot_begin_arch_reserve(bhctx); + // 将内核占据的页,包括前1MB,hhk_init 设为已占用 size_t pg_count = leaf_count(to_kphysical(__kexec_end)); pmm_onhold_range(0, pg_count); @@ -70,18 +65,8 @@ boot_end(struct boot_handoff* bhctx) } bhctx->release(bhctx); -} -/** - * @brief Clean up the boot stage code and data - * - */ -void -boot_cleanup() -{ - pte_t* ptep = mkl0tep(mkptep_va(VMS_SELF, 0)); - size_t count = page_count(KERNEL_RESIDENT, L0T_SIZE); - vmm_unset_ptes(ptep, count); + boot_clean_arch_reserve(bhctx); } void diff --git a/lunaix-os/kernel/debug/trace.c b/lunaix-os/kernel/debug/trace.c index 66e5505..e238526 100644 --- a/lunaix-os/kernel/debug/trace.c +++ b/lunaix-os/kernel/debug/trace.c @@ -71,14 +71,14 @@ static char* ksym_getstr(struct ksym_entry* sym) { if (!sym) { - return "???"; + return NULL; } return sym->label; } static inline bool valid_fp(ptr_t ptr) { - ptr_t start = ROUNDUP(current_thread->kstack - KSTACK_SIZE, MEM_PAGE); + ptr_t start = ROUNDUP(current_thread->kstack - KSTACK_SIZE, PAGE_SIZE); return (start < ptr && ptr < current_thread->kstack) || arch_valid_fp(ptr); @@ -121,10 +121,10 @@ trace_walkback(struct trace_record* tb_buffer, static inline void trace_print_code_entry(ptr_t sym_pc, ptr_t inst_pc, char* sym) { - if (sym_pc) { + if (sym) { trace_log("%s+%p", sym, inst_pc - sym_pc); } else { - trace_log("%s [%p]", sym, sym_pc); + trace_log("??? [%p]", inst_pc); } } @@ -161,7 +161,7 @@ static void trace_printswctx(const struct hart_state* hstate, bool from_usr, bool to_usr) { - struct ksym_entry* sym = trace_sym_lookup(hstate->execp->eip); + struct ksym_entry* sym = trace_sym_lookup(hart_pc(hstate)); trace_log("^^^^^ --- %s", to_usr ? "user" : "kernel"); trace_print_transistion_short(hstate); diff --git a/lunaix-os/kernel/device/device.c b/lunaix-os/kernel/device/device.c index d3552c6..d32ca32 100644 --- a/lunaix-os/kernel/device/device.c +++ b/lunaix-os/kernel/device/device.c @@ -292,10 +292,14 @@ device_alert_poller(struct device* dev, int poll_evt) iopoll_wake_pollers(&dev->pollers); } -__DEFINE_LXSYSCALL3(int, ioctl, int, fd, int, req, va_list, args) +__DEFINE_LXSYSCALL3(int, ioctl, int, fd, int, req, sc_va_list, _args) { int errno = -1; struct v_fd* fd_s; + va_list args; + + convert_valist(&args, _args); + if ((errno &= vfs_getfd(fd, &fd_s))) { goto done; } diff --git a/lunaix-os/kernel/device/poll.c b/lunaix-os/kernel/device/poll.c index 58d3621..493d5d3 100644 --- a/lunaix-os/kernel/device/poll.c +++ b/lunaix-os/kernel/device/poll.c @@ -244,9 +244,13 @@ iopoll_install(struct thread* thread, struct v_fd* fd) return pld; } -__DEFINE_LXSYSCALL2(int, pollctl, int, action, va_list, va) +__DEFINE_LXSYSCALL2(int, pollctl, int, action, sc_va_list, _ap) { int retcode = 0; + va_list va; + + convert_valist(&va, _ap); + switch (action) { case _SPOLL_ADD: { int* ds = va_arg(va, int*); diff --git a/lunaix-os/kernel/exe/LBuild b/lunaix-os/kernel/exe/LBuild index 8b24498..3ab25b4 100644 --- a/lunaix-os/kernel/exe/LBuild +++ b/lunaix-os/kernel/exe/LBuild @@ -1,4 +1,4 @@ -use("elf32") +use("elf-generic") sources([ "exec.c" diff --git a/lunaix-os/kernel/exe/elf-generic/LBuild b/lunaix-os/kernel/exe/elf-generic/LBuild new file mode 100644 index 0000000..80f3a1e --- /dev/null +++ b/lunaix-os/kernel/exe/elf-generic/LBuild @@ -0,0 +1,4 @@ +sources([ + "elfbfmt.c", + "ldelf.c" +]) \ No newline at end of file diff --git a/lunaix-os/kernel/exe/elf32/elf32bfmt.c b/lunaix-os/kernel/exe/elf-generic/elfbfmt.c similarity index 61% rename from lunaix-os/kernel/exe/elf32/elf32bfmt.c rename to lunaix-os/kernel/exe/elf-generic/elfbfmt.c index da94735..d7b09f1 100644 --- a/lunaix-os/kernel/exe/elf32/elf32bfmt.c +++ b/lunaix-os/kernel/exe/elf-generic/elfbfmt.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -6,34 +6,34 @@ #include static inline int -elf32_read(struct v_file* elf, void* data, size_t off, size_t len) +elf_read(struct v_file* elf, void* data, size_t off, size_t len) { // it is wise to do cached read return pcache_read(elf->inode, data, len, off); } static int -elf32_do_open(struct elf32* elf, struct v_file* elf_file) +elf_do_open(struct elf* elf, struct v_file* elf_file) { int status = 0; elf->pheaders = NULL; elf->elf_file = elf_file; - if ((status = elf32_read_ehdr(elf)) < 0) { - elf32_close(elf); + if ((status = elf_read_ehdr(elf)) < 0) { + elf_close(elf); return status; } - if ((status = elf32_read_phdr(elf)) < 0) { - elf32_close(elf); + if ((status = elf_read_phdr(elf)) < 0) { + elf_close(elf); return status; } return 0; } -int -elf32_open(struct elf32* elf, const char* path) +defualt int +elf_open(struct elf* elf, const char* path) { struct v_dnode* elfdn; struct v_file* elffile; @@ -47,19 +47,19 @@ elf32_open(struct elf32* elf, const char* path) return error; } - return elf32_do_open(elf, elffile); + return elf_do_open(elf, elffile); } -int -elf32_openat(struct elf32* elf, void* elf_vfile) +defualt int +elf_openat(struct elf* elf, void* elf_vfile) { // so the ref count kept in sync vfs_ref_file(elf_vfile); - return elf32_do_open(elf, elf_vfile); + return elf_do_open(elf, elf_vfile); } -int -elf32_close(struct elf32* elf) +defualt int +elf_close(struct elf* elf) { if (elf->pheaders) { vfree(elf->pheaders); @@ -74,11 +74,11 @@ elf32_close(struct elf32* elf) return 0; } -int -elf32_static_linked(const struct elf32* elf) +defualt int +elf_static_linked(const struct elf* elf) { for (size_t i = 0; i < elf->eheader.e_phnum; i++) { - struct elf32_phdr* phdre = &elf->pheaders[i]; + struct elf_phdr* phdre = &elf->pheaders[i]; if (phdre->p_type == PT_INTERP) { return 0; } @@ -86,8 +86,8 @@ elf32_static_linked(const struct elf32* elf) return 1; } -size_t -elf32_loadable_memsz(const struct elf32* elf) +defualt size_t +elf_loadable_memsz(const struct elf* elf) { // XXX: Hmmmm, I am not sure if we need this. This is designed to be handy // if we decided to map the heap region before transfer to loader. As @@ -96,7 +96,7 @@ elf32_loadable_memsz(const struct elf32* elf) size_t sz = 0; for (size_t i = 0; i < elf->eheader.e_phnum; i++) { - struct elf32_phdr* phdre = &elf->pheaders[i]; + struct elf_phdr* phdre = &elf->pheaders[i]; if (phdre->p_type == PT_LOAD) { sz += phdre->p_memsz; } @@ -105,8 +105,8 @@ elf32_loadable_memsz(const struct elf32* elf) return sz; } -int -elf32_find_loader(const struct elf32* elf, char* path_out, size_t len) +defualt int +elf_find_loader(const struct elf* elf, char* path_out, size_t len) { int retval = NO_LOADER; @@ -115,14 +115,14 @@ elf32_find_loader(const struct elf32* elf, char* path_out, size_t len) struct v_file* elfile = (struct v_file*)elf->elf_file; for (size_t i = 0; i < elf->eheader.e_phnum; i++) { - struct elf32_phdr* phdre = &elf->pheaders[i]; + struct elf_phdr* phdre = &elf->pheaders[i]; if (phdre->p_type == PT_INTERP) { if (len >= phdre->p_filesz) { return EINVAL; } retval = - elf32_read(elfile, path_out, phdre->p_offset, phdre->p_filesz); + elf_read(elfile, path_out, phdre->p_offset, phdre->p_filesz); if (retval < 0) { return retval; @@ -135,16 +135,16 @@ elf32_find_loader(const struct elf32* elf, char* path_out, size_t len) return retval; } -int -elf32_read_ehdr(struct elf32* elf) +defualt int +elf_read_ehdr(struct elf* elf) { struct v_file* elfile = (struct v_file*)elf->elf_file; - return elf32_read(elfile, (void*)&elf->eheader, 0, SIZE_EHDR); + return elf_read(elfile, (void*)&elf->eheader, 0, SIZE_EHDR); } -int -elf32_read_phdr(struct elf32* elf) +defualt int +elf_read_phdr(struct elf* elf) { int status = 0; @@ -153,13 +153,13 @@ elf32_read_phdr(struct elf32* elf) size_t entries = elf->eheader.e_phnum; size_t tbl_sz = entries * SIZE_PHDR; - struct elf32_phdr* phdrs = valloc(tbl_sz); + struct elf_phdr* phdrs = valloc(tbl_sz); if (!phdrs) { return ENOMEM; } - status = elf32_read(elfile, phdrs, elf->eheader.e_phoff, tbl_sz); + status = elf_read(elfile, phdrs, elf->eheader.e_phoff, tbl_sz); if (status < 0) { vfree(phdrs); @@ -170,20 +170,18 @@ elf32_read_phdr(struct elf32* elf) return entries; } -int -elf32_check_exec(const struct elf32* elf, int type) +defualt int +elf_check_exec(const struct elf* elf, int type) { - const struct elf32_ehdr* ehdr = &elf->eheader; + const struct elf_ehdr* ehdr = &elf->eheader; return (ehdr->e_entry) && ehdr->e_type == type; } -int -elf32_check_arch(const struct elf32* elf) +defualt int +elf_check_arch(const struct elf* elf) { - const struct elf32_ehdr* ehdr = &elf->eheader; + const struct elf_ehdr* ehdr = &elf->eheader; - return *(u32_t*)(ehdr->e_ident) == ELFMAGIC && - ehdr->e_ident[EI_CLASS] == ELFCLASS32 && - ehdr->e_ident[EI_DATA] == ELFDATA2LSB && ehdr->e_machine == EM_386; + return *(u32_t*)(ehdr->e_ident) == ELFMAGIC_LE; } \ No newline at end of file diff --git a/lunaix-os/kernel/exe/elf32/ldelf32.c b/lunaix-os/kernel/exe/elf-generic/ldelf.c similarity index 73% rename from lunaix-os/kernel/exe/elf32/ldelf32.c rename to lunaix-os/kernel/exe/elf-generic/ldelf.c index 69ae939..eaabf16 100644 --- a/lunaix-os/kernel/exe/elf32/ldelf32.c +++ b/lunaix-os/kernel/exe/elf-generic/ldelf.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -7,9 +7,9 @@ #include int -elf32_smap(struct load_context* ldctx, - const struct elf32* elf, - struct elf32_phdr* phdre, +elf_smap(struct load_context* ldctx, + const struct elf* elf, + struct elf_phdr* phdre, uintptr_t base_va) { struct v_file* elfile = (struct v_file*)elf->elf_file; @@ -28,12 +28,13 @@ elf32_smap(struct load_context* ldctx, } uintptr_t va = phdre->p_va + base_va; - struct exec_container* container = ldctx->container; + struct exec_host* container = ldctx->container; struct mmap_param param = { .vms_mnt = container->vms_mnt, .pvms = vmspace(container->proc), .proct = proct, .offset = page_aligned(phdre->p_offset), .mlen = page_upaligned(phdre->p_memsz), + .flen = phdre->p_filesz, .flags = MAP_FIXED | MAP_PRIVATE, .type = REGION_TYPE_CODE }; @@ -58,25 +59,25 @@ load_executable(struct load_context* context, const struct v_file* exefile) int errno = 0; char* ldpath = NULL; - struct elf32 elf; - struct exec_container* container = context->container; + struct elf elf; + struct exec_host* container = context->container; - if ((errno = elf32_openat(&elf, exefile))) { + if ((errno = elf_openat(&elf, exefile))) { goto done; } - if (!elf32_check_arch(&elf)) { + if (!elf_check_arch(&elf)) { errno = EINVAL; goto done; } - if (!(elf32_check_exec(&elf, ET_EXEC) || elf32_check_exec(&elf, ET_DYN))) { + if (!(elf_check_exec(&elf, ET_EXEC) || elf_check_exec(&elf, ET_DYN))) { errno = ENOEXEC; goto done; } ldpath = valloc(256); - errno = elf32_find_loader(&elf, ldpath, 256); + errno = elf_find_loader(&elf, ldpath, 256); uintptr_t load_base = 0; if (errno < 0) { @@ -84,20 +85,18 @@ load_executable(struct load_context* context, const struct v_file* exefile) } if (errno != NO_LOADER) { - container->argv_pp[1] = ldpath; - // close old elf - if ((errno = elf32_close(&elf))) { + if ((errno = elf_close(&elf))) { goto done; } // open the loader instead - if ((errno = elf32_open(&elf, ldpath))) { + if ((errno = elf_open(&elf, ldpath))) { goto done; } // Is this the valid loader? - if (!elf32_static_linked(&elf) || !elf32_check_exec(&elf, ET_DYN)) { + if (!elf_static_linked(&elf) || !elf_check_exec(&elf, ET_DYN)) { errno = ELIBBAD; goto done_close_elf32; } @@ -110,7 +109,7 @@ load_executable(struct load_context* context, const struct v_file* exefile) struct v_file* elfile = (struct v_file*)elf.elf_file; for (size_t i = 0; i < elf.eheader.e_phnum && !errno; i++) { - struct elf32_phdr* phdr = &elf.pheaders[i]; + struct elf_phdr* phdr = &elf.pheaders[i]; if (phdr->p_type != PT_LOAD) { continue; @@ -122,15 +121,13 @@ load_executable(struct load_context* context, const struct v_file* exefile) break; } - errno = elf32_smap(context, &elf, phdr, load_base); + errno = elf_smap(context, &elf, phdr, load_base); } done_close_elf32: - elf32_close(&elf); + elf_close(&elf); done: - if (!container->argv_pp[1]) { - vfree_safe(ldpath); - } + vfree_safe(ldpath); return errno; } diff --git a/lunaix-os/kernel/exe/elf32/LBuild b/lunaix-os/kernel/exe/elf32/LBuild deleted file mode 100644 index ef8cd25..0000000 --- a/lunaix-os/kernel/exe/elf32/LBuild +++ /dev/null @@ -1,4 +0,0 @@ -sources([ - "elf32bfmt.c", - "ldelf32.c" -]) \ No newline at end of file diff --git a/lunaix-os/kernel/exe/exec.c b/lunaix-os/kernel/exe/exec.c index 0f6e4ec..38c2121 100644 --- a/lunaix-os/kernel/exe/exec.c +++ b/lunaix-os/kernel/exe/exec.c @@ -16,8 +16,72 @@ #include +#define _push(ptr, type, val) \ + do { \ + ptr = __ptr(&((type*)ptr)[-1]); \ + *((type*)ptr) = (val); \ + } while(0) + +static int +__place_arrayptrs(struct exec_host* container, struct exec_arrptr* param) +{ + int len; + ptr_t usp, usp_top; + ptr_t* ptrs; + unsigned int* reloc_off; + + usp_top = container->stack_top; + usp = usp_top; + ptrs = (ptr_t*)param->raw; + + if (!param->len) { + _push(usp, unsigned int, 0); + + goto done; + } + + len = param->len; + reloc_off = valloc(len * sizeof(unsigned int)); + + char* el; + size_t el_sz, sz_acc = 0; + for (int i = 0; i < len; i++) + { + el= (char*)ptrs[i]; + el_sz = strnlen(el, MAX_PARAM_SIZE) + 1; + + usp -= el_sz; + sz_acc += el_sz; + strncpy((char*)usp, el, el_sz); + + reloc_off[i] = sz_acc; + } + + param->size = sz_acc; + + ptr_t* toc = (ptr_t*)(usp) - 1; + toc[0] = 0; + + toc = &toc[-1]; + for (int i = 0, j = len - 1; i < len; i++, j--) + { + toc[-i] = usp_top - (ptr_t)reloc_off[j]; + } + + toc[-len] = (ptr_t)len; + + usp = __ptr(&toc[-len]); + param->copied = __ptr(&toc[-len + 1]); + + vfree(reloc_off); + +done: + container->stack_top = usp; + return 0; +} + void -exec_init_container(struct exec_container* param, +exec_init_container(struct exec_host* param, struct thread* thread, ptr_t vms, const char** argv, @@ -25,90 +89,89 @@ exec_init_container(struct exec_container* param, { assert(thread->ustack); ptr_t ustack_top = align_stack(thread->ustack->end - 1); - *param = (struct exec_container){ .proc = thread->process, - .vms_mnt = vms, - .exe = { .container = param }, - .argv_pp = { 0, 0 }, - .argv = argv, - .envp = envp, - .stack_top = ustack_top }; + *param = (struct exec_host) + { + .proc = thread->process, + .vms_mnt = vms, + .exe = { + .container = param + }, + .argv = { + .raw = __ptr(argv) + }, + .envp = { + .raw = __ptr(envp) + }, + .stack_top = ustack_top + }; } -size_t -args_ptr_size(const char** paramv) -{ - size_t sz = 0; - while (*paramv) { - sz++; - paramv++; - } - - return (sz + 1) * sizeof(ptr_t); -} - -static ptr_t -copy_to_ustack(ptr_t stack_top, ptr_t* paramv) +int +count_length(struct exec_arrptr* param) { - ptr_t ptr; - size_t sz = 0; - - while ((ptr = *paramv)) { - sz = strlen((const char*)ptr) + 1; - - stack_top -= sz; - memcpy((void*)stack_top, (const void*)ptr, sz); - *paramv = stack_top; + int i = 0; + ptr_t* arr = (ptr_t*)param->raw; - paramv++; + if (!arr) { + param->len = 0; + return 0; } - return stack_top; + for (; i < MAX_PARAM_LEN && arr[i]; i++); + + param->len = i; + return i > 0 && arr[i] ? E2BIG : 0; } static void -save_process_cmd(struct proc_info* proc, ptr_t* argv) +save_process_cmd(struct proc_info* proc, struct exec_arrptr* argv) { - ptr_t ptr, *_argv = argv; - size_t total_sz = 0; - while ((ptr = *_argv)) { - total_sz += strlen((const char*)ptr) + 1; - _argv++; - } + ptr_t ptr, *argv_ptrs; + char* cmd_; if (proc->cmd) { vfree(proc->cmd); } - char* cmd_ = (char*)valloc(total_sz); - proc->cmd = cmd_; - proc->cmd_len = total_sz; + argv_ptrs = (ptr_t*)argv->copied; + cmd_ = (char*)valloc(argv->size); - while ((ptr = *argv)) { + proc->cmd = cmd_; + while ((ptr = *argv_ptrs)) { cmd_ = strcpy(cmd_, (const char*)ptr); cmd_[-1] = ' '; - argv++; + argv_ptrs++; } cmd_[-1] = '\0'; + + proc->cmd_len = argv->size; } -// externed from mm/dmm.c -extern int -create_heap(struct proc_mm* pvms, ptr_t addr); -int -exec_load(struct exec_container* container, struct v_file* executable) +static int +__place_params(struct exec_host* container) { int errno = 0; - const char **argv = container->argv, **envp = container->envp; - const char** argv_extra = container->argv_pp; - - argv_extra[0] = executable->dnode->name.value; - - if ((errno = load_executable(&container->exe, executable))) { + errno = __place_arrayptrs(container, &container->envp); + if (errno) { goto done; } + errno = __place_arrayptrs(container, &container->argv); + +done: + return errno; +} + +int +exec_load(struct exec_host* container, struct v_file* executable) +{ + int errno = 0; + + struct exec_arrptr* argv = &container->argv; + struct exec_arrptr* envp = &container->envp; + struct proc_info* proc = container->proc; struct proc_mm* pvms = vmspace(proc); @@ -117,77 +180,40 @@ exec_load(struct exec_container* container, struct v_file* executable) pvms->heap = NULL; } - if (!argv_extra[1]) { - // If loading a statically linked file, then heap remapping we can do, - // otherwise delayed. - create_heap(vmspace(proc), page_aligned(container->exe.end)); - } - - if (container->vms_mnt == VMS_SELF) { - // we are loading executable into current addr space - - ptr_t ustack = container->stack_top; - size_t argv_len = 0, envp_len = 0; - ptr_t argv_ptr = 0, envp_ptr = 0; - - if (envp) { - argv_len = args_ptr_size(envp); - ustack -= envp_len; - envp_ptr = ustack; - - memcpy((void*)ustack, (const void*)envp, envp_len); - ustack = copy_to_ustack(ustack, (ptr_t*)ustack); - } else { - ustack -= sizeof(ptr_t); - *((ptr_t*)ustack) = 0; - } - - if (argv) { - argv_len = args_ptr_size(argv); - ustack -= argv_len; - - memcpy((void*)ustack, (const void**)argv, argv_len); - } else { - ustack -= sizeof(ptr_t); - *((ptr_t*)ustack) = 0; - } - - for (size_t i = 0; i < 2 && argv_extra[i]; i++) { - ustack -= sizeof(ptr_t); - *((ptr_t*)ustack) = (ptr_t)argv_extra[i]; - argv_len += sizeof(ptr_t); - } - - argv_ptr = ustack; - ustack = copy_to_ustack(ustack, (ptr_t*)ustack); - - save_process_cmd(proc, (ptr_t*)argv_ptr); - - // four args (arg{c|v}, env{c|p}) for main - struct uexec_param* exec_param = &((struct uexec_param*)ustack)[-1]; - - container->stack_top = (ptr_t)exec_param; - - *exec_param = - (struct uexec_param){ .argc = (argv_len - 1) / sizeof(ptr_t), - .argv = (char**)argv_ptr, - .envc = (envp_len - 1) / sizeof(ptr_t), - .envp = (char**)envp_ptr }; - } else { + if (!active_vms(container->vms_mnt)) { /* - TODO Inject to remote user stack with our procvm_remote toolsets - Need a better way to factorise the argv/envp length calculating + TODO Setup remote mapping of user stack for later use */ fail("not implemented"); } + if ((errno = count_length(argv))) { + goto done; + } + + if ((errno = count_length(envp))) { + goto done; + } + + errno = __place_params(container); + if (errno) { + goto done; + } + + save_process_cmd(proc, argv); + + errno = load_executable(&container->exe, executable); + if (errno) { + goto done; + } + done: return errno; } int -exec_load_byname(struct exec_container* container, const char* filename) +exec_load_byname(struct exec_host* container, const char* filename) { int errno = 0; struct v_dnode* dnode; @@ -222,7 +248,9 @@ int exec_kexecve(const char* filename, const char* argv[], const char* envp[]) { int errno = 0; - struct exec_container container; + struct exec_host container; + + assert(argv && envp); exec_init_container(&container, current_thread, VMS_SELF, argv, envp); @@ -252,7 +280,12 @@ __DEFINE_LXSYSCALL3(int, envp[]) { int errno = 0; - struct exec_container container; + struct exec_host container; + + if (!argv || !envp) { + errno = EINVAL; + goto done; + } exec_init_container( &container, current_thread, VMS_SELF, argv, envp); @@ -263,8 +296,7 @@ __DEFINE_LXSYSCALL3(int, // we will jump to new entry point (_u_start) upon syscall's // return so execve 'will not return' from the perspective of it's invoker - hart_flow_redirect(current_thread->hstate, - container.exe.entry, container.stack_top); + exec_arch_prepare_entry(current_thread, &container); // these become meaningless once execved! current_thread->ustack_top = 0; diff --git a/lunaix-os/kernel/fs/fs_export.c b/lunaix-os/kernel/fs/fs_export.c index dffff0a..1fedef6 100644 --- a/lunaix-os/kernel/fs/fs_export.c +++ b/lunaix-os/kernel/fs/fs_export.c @@ -41,11 +41,9 @@ void __version_rd(struct twimap* map) { twimap_printf(map, - "LunaixOS version %s (gnu-cc %s) %s %s", - CONFIG_LUNAIX_VER, - __VERSION__, - __DATE__, - __TIME__); + "Lunaix " + CONFIG_LUNAIX_VER + " (gnu-cc " __VERSION__ ") " __DATE__ " " __TIME__); } void diff --git a/lunaix-os/kernel/fs/iso9660/file.c b/lunaix-os/kernel/fs/iso9660/file.c index a48da33..23c4066 100644 --- a/lunaix-os/kernel/fs/iso9660/file.c +++ b/lunaix-os/kernel/fs/iso9660/file.c @@ -4,7 +4,7 @@ #include #include -#include +#include int iso9660_open(struct v_inode* this, struct v_file* file) @@ -83,7 +83,7 @@ done: int iso9660_read_page(struct v_inode* inode, void* buffer, size_t fpos) { - return iso9660_read(inode, buffer, MEM_PAGE, fpos); + return iso9660_read(inode, buffer, PAGE_SIZE, fpos); } int diff --git a/lunaix-os/kernel/fs/twifs/twifs.c b/lunaix-os/kernel/fs/twifs/twifs.c index 6aa5f6a..2894f96 100644 --- a/lunaix-os/kernel/fs/twifs/twifs.c +++ b/lunaix-os/kernel/fs/twifs/twifs.c @@ -18,7 +18,7 @@ #include #include -#include +#include static struct twifs_node* fs_root; @@ -92,7 +92,7 @@ __twifs_fwrite(struct v_inode* inode, void* buffer, size_t len, size_t fpos) int __twifs_fwrite_pg(struct v_inode* inode, void* buffer, size_t fpos) { - return __twifs_fwrite(inode, buffer, MEM_PAGE, fpos); + return __twifs_fwrite(inode, buffer, PAGE_SIZE, fpos); } int @@ -108,7 +108,7 @@ __twifs_fread(struct v_inode* inode, void* buffer, size_t len, size_t fpos) int __twifs_fread_pg(struct v_inode* inode, void* buffer, size_t fpos) { - return __twifs_fread(inode, buffer, MEM_PAGE, fpos); + return __twifs_fread(inode, buffer, PAGE_SIZE, fpos); } struct twifs_node* diff --git a/lunaix-os/kernel/fs/twimap.c b/lunaix-os/kernel/fs/twimap.c index 6b74ad3..e72f6c2 100644 --- a/lunaix-os/kernel/fs/twimap.c +++ b/lunaix-os/kernel/fs/twimap.c @@ -6,9 +6,9 @@ #include #include -#include +#include -#define TWIMAP_BUFFER_SIZE MEM_PAGE +#define TWIMAP_BUFFER_SIZE PAGE_SIZE void __twimap_default_reset(struct twimap* map) @@ -32,7 +32,7 @@ __twimap_file_read(struct v_inode* inode, void* buf, size_t len, size_t fpos) static int __twimap_file_read_page(struct v_inode* inode, void* buf, size_t fpos) { - return __twimap_file_read(inode, buf, MEM_PAGE, fpos); + return __twimap_file_read(inode, buf, PAGE_SIZE, fpos); } int diff --git a/lunaix-os/kernel/fs/vfs.c b/lunaix-os/kernel/fs/vfs.c index eb42396..d4bc56a 100644 --- a/lunaix-os/kernel/fs/vfs.c +++ b/lunaix-os/kernel/fs/vfs.c @@ -116,7 +116,7 @@ __dcache_hash(struct v_dnode* parent, u32_t* hash) // 确保低位更加随机 _hash = _hash ^ (_hash >> VFS_HASHBITS); // 与parent的指针值做加法,来减小碰撞的可能性。 - _hash += (u32_t)parent; + _hash += (u32_t)__ptr(parent); *hash = _hash; return &dnode_cache[_hash & VFS_HASH_MASK]; } diff --git a/lunaix-os/kernel/kinit.c b/lunaix-os/kernel/kinit.c index c74f8b3..685c3d0 100644 --- a/lunaix-os/kernel/kinit.c +++ b/lunaix-os/kernel/kinit.c @@ -92,7 +92,6 @@ kernel_bootstrap(struct boot_handoff* bhctx) * and start geting into uspace */ boot_end(bhctx); - boot_cleanup(); spawn_lunad(); } @@ -122,9 +121,16 @@ void kmem_init(struct boot_handoff* bhctx) { pte_t* ptep = mkptep_va(VMS_SELF, KERNEL_RESIDENT); + ptep = mkl0tep(ptep); + unsigned int i = ptep_vfn(ptep); do { + if (l0tep_impile_vmnts(ptep)) { + ptep++; + continue; + } + #if LnT_ENABLED(1) assert(mkl1t(ptep++, 0, KERNEL_DATA)); #elif LnT_ENABLED(2) @@ -134,7 +140,7 @@ kmem_init(struct boot_handoff* bhctx) #else assert(mklft(ptep++, 0, KERNEL_DATA)); #endif - } while (ptep_vfn(ptep) < MAX_PTEN - 2); + } while (++i < MAX_PTEN); // allocators cake_init(); diff --git a/lunaix-os/kernel/kprint/kprintf.c b/lunaix-os/kernel/kprint/kprintf.c index 512e797..4c1ee40 100644 --- a/lunaix-os/kernel/kprint/kprintf.c +++ b/lunaix-os/kernel/kprint/kprintf.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +39,16 @@ shift_level(const char* str, int* level) return str; } +static inline void +kprintf_put(int level, const char* buf, size_t sz) +{ + kprec_put(&kprecs, level, buf, sz); + + if (likely(sysconsole)) { + sysconsole->ops.write(sysconsole, buf, 0, sz); + } +} + static inline void kprintf_ml(const char* component, int level, const char* fmt, va_list args) { @@ -45,11 +56,7 @@ kprintf_ml(const char* component, int level, const char* fmt, va_list args) ksnprintf(buf, MAX_BUFSZ_HLF, "%s: %s\n", component, fmt); size_t sz = ksnprintfv(tmp_buf, buf, MAX_BUFSZ_HLF, args); - kprec_put(&kprecs, level, tmp_buf, sz); - - if (likely(sysconsole)) { - sysconsole->ops.write(sysconsole, tmp_buf, 0, sz); - } + kprintf_put(level, tmp_buf, sz); } void @@ -100,7 +107,8 @@ kprintf_dump_logs() { } } -__DEFINE_LXSYSCALL3(void, syslog, int, level, const char*, fmt, va_list, args) +__DEFINE_LXSYSCALL3(void, syslog, int, level, + const char*, buf, unsigned int, size) { - kprintf_ml("syslog", level, fmt, args); + kprintf_put(level, buf, size); } \ No newline at end of file diff --git a/lunaix-os/kernel/lunad.c b/lunaix-os/kernel/lunad.c index 1f2fb95..ff52e71 100644 --- a/lunaix-os/kernel/lunad.c +++ b/lunaix-os/kernel/lunad.c @@ -41,8 +41,10 @@ int exec_initd() { int errno = 0; + const char* argv[] = { "/mnt/lunaix-os/usr/bin/init", 0 }; + const char* envp[] = { 0 }; - if ((errno = exec_kexecve("/mnt/lunaix-os/usr/bin/init", NULL, NULL))) { + if ((errno = exec_kexecve(argv[0], argv, envp))) { goto fail; } diff --git a/lunaix-os/kernel/mm/dmm.c b/lunaix-os/kernel/mm/dmm.c index f665e9d..50804db 100644 --- a/lunaix-os/kernel/mm/dmm.c +++ b/lunaix-os/kernel/mm/dmm.c @@ -42,7 +42,7 @@ __DEFINE_LXSYSCALL1(void*, sbrk, ssize_t, incr) assert(heap); int err = mem_adjust_inplace(&pvms->regions, heap, heap->end + incr); if (err) { - return (void*)DO_STATUS(err); + return (void*)__ptr(DO_STATUS(err)); } return (void*)heap->end; } diff --git a/lunaix-os/kernel/mm/fault.c b/lunaix-os/kernel/mm/fault.c index e840b76..5bbf6ee 100644 --- a/lunaix-os/kernel/mm/fault.c +++ b/lunaix-os/kernel/mm/fault.c @@ -25,23 +25,25 @@ __gather_memaccess_info(struct fault_context* context) context->mm = vmspace(__current); - if (mnt < VMS_MOUNT_1) { + if (!vmnt_packed(ptep)) { refva = (ptr_t)ptep; goto done; } context->ptep_fault = true; - context->remote_fault = (mnt != VMS_SELF); + context->remote_fault = !active_vms(mnt); if (context->remote_fault && context->mm) { context->mm = context->mm->guest_mm; assert(context->mm); } + // unpack the ptep to reveal the one true va! + #if LnT_ENABLED(1) ptep = (pte_t*)page_addr(ptep_pfn(ptep)); mnt = ptep_vm_mnt(ptep); - if (mnt < VMS_MOUNT_1) { + if (!vmnt_packed(ptep)) { refva = (ptr_t)ptep; goto done; } @@ -50,7 +52,7 @@ __gather_memaccess_info(struct fault_context* context) #if LnT_ENABLED(2) ptep = (pte_t*)page_addr(ptep_pfn(ptep)); mnt = ptep_vm_mnt(ptep); - if (mnt < VMS_MOUNT_1) { + if (!vmnt_packed(ptep)) { refva = (ptr_t)ptep; goto done; } @@ -59,7 +61,7 @@ __gather_memaccess_info(struct fault_context* context) #if LnT_ENABLED(3) ptep = (pte_t*)page_addr(ptep_pfn(ptep)); mnt = ptep_vm_mnt(ptep); - if (mnt < VMS_MOUNT_1) { + if (!vmnt_packed(ptep)) { refva = (ptr_t)ptep; goto done; } @@ -68,7 +70,7 @@ __gather_memaccess_info(struct fault_context* context) ptep = (pte_t*)page_addr(ptep_pfn(ptep)); mnt = ptep_vm_mnt(ptep); - assert(mnt < VMS_MOUNT_1); + assert(!vmnt_packed(ptep)); refva = (ptr_t)ptep; done: @@ -174,14 +176,17 @@ __handle_anon_region(struct fault_context* fault) static void __handle_named_region(struct fault_context* fault) { + int errno = 0; struct mm_region* vmr = fault->vmr; struct v_file* file = vmr->mfile; + struct v_file_ops * fops = file->ops; pte_t pte = fault->resolving; ptr_t fault_va = page_aligned(fault->fault_va); u32_t mseg_off = (fault_va - vmr->start); u32_t mfile_off = mseg_off + vmr->foff; + size_t mapped_len = vmr->flen; // TODO Potentially we can get different order of leaflet here struct leaflet* region_part = alloc_leaflet(0); @@ -189,7 +194,25 @@ __handle_named_region(struct fault_context* fault) pte = pte_setprot(pte, region_pteprot(vmr)); ptep_map_leaflet(fault->fault_ptep, pte, region_part); - int errno = file->ops->read_page(file->inode, (void*)fault_va, mfile_off); + if (mseg_off < mapped_len) { + mapped_len = MIN(mapped_len - mseg_off, PAGE_SIZE); + } + else { + mapped_len = 0; + } + + if (mapped_len == PAGE_SIZE) { + errno = fops->read_page(file->inode, (void*)fault_va, mfile_off); + } + else { + leaflet_wipe(region_part); + + if (mapped_len) { + errno = fops->read(file->inode, + (void*)fault_va, mapped_len, mfile_off); + } + } + if (errno < 0) { ERROR("fail to populate page (%d)", errno); @@ -208,7 +231,7 @@ static void __handle_kernel_page(struct fault_context* fault) { // we must ensure only ptep fault is resolvable - if (fault->fault_va < VMS_MOUNT_1) { + if (!is_ptep(fault->fault_va)) { return; } @@ -341,4 +364,6 @@ intr_routine_page_fault(const struct hart_state* hstate) leaflet_return(fault.prealloc); } } + + tlb_flush_kernel(fault.fault_va); } \ No newline at end of file diff --git a/lunaix-os/kernel/mm/mmap.c b/lunaix-os/kernel/mm/mmap.c index 10d4f2c..972bbee 100644 --- a/lunaix-os/kernel/mm/mmap.c +++ b/lunaix-os/kernel/mm/mmap.c @@ -232,6 +232,7 @@ found: ((param->proct | param->flags) & 0x3f) | (param->type & ~0xffff)); region->mfile = file; + region->flen = param->flen; region->foff = param->offset; region->proc_vms = param->pvms; @@ -459,9 +460,14 @@ mem_unmap(ptr_t mnt, vm_regions_t* regions, ptr_t addr, size_t length) } } - while (&pos->head != regions && length) { + size_t remaining = length; + while (&pos->head != regions && remaining) { n = container_of(pos->head.next, typeof(*pos), head); - __unmap_overlapped_cases(mnt, pos, &cur_addr, &length); + if (pos->start > cur_addr + length) { + break; + } + + __unmap_overlapped_cases(mnt, pos, &cur_addr, &remaining); pos = n; } @@ -469,16 +475,24 @@ mem_unmap(ptr_t mnt, vm_regions_t* regions, ptr_t addr, size_t length) return 0; } -__DEFINE_LXSYSCALL3(void*, sys_mmap, void*, addr, size_t, length, va_list, lst) +__DEFINE_LXSYSCALL1(void*, sys_mmap, struct usr_mmap_param*, mparam) { - int proct = va_arg(lst, int); - int fd = va_arg(lst, u32_t); - off_t offset = va_arg(lst, off_t); - int options = va_arg(lst, int); - int errno = 0; - void* result = (void*)-1; - - ptr_t addr_ptr = (ptr_t)addr; + off_t offset; + size_t length; + int proct, fd, options; + int errno; + void* result; + ptr_t addr_ptr; + + proct = mparam->proct; + fd = mparam->fd; + offset = mparam->offset; + options = mparam->flags; + addr_ptr = __ptr(mparam->addr); + length = mparam->length; + + errno = 0; + result = (void*)-1; if (!length || length > BS_SIZE || va_offset(addr_ptr)) { errno = EINVAL; @@ -509,8 +523,10 @@ __DEFINE_LXSYSCALL3(void*, sys_mmap, void*, addr, size_t, length, va_list, lst) } } + length = ROUNDUP(length, PAGE_SIZE); struct mmap_param param = { .flags = options, - .mlen = ROUNDUP(length, PAGE_SIZE), + .mlen = length, + .flen = length, .offset = offset, .type = REGION_TYPE_GENERAL, .proct = proct, diff --git a/lunaix-os/kernel/mm/procvm.c b/lunaix-os/kernel/mm/procvm.c index 7b07560..5b7afad 100644 --- a/lunaix-os/kernel/mm/procvm.c +++ b/lunaix-os/kernel/mm/procvm.c @@ -38,14 +38,50 @@ vmscpy(ptr_t dest_mnt, ptr_t src_mnt, bool only_kernel) pte_t* ptep_kernel = mkl0tep(mkptep_va(src_mnt, KERNEL_RESIDENT)); // Build the self-reference on dest vms - pte_t* ptep_sms = mkptep_va(VMS_SELF, (ptr_t)ptep_dest); - pte_t* ptep_ssm = mkptep_va(VMS_SELF, (ptr_t)ptep_sms); + + /* + * -- What the heck are ptep_ssm and ptep_sms ? -- + * + * ptep_dest point to the pagetable itself that is mounted + * at dest_mnt (or simply mnt): + * mnt -> self -> self -> self -> L0TE@offset + * + * ptep_sms shallowed the recursion chain: + * self -> mnt -> self -> self -> L0TE@self + * + * ptep_ssm shallowed the recursion chain: + * self -> self -> mnt -> self -> L0TE@self + * + * Now, here is the problem, back to x86_32, the translation is + * a depth-3 recursion: + * L0T -> LFT -> Page + * + * So ptep_ssm will terminate at mnt and give us a leaf + * slot for allocate a fresh page table for mnt: + * self -> self -> L0TE@mnt + * + * but in x86_64 translation has extra two more step: + * L0T -> L1T -> L2T -> LFT -> Page + * + * So we must continue push down.... + * ptep_sssms shallowed the recursion chain: + * self -> self -> self -> mnt -> L0TE@self + * + * ptep_ssssm shallowed the recursion chain: + * self -> self -> self -> self -> L0TE@mnt + * + * Note: PML4: 2 extra steps + * PML5: 3 extra steps + */ + pte_t* ptep_ssm = mkl0tep_va(VMS_SELF, dest_mnt); + pte_t* ptep_sms = mkl1tep_va(VMS_SELF, dest_mnt) + VMS_SELF_L0TI; pte_t pte_sms = mkpte_prot(KERNEL_DATA); pte_sms = alloc_kpage_at(ptep_ssm, pte_sms, 0); set_pte(ptep_sms, pte_sms); tlb_flush_kernel((ptr_t)dest_mnt); + tlb_flush_kernel((ptr_t)ptep_sms); if (only_kernel) { ptep = ptep_kernel; @@ -89,7 +125,7 @@ vmscpy(ptr_t dest_mnt, ptr_t src_mnt, bool only_kernel) } cont: - if (ptep_vfn(ptep) == MAX_PTEN - 1) { + while (ptep_vfn(ptep) == MAX_PTEN - 1) { assert(level > 0); ptep = ptep_step_out(ptep); ptep_dest = ptep_step_out(ptep_dest); @@ -105,8 +141,14 @@ vmscpy(ptr_t dest_mnt, ptr_t src_mnt, bool only_kernel) assert(ptep_dest == ptepd_kernel); // Carry over the kernel (exclude last two entry) - while (ptep_vfn(ptep) < MAX_PTEN - 2) { + unsigned int i = ptep_vfn(ptep); + while (i++ < MAX_PTEN) { pte_t pte = *ptep; + + if (l0tep_impile_vmnts(ptep)) { + goto _cont; + } + assert(!pte_isnull(pte)); // Ensure it is a next level pagetable, @@ -117,12 +159,13 @@ vmscpy(ptr_t dest_mnt, ptr_t src_mnt, bool only_kernel) set_pte(ptep_dest, pte); leaflet_borrow(leaflet); - + + _cont: ptep++; ptep_dest++; } - return pte_paddr(*(ptep_dest + 1)); + return pte_paddr(pte_sms); } static void @@ -130,6 +173,7 @@ vmsfree(ptr_t vm_mnt) { struct leaflet* leaflet; pte_t* ptep_head = mkl0tep(mkptep_va(vm_mnt, 0)); + pte_t* ptep_self = mkl0tep(mkptep_va(vm_mnt, VMS_SELF)); pte_t* ptep_kernel = mkl0tep(mkptep_va(vm_mnt, KERNEL_RESIDENT)); int level = 0; @@ -158,7 +202,7 @@ vmsfree(ptr_t vm_mnt) } cont: - if (ptep_vfn(ptep) == MAX_PTEN - 1) { + while (ptep_vfn(ptep) == MAX_PTEN - 1) { ptep = ptep_step_out(ptep); leaflet = pte_leaflet_aligned(pte_at(ptep)); @@ -171,7 +215,7 @@ vmsfree(ptr_t vm_mnt) ptep++; } - leaflet = pte_leaflet_aligned(ptep_head[MAX_PTEN - 1]); + leaflet = pte_leaflet_aligned(pte_at(ptep_self)); leaflet_return(leaflet); } @@ -279,7 +323,7 @@ procvm_mount_self(struct proc_mm* mm) void procvm_unmount_self(struct proc_mm* mm) { - assert(mm->vm_mnt == VMS_SELF); + assert(active_vms(mm->vm_mnt)); mm->vm_mnt = 0; } @@ -291,7 +335,7 @@ procvm_enter_remote(struct remote_vmctx* rvmctx, struct proc_mm* mm, ptr_t vm_mnt = mm->vm_mnt; assert(vm_mnt); - pfn_t size_pn = pfn(size + MEM_PAGE); + pfn_t size_pn = pfn(size + PAGE_SIZE); assert(size_pn < REMOTEVM_MAX_PAGES); struct mm_region* region = region_get(&mm->regions, remote_base); diff --git a/lunaix-os/kernel/mm/region.c b/lunaix-os/kernel/mm/region.c index 14cada1..d8035db 100644 --- a/lunaix-os/kernel/mm/region.c +++ b/lunaix-os/kernel/mm/region.c @@ -26,7 +26,7 @@ region_create_range(ptr_t start, size_t length, u32_t attr) struct mm_region* region = valloc(sizeof(struct mm_region)); *region = (struct mm_region){ .attr = attr, .start = start, - .end = ROUNDUP(start + length, MEM_PAGE) }; + .end = ROUNDUP(start + length, PAGE_SIZE) }; return region; } diff --git a/lunaix-os/kernel/process/process.c b/lunaix-os/kernel/process/process.c index 818493a..de533c7 100644 --- a/lunaix-os/kernel/process/process.c +++ b/lunaix-os/kernel/process/process.c @@ -105,7 +105,7 @@ spawn_process_usr(struct thread** created, char* path, goto fail; } - struct exec_container container; + struct exec_host container; exec_init_container(&container, main_thread, VMS_MOUNT_1, argv, envp); if ((errno = exec_load_byname(&container, path))) { goto fail; diff --git a/lunaix-os/kernel/process/thread.c b/lunaix-os/kernel/process/thread.c index 9d93566..ef207aa 100644 --- a/lunaix-os/kernel/process/thread.c +++ b/lunaix-os/kernel/process/thread.c @@ -17,14 +17,14 @@ static ptr_t __alloc_user_thread_stack(struct proc_info* proc, struct mm_region** stack_region, ptr_t vm_mnt) { - ptr_t th_stack_top = (proc->thread_count + 1) * USR_STACK_SIZE; - th_stack_top = ROUNDUP(USR_STACK_END - th_stack_top, MEM_PAGE); + ptr_t th_stack_top = (proc->thread_count + 1) * USR_STACK_SIZE_THREAD; + th_stack_top = ROUNDUP(USR_STACK_END - th_stack_top, PAGE_SIZE); struct mm_region* vmr; struct proc_mm* mm = vmspace(proc); struct mmap_param param = { .vms_mnt = vm_mnt, .pvms = mm, - .mlen = USR_STACK_SIZE, + .mlen = USR_STACK_SIZE_THREAD, .proct = PROT_READ | PROT_WRITE, .flags = MAP_ANON | MAP_PRIVATE, .type = REGION_TYPE_STACK }; @@ -37,11 +37,12 @@ __alloc_user_thread_stack(struct proc_info* proc, return 0; } - set_pte(mkptep_va(vm_mnt, vmr->start), guard_pte); + pte_t* guardp = mkptep_va(vm_mnt, vmr->start); + set_pte(guardp, guard_pte); *stack_region = vmr; - ptr_t stack_top = align_stack(th_stack_top + USR_STACK_SIZE - 1); + ptr_t stack_top = align_stack(th_stack_top + USR_STACK_SIZE_THREAD - 1); return stack_top; } @@ -52,10 +53,9 @@ __alloc_kernel_thread_stack(struct proc_info* proc, ptr_t vm_mnt) pfn_t kstack_end = pfn(KSTACK_AREA); pte_t* ptep = mkptep_pn(vm_mnt, kstack_top); while (ptep_pfn(ptep) > kstack_end) { - ptep -= KSTACK_PAGES; + ptep -= KSTACK_PAGES + 1; - // first page in the kernel stack is guardian page - pte_t pte = *(ptep + 1); + pte_t pte = pte_at(ptep + 1); if (pte_isnull(pte)) { goto found; } @@ -65,8 +65,8 @@ __alloc_kernel_thread_stack(struct proc_info* proc, ptr_t vm_mnt) return 0; found:; - // KSTACK_PAGES = 3, removal one guardian pte, give order 1 page - struct leaflet* leaflet = alloc_leaflet(1); + unsigned int po = count_order(KSTACK_PAGES); + struct leaflet* leaflet = alloc_leaflet(po); if (!leaflet) { WARN("failed to create kernel stack: nomem\n"); @@ -134,6 +134,10 @@ create_thread(struct proc_info* proc, bool with_ustack) th->kstack = kstack; th->ustack = ustack_region; + + if (ustack_region) { + th->ustack_top = align_stack(ustack_region->end - 1); + } return th; } @@ -150,11 +154,7 @@ start_thread(struct thread* th, ptr_t entry) if (!kernel_addr(entry)) { assert(th->ustack); - ptr_t ustack_top = align_stack(th->ustack->end - 1); - ustack_top -= 16; // pre_allocate a 16 byte for inject parameter - hart_user_transfer(&transition, th->kstack, ustack_top, entry); - - th->ustack_top = ustack_top; + hart_user_transfer(&transition, th->kstack, th->ustack_top, entry); } else { hart_kernel_transfer(&transition, th->kstack, entry); @@ -185,21 +185,23 @@ thread_find(struct proc_info* proc, tid_t tid) return NULL; } -__DEFINE_LXSYSCALL4(int, th_create, tid_t*, tid, struct uthread_info*, thinfo, - void*, entry, void*, param) +__DEFINE_LXSYSCALL3(int, th_create, tid_t*, tid, + struct uthread_param*, thparam, void*, entry) { struct thread* th = create_thread(__current, true); if (!th) { return EAGAIN; } - start_thread(th, (ptr_t)entry); + ptr_t ustack_top; + + ustack_top = th->ustack_top; + ustack_top = align_stack(ustack_top - sizeof(*thparam)); - ptr_t ustack_top = th->ustack_top; - *((void**)ustack_top) = param; + memcpy((void*)ustack_top, thparam, sizeof(*thparam)); - thinfo->th_stack_sz = region_size(th->ustack); - thinfo->th_stack_top = (void*)ustack_top; + th->ustack_top = ustack_top; + start_thread(th, (ptr_t)entry); if (tid) { *tid = th->tid; diff --git a/lunaix-os/libs/klibc/itoa.c b/lunaix-os/libs/klibc/itoa.c index cbffd52..9eaf55b 100644 --- a/lunaix-os/libs/klibc/itoa.c +++ b/lunaix-os/libs/klibc/itoa.c @@ -5,12 +5,12 @@ char base_char[] = "0123456789abcdefghijklmnopqrstuvwxyz"; static char* -__uitoa_internal(unsigned int value, char* str, int base, unsigned int* size) +__uitoa_internal(unsigned long value, char* str, int base, unsigned int* size) { unsigned int ptr = 0; do { str[ptr] = base_char[value % base]; - value = value / base; + value = value / (unsigned long)base; ptr++; } while (value); @@ -27,11 +27,11 @@ __uitoa_internal(unsigned int value, char* str, int base, unsigned int* size) } static char* -__itoa_internal(int value, char* str, int base, unsigned int* size) +__itoa_internal(long value, char* str, int base, unsigned int* size) { if (value < 0 && base == 10) { str[0] = '-'; - unsigned int _v = (unsigned int)(-value); + unsigned long _v = (unsigned long)(-value); __uitoa_internal(_v, str + 1, base, size); } else { __uitoa_internal(value, str, base, size); @@ -41,7 +41,7 @@ __itoa_internal(int value, char* str, int base, unsigned int* size) } char* -itoa(int value, char* str, int base) +itoa(long value, char* str, int base) { return __itoa_internal(value, str, base, NULL); } \ No newline at end of file diff --git a/lunaix-os/link/base.ldx b/lunaix-os/link/base.ldx new file mode 100644 index 0000000..e62aae3 --- /dev/null +++ b/lunaix-os/link/base.ldx @@ -0,0 +1,7 @@ +#ifndef __LUNAIX_BASE_LD_INC +#define __LUNAIX_BASE_LD_INC + +#define __LD__ +#include + +#endif /* __LUNAIX_BASE_LD_INC */ diff --git a/lunaix-os/link/kernel.ldx b/lunaix-os/link/kernel.ldx new file mode 100644 index 0000000..a259e1b --- /dev/null +++ b/lunaix-os/link/kernel.ldx @@ -0,0 +1,31 @@ +.text BLOCK(PAGE_GRAN) : AT ( ADDR(.text) - KEXEC_BASE ) +{ + *(.text) +} + +.kf.preempt BLOCK(PAGE_GRAN) : AT ( ADDR(.kf.preempt) - KEXEC_BASE ) +{ + PROVIDE(__kf_preempt_start = .); + + KEEP(*(.kf.preempt)); + + PROVIDE(__kf_preempt_end = .); +} + +PROVIDE(__kexec_text_end = .); + +.data BLOCK(PAGE_GRAN) : AT ( ADDR(.data) - KEXEC_BASE ) +{ + *(.data) +} + +.rodata BLOCK(PAGE_GRAN) : AT ( ADDR(.rodata) - KEXEC_BASE ) +{ + *(.rodata) + *(.rodata.*) +} + +.kpg BLOCK(PAGE_GRAN) : AT ( ADDR(.kpg) - KEXEC_BASE ) +{ + *(.kpg) +} \ No newline at end of file diff --git a/lunaix-os/link/lga.ldx b/lunaix-os/link/lga.ldx new file mode 100644 index 0000000..3d8962a --- /dev/null +++ b/lunaix-os/link/lga.ldx @@ -0,0 +1,101 @@ +#include "base.ldx" + +.lga BLOCK(PAGE_GRAN) : AT ( ADDR(.lga) - KEXEC_BASE ) +{ + PROVIDE(__lga_twiplugin_inits_start = .); + + KEEP(*(.lga.twiplugin_inits)); + + PROVIDE(__lga_twiplugin_inits_end = .); + + /* ---- */ + + /* align to 8 bytes, so it can cover both 32 and 64 bits address line*/ + . = ALIGN(8); + + PROVIDE(__lga_devdefs_start = .); + + KEEP(*(.lga.devdefs)); + + PROVIDE(__lga_devdefs_end = .); + + /* ---- */ + + . = ALIGN(8); + + PROVIDE(__lga_dev_ld_kboot_start = .); + + KEEP(*(.lga.devdefs.ld_kboot)); + + PROVIDE(__lga_dev_ld_kboot_end = .); + + /* ---- */ + + . = ALIGN(8); + + PROVIDE(__lga_dev_ld_sysconf_start = .); + + KEEP(*(.lga.devdefs.ld_sysconf)); + + PROVIDE(__lga_dev_ld_sysconf_end = .); + + /* ---- */ + + . = ALIGN(8); + + PROVIDE(__lga_dev_ld_timedev_start = .); + + KEEP(*(.lga.devdefs.ld_timedev)); + + PROVIDE(__lga_dev_ld_timedev_end = .); + + /* ---- */ + + . = ALIGN(8); + + PROVIDE(__lga_dev_ld_post_start = .); + + KEEP(*(.lga.devdefs.ld_post)); + + PROVIDE(__lga_dev_ld_post_end = .); + + /* ---- */ + + . = ALIGN(8); + + PROVIDE(__lga_fs_start = .); + + KEEP(*(.lga.fs)); + + PROVIDE(__lga_fs_end = .); + + /* ---- */ + + . = ALIGN(8); + + PROVIDE(__lga_lunainit_on_earlyboot_start = .); + + KEEP(*(.lga.lunainit.c_earlyboot)); + + PROVIDE(__lga_lunainit_on_earlyboot_end = .); + + /* ---- */ + + . = ALIGN(8); + + PROVIDE(__lga_lunainit_on_boot_start = .); + + KEEP(*(.lga.lunainit.c_boot)); + + PROVIDE(__lga_lunainit_on_boot_end = .); + + /* ---- */ + + . = ALIGN(8); + + PROVIDE(__lga_lunainit_on_postboot_start = .); + + KEEP(*(.lga.lunainit.c_postboot)); + + PROVIDE(__lga_lunainit_on_postboot_end = .); +} \ No newline at end of file diff --git a/lunaix-os/link/linker.ld b/lunaix-os/link/linker.ld deleted file mode 100644 index c3d57da..0000000 --- a/lunaix-os/link/linker.ld +++ /dev/null @@ -1,203 +0,0 @@ -ENTRY(start_) - -SECTIONS { - . = 0x100000; - __kboot_start = .; - - /* 这里是我们的高半核初始化代码段和数据段 */ - .boot.text BLOCK(4K) : - { - *(.multiboot) - *(.boot.text) - } - - .boot.bss BLOCK(4K) : - { - *(.boot.bss) - } - - .boot.data BLOCK(4K) : - { - *(.boot.data) - } - - .boot.rodata BLOCK(4K) : - { - *(.boot.rodata) - } - - .boot.bss BLOCK(4K) : - { - *(.boot.rodata) - } - __kboot_end = ALIGN(4K); - - /* ---- boot end ---- */ - - /* ---- kernel start ---- */ - - . += 0xC0000000; - - /* 好了,我们的内核…… */ - - PROVIDE(__kexec_text_start = ALIGN(4K)); - - .text BLOCK(4K) : AT ( ADDR(.text) - 0xC0000000 ) - { - __kexec_start = .; - - *(.text) - } - - .kf.preempt BLOCK(4K) : AT ( ADDR(.kf.preempt) - 0xC0000000 ) - { - PROVIDE(__kf_preempt_start = .); - - KEEP(*(.kf.preempt)); - - PROVIDE(__kf_preempt_end = .); - } - - PROVIDE(__kexec_text_end = .); - - .data BLOCK(4K) : AT ( ADDR(.data) - 0xC0000000 ) - { - *(.data) - } - - .rodata BLOCK(4K) : AT ( ADDR(.rodata) - 0xC0000000 ) - { - *(.rodata) - } - - .kpg BLOCK(4K) : AT ( ADDR(.kpg) - 0xC0000000 ) - { - *(.kpg) - } - - . = ALIGN(4K); - - /* for generated array, we align to address line size */ - - .lga BLOCK(4K) : AT ( ADDR(.lga) - 0xC0000000 ) - { - PROVIDE(__lga_twiplugin_inits_start = .); - - KEEP(*(.lga.twiplugin_inits)); - - PROVIDE(__lga_twiplugin_inits_end = .); - - /* ---- */ - - /* align to 8 bytes, so it can cover both 32 and 64 bits address line*/ - . = ALIGN(8); - - PROVIDE(__lga_devdefs_start = .); - - KEEP(*(.lga.devdefs)); - - PROVIDE(__lga_devdefs_end = .); - - /* ---- */ - - . = ALIGN(8); - - PROVIDE(__lga_dev_ld_kboot_start = .); - - KEEP(*(.lga.devdefs.ld_kboot)); - - PROVIDE(__lga_dev_ld_kboot_end = .); - - /* ---- */ - - . = ALIGN(8); - - PROVIDE(__lga_dev_ld_sysconf_start = .); - - KEEP(*(.lga.devdefs.ld_sysconf)); - - PROVIDE(__lga_dev_ld_sysconf_end = .); - - /* ---- */ - - . = ALIGN(8); - - PROVIDE(__lga_dev_ld_timedev_start = .); - - KEEP(*(.lga.devdefs.ld_timedev)); - - PROVIDE(__lga_dev_ld_timedev_end = .); - - /* ---- */ - - . = ALIGN(8); - - PROVIDE(__lga_dev_ld_post_start = .); - - KEEP(*(.lga.devdefs.ld_post)); - - PROVIDE(__lga_dev_ld_post_end = .); - - /* ---- */ - - . = ALIGN(8); - - PROVIDE(__lga_fs_start = .); - - KEEP(*(.lga.fs)); - - PROVIDE(__lga_fs_end = .); - - /* ---- */ - - . = ALIGN(8); - - PROVIDE(__lga_lunainit_on_earlyboot_start = .); - - KEEP(*(.lga.lunainit.c_earlyboot)); - - PROVIDE(__lga_lunainit_on_earlyboot_end = .); - - /* ---- */ - - . = ALIGN(8); - - PROVIDE(__lga_lunainit_on_boot_start = .); - - KEEP(*(.lga.lunainit.c_boot)); - - PROVIDE(__lga_lunainit_on_boot_end = .); - - /* ---- */ - - . = ALIGN(8); - - PROVIDE(__lga_lunainit_on_postboot_start = .); - - KEEP(*(.lga.lunainit.c_postboot)); - - PROVIDE(__lga_lunainit_on_postboot_end = .); - - } - - .ksymtable BLOCK(4K) : AT ( ADDR(.ksymtable) - 0xC0000000 ) - { - *(.ksymtable) - } - - .bss BLOCK(4K) : AT ( ADDR(.bss) - 0xC0000000 ) - { - *(.bss) - } - - .bss.kstack BLOCK(4K) : AT ( ADDR(.bss.kstack) - 0xC0000000) - { - PROVIDE(__bsskstack_start = .); - - *(.bss.kstack) - - PROVIDE(__bsskstack_end = .); - } - - __kexec_end = ALIGN(4K); -} \ No newline at end of file diff --git a/lunaix-os/link/lunaix.ldx b/lunaix-os/link/lunaix.ldx new file mode 100644 index 0000000..e6f718a --- /dev/null +++ b/lunaix-os/link/lunaix.ldx @@ -0,0 +1,51 @@ +#define __LD__ +#include "base.ldx" + +ENTRY(ENTRY_POINT) + +SECTIONS { + . = LOAD_OFF; + + #include + + /* ---- kernel start ---- */ + + . += KEXEC_BASE; + + PROVIDE(__kexec_text_start = ALIGN(PAGE_GRAN)); + __kexec_start = ALIGN(PAGE_GRAN); + + + /* kernel executable sections */ + + #include "kernel.ldx" + + + /* link-time allocated array */ + + #include "lga.ldx" + + + /* All other stuff */ + + .ksymtable BLOCK(PAGE_GRAN) : AT ( ADDR(.ksymtable) - KEXEC_BASE ) + { + *(.ksymtable) + } + + .bss BLOCK(PAGE_GRAN) : AT ( ADDR(.bss) - KEXEC_BASE ) + { + *(.bss) + } + + .bss.kstack BLOCK(PAGE_GRAN) : AT ( ADDR(.bss.kstack) - KEXEC_BASE ) + { + PROVIDE(__bsskstack_start = .); + + *(.bss.kstack) + + PROVIDE(__bsskstack_end = .); + } + + __kexec_end = ALIGN(PAGE_GRAN); +} \ No newline at end of file diff --git a/lunaix-os/live_debug.sh b/lunaix-os/live_debug.sh new file mode 100755 index 0000000..e10f71c --- /dev/null +++ b/lunaix-os/live_debug.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +hmp_port=45454 +gdb_port=1234 +default_cmd="console=/dev/ttyS0" + +make CMDLINE=${default_cmd} ARCH=${ARCH} MODE=debug image -j5 || exit -1 + +./scripts/qemu.py \ + scripts/qemus/qemu_x86_dev.json \ + --qemu-dir "${QEMU_DIR}" \ + -v KIMG=build/lunaix.iso \ + -v QMPORT=${hmp_port} \ + -v GDB_PORT=${gdb_port} \ + -v ARCH=${ARCH} & + +QMPORT=${hmp_port} gdb build/bin/kernel.bin -ex "target remote localhost:${gdb_port}" \ No newline at end of file diff --git a/lunaix-os/makefile b/lunaix-os/makefile index 09ee4b9..5427275 100644 --- a/lunaix-os/makefile +++ b/lunaix-os/makefile @@ -1,11 +1,11 @@ mkinc_dir := $(CURDIR)/makeinc -include $(mkinc_dir)/os.mkinc include $(mkinc_dir)/toolchain.mkinc -include $(mkinc_dir)/qemu.mkinc include $(mkinc_dir)/utils.mkinc +include $(mkinc_dir)/lunabuild.mkinc ARCH ?= i386 +MODE ?= debug export ARCH DEPS := $(CC) $(LD) $(AR) xorriso grub-mkrescue @@ -16,9 +16,8 @@ kbuild_dir := build kbin_dir := $(kbuild_dir)/bin os_img_dir := $(kbuild_dir)/img -os_build_tag := $(OS_NAME)_$(ARCH)_$(OS_VER) kbin := $(kbin_dir)/kernel.bin -kimg := $(kbuild_dir)/$(os_build_tag).iso +kimg := $(kbuild_dir)/lunaix.iso $(DEPS): @echo -n "checking $@ .... " @@ -28,8 +27,6 @@ $(DEPS): echo "failed" && exit 1;\ fi -all_lconfigs = $(shell find . -name "LConfig") - $(kbuild_dir): @mkdir -p $(kbin_dir) @mkdir -p $(os_img_dir) @@ -37,80 +34,40 @@ $(kbuild_dir): @mkdir -p $(os_img_dir)/boot/grub @mkdir -p $(os_img_dir)/usr -.builder/configs.h: $(all_lconfigs) - @echo restarting configuration... - @echo - @./scripts/build-tools/luna_build.py --config --lconfig-file LConfig -o $(@D) - -.builder/lbuild.mkinc: .builder/configs.h - @./scripts/build-tools/luna_build.py LBuild --lconfig-file LConfig -o $(@D) - .PHONY: kernel export BUILD_DIR=$(kbin_dir) export BUILD_NAME=$(kbin) -kernel: .builder/lbuild.mkinc +kernel: $(lbuild_mkinc) $(call status,TASK,$(notdir $@)) + @$(MAKE) $(MKFLAGS) -I $(mkinc_dir) -f kernel.mk all +.NOTPARALLEL: .PHONY: image export KCMD=$(CMDLINE) -export _OS_NAME=$(OS_NAME) -image: usr/build kernel +export LBUILD ARCH MODE +image: $(kbuild_dir) kernel usr/build $(call status,TASK,$(notdir $@)) + $(call status,PACK,$(kimg)) + @./scripts/grub/config-grub.sh $(os_img_dir)/boot/grub/grub.cfg @cp -r usr/build/* $(os_img_dir)/usr @cp -r $(kbin_dir)/* $(os_img_dir)/boot @grub-mkrescue -o $(kimg) $(os_img_dir)\ - -- -volid "$(OS_ID) $(OS_VER)" -system_id "$(OS_NAME)" + -- -volid "$(OS_ID) $(OS_VER)" -system_id "$(OS_NAME)" \ + -report_about FAILURE -abort_on FAILURE usr/build: user -check: $(DEPS) check-cc scripts/grub/GRUB_TEMPLATE - -prepare: check $(os_img_dir) - -export BUILD_MODE=release -bootable: $(kbuild_dir) image - -export BUILD_MODE=debug -bootable-debug: $(kbuild_dir) image +prepare: $(os_img_dir) +export LBUILD ARCH MODE user: - $(call status,$@) + $(call status,TASK,$@) @$(MAKE) $(MKFLAGS) -C usr all -I $(mkinc_dir) -all: bootable - -instable: CFLAGS := -g -std=gnu99 -ffreestanding $(O) $(W) $(ARCH_OPT) -D__LUNAIXOS_DEBUG__ -instable: all - -all-debug: bootable-debug - clean: @$(MAKE) -C usr clean -I $(mkinc_dir) @$(MAKE) -f kernel.mk clean -I $(mkinc_dir) @rm -rf $(kbuild_dir) || exit 1 - @rm -f .builder/lbuild.mkinc || exit 1 - -run: all - @qemu-system-i386 $(call get_qemu_options,$(kimg)) - @sleep 1 - @telnet 127.0.0.1 $(QEMU_MON_PORT) - -debug-qemu: all-debug - @objcopy --only-keep-debug $(kbin) $(kbuild_dir)/kernel.dbg - @qemu-system-i386 $(call get_qemu_options,$(kimg)) - @sleep 1 - @QMPORT=$(QEMU_MON_PORT) gdb $(kbin) -ex "target remote localhost:1234" - -debug-qemu-vscode: all-debug - @qemu-system-i386 $(call get_qemu_options,$(kimg)) - @sleep 0.5 - @telnet 127.0.0.1 $(QEMU_MON_PORT) - -debug-bochs: all-debug - @bochs -q -f bochs.cfg - -debug-metal: - @printf "@cmc" > $(PORT) - @gdb -s $(kbuild_dir)/kernel.dbg -ex "target remote $(PORT)" \ No newline at end of file + @rm -rf .builder || exit 1 \ No newline at end of file diff --git a/lunaix-os/makeinc/lunabuild.mkinc b/lunaix-os/makeinc/lunabuild.mkinc new file mode 100644 index 0000000..d246a6e --- /dev/null +++ b/lunaix-os/makeinc/lunabuild.mkinc @@ -0,0 +1,28 @@ +lbuild_dir := $(CURDIR)/.builder +lbuild_config_h := $(lbuild_dir)/configs.h +lbuild_mkinc := $(lbuild_dir)/lbuild.mkinc +lconfig_save := $(CURDIR)/.config.json + +lbuild_opts := --lconfig-file LConfig + +all_lconfigs = $(shell find $(CURDIR) -name "LConfig") + +export +$(lconfig_save): $(all_lconfigs) + @echo restarting configuration... + @$(LBUILD) --config $(lbuild_opts) --config-save $(lconfig_save) --force\ + -o $(lbuild_dir)/ + +export +$(lbuild_config_h): $(lconfig_save) + @$(LBUILD) --config $(lbuild_opts) --config-save $(lconfig_save) -o $(@D) + +export +$(lbuild_mkinc): $(lbuild_config_h) + @$(LBUILD) LBuild $(lbuild_opts) -o $(@D) + +.PHONY: config +export +config: $(all_lconfigs) + @$(LBUILD) --config $(lbuild_opts) --config-save $(lconfig_save) --force\ + -o $(lbuild_dir)/ diff --git a/lunaix-os/makeinc/os.mkinc b/lunaix-os/makeinc/os.mkinc deleted file mode 100644 index d1f0a7b..0000000 --- a/lunaix-os/makeinc/os.mkinc +++ /dev/null @@ -1,5 +0,0 @@ -OS_NAME := lunaix -OS_ID := LunaixOS -OS_VER := dev$(shell date +%Y%m%d) - -INCLUDES := -Iincludes -Iincludes/usr \ No newline at end of file diff --git a/lunaix-os/makeinc/qemu.mkinc b/lunaix-os/makeinc/qemu.mkinc deleted file mode 100644 index 1fc8a91..0000000 --- a/lunaix-os/makeinc/qemu.mkinc +++ /dev/null @@ -1,18 +0,0 @@ -QEMU_MON_TERM := gnome-terminal -QEMU_MON_PORT := 45454 - -get_qemu_options = -s -S -m 1G \ - -smp 1 \ - -rtc base=utc \ - -no-reboot \ - -machine q35 \ - -cpu pentium3,rdrand \ - -no-shutdown \ - -d cpu_reset \ - -d trace:ide_dma_cb \ - -vga std,retrace=precise \ - -serial telnet::12345,server,nowait,logfile=lunaix_ttyS0.log\ - -drive id=cdrom,file="$(1)",readonly=on,if=none,format=raw \ - -device ahci,id=ahci \ - -device ide-cd,drive=cdrom,bus=ahci.0 \ - -monitor telnet::$(QEMU_MON_PORT),server,nowait,logfile=qm.log & \ No newline at end of file diff --git a/lunaix-os/makeinc/toolchain.mkinc b/lunaix-os/makeinc/toolchain.mkinc index 552c2fd..a538488 100644 --- a/lunaix-os/makeinc/toolchain.mkinc +++ b/lunaix-os/makeinc/toolchain.mkinc @@ -2,6 +2,7 @@ CC := $(CX_PREFIX)gcc CC := $(CX_PREFIX)gcc AS := $(CX_PREFIX)as AR := $(CX_PREFIX)ar +LBUILD ?= $(shell realpath ./scripts/build-tools/luna_build.py) O := -O2 W := -Wall -Wextra -Werror \ @@ -25,7 +26,7 @@ OFLAGS := -fno-gcse\ CFLAGS := -std=gnu99 $(OFLAGS) $(W) -ifeq ($(BUILD_MODE),debug) +ifeq ($(MODE),debug) O = -Og CFLAGS += -g endif diff --git a/lunaix-os/scripts/build-tools/lbuild/contract.py b/lunaix-os/scripts/build-tools/lbuild/contract.py index 643be14..0484947 100644 --- a/lunaix-os/scripts/build-tools/lbuild/contract.py +++ b/lunaix-os/scripts/build-tools/lbuild/contract.py @@ -31,8 +31,8 @@ class LunaBuildFile(Sandbox): def resolve(self): self.execute(self.__path) - self.__env.add_sources(self.__do_process(self.__srcs)) - self.__env.add_headers(self.__do_process(self.__hdrs)) + self.__env.add_sources(self.__srcs) + self.__env.add_headers(self.__hdrs) def __do_process(self, list): resolved = [] @@ -56,40 +56,44 @@ class LunaBuildFile(Sandbox): def __resolve_value(self, source): resolved = source - while not isinstance(resolved, str): + while isinstance(resolved, dict): if isinstance(resolved, dict): resolved = self.expand_select(resolved) else: self.__raise(f"entry with unknown type: {resolved}") - resolved = resolved.strip() - resolved = join_path(self.__dir, resolved) + if isinstance(resolved, list): + rs = [] + for file in resolved: + file = join_path(self.__dir, file) + file = self.__env.to_wspath(file) + rs.append(file) + else: + rs = join_path(self.__dir, resolved) + rs = [self.__env.to_wspath(rs)] - return self.__env.to_wspath(resolved) + return rs def import_buildfile(self, path): path = self.__resolve_value(path) - path = self.__env.to_wspath(path) - - if (os.path.isdir(path)): - path = os.path.join(path, "LBuild") - - if not os.path.exists(path): - self.__raise("Build file not exist: %s", path) + for p in path: + if (os.path.isdir(p)): + p = os.path.join(p, "LBuild") + + if not os.path.exists(p): + self.__raise("Build file not exist: %s", p) - if os.path.abspath(path) == os.path.abspath(self.__path): - self.__raise("self dependency detected") + if os.path.abspath(p) == os.path.abspath(self.__path): + self.__raise("self dependency detected") - LunaBuildFile(self.__env, path).resolve() + LunaBuildFile(self.__env, p).resolve() def export_sources(self, src): - if not isinstance(src, list): - src = [src] + src = self.__resolve_value(src) self.__srcs += src def export_headers(self, hdr): - if not isinstance(hdr, list): - hdr = [hdr] + hdr = self.__resolve_value(hdr) self.__hdrs += hdr def check_config(self, name): diff --git a/lunaix-os/scripts/build-tools/lcfg/builtins.py b/lunaix-os/scripts/build-tools/lcfg/builtins.py index 7a46699..f32b9b6 100644 --- a/lunaix-os/scripts/build-tools/lcfg/builtins.py +++ b/lunaix-os/scripts/build-tools/lcfg/builtins.py @@ -7,8 +7,7 @@ import os def v(env, caller, term): node = env.lookup_node(term.__name__) env.dependency().add(node, caller) - - return env.lookup_value(node.get_name()) + return env.resolve_symbol(node.get_name()) @contextual(caller_type=[LCModuleNode]) def include(env, caller, file): @@ -31,6 +30,10 @@ def parent(env, caller, ref): def default(env, caller, val): caller.set_default(val) +@contextual(caller_type=[LCTermNode]) +def set_value(env, caller, val): + caller.set_value(val) + @builtin() def env(env, key, default=None): return os.getenv(key, default) \ No newline at end of file diff --git a/lunaix-os/scripts/build-tools/lcfg/common.py b/lunaix-os/scripts/build-tools/lcfg/common.py index b409f1d..25e8d1b 100644 --- a/lunaix-os/scripts/build-tools/lcfg/common.py +++ b/lunaix-os/scripts/build-tools/lcfg/common.py @@ -1,7 +1,7 @@ import os.path as path import ast, json -from .lcnodes import LCModuleNode +from .lcnodes import LCModuleNode, LCTermNode from .api import ( ConfigLoadException, Renderable @@ -75,7 +75,8 @@ class DependencyGraph: if current in self._edges: for x in self._edges[current]: q.append(x) - current.evaluate() + if current != start: + current.evaluate() class ConfigTypeFactory: def __init__(self) -> None: @@ -188,6 +189,14 @@ class LConfigEnvironment(Renderable): def lookup_value(self, key): return self.__config_val[key] + def resolve_symbol(self, sym): + term_node = self.__node_table[sym] + if isinstance(term_node, LCTermNode): + if not term_node.is_ready(): + term_node.evaluate() + return term_node.get_value() + raise Exception(f"fail to resolve symbol: {sym}, not resolvable") + def dependency(self): return self.__deps_graph diff --git a/lunaix-os/scripts/build-tools/lcfg/lcnodes.py b/lunaix-os/scripts/build-tools/lcfg/lcnodes.py index cf869b0..87aa20d 100644 --- a/lunaix-os/scripts/build-tools/lcfg/lcnodes.py +++ b/lunaix-os/scripts/build-tools/lcfg/lcnodes.py @@ -200,6 +200,7 @@ class LCTermNode(LCFuncNode): self._default = None self._type = None self._rdonly = False + self._ready = False super().__init__(fo, astn) @@ -240,8 +241,11 @@ class LCTermNode(LCFuncNode): self.__assert_type(val) self._value = val + + self._ready = True self.__update_value() self._env.dependency().cascade(self) + def set_default(self, val): self.__assert_type(val) @@ -253,6 +257,9 @@ class LCTermNode(LCFuncNode): def get_value(self): return self._value + def is_ready(self): + return self._ready + def evaluate(self): super().evaluate() self.__update_value() diff --git a/lunaix-os/scripts/build-tools/luna_build.py b/lunaix-os/scripts/build-tools/luna_build.py index 3d7f21a..f5893c6 100755 --- a/lunaix-os/scripts/build-tools/luna_build.py +++ b/lunaix-os/scripts/build-tools/luna_build.py @@ -28,21 +28,23 @@ def prepare_lconfig_env(out_dir): env.register_builtin_func(builtin.default) env.register_builtin_func(builtin.include) env.register_builtin_func(builtin.env) + env.register_builtin_func(builtin.set_value) env.type_factory().regitser(lcfg_type.PrimitiveType) env.type_factory().regitser(lcfg_type.MultipleChoiceType) return env -def do_config(lcfg_env): +def do_config(opt, lcfg_env): + redo_config = not exists(opt.config_save) or opt.force + if not redo_config: + return + shell = InteractiveShell(lcfg_env) if not shell.render_loop(): print("Configuration aborted.") exit(-1) - lcfg_env.export() - lcfg_env.save() - def do_buildfile_gen(opts, lcfg_env): root_path = abspath(opts.root) ws_path = dirname(root_path) @@ -70,6 +72,8 @@ def main(): parser = ArgumentParser() parser.add_argument("--config", action="store_true", default=False) parser.add_argument("--lconfig-file", default="LConfig") + parser.add_argument("--config-save", default=".config.json") + parser.add_argument("--force", action="store_true", default=False) parser.add_argument("root", nargs="?", default="LBuild") parser.add_argument("-o", "--out-dir", required=True) @@ -79,12 +83,22 @@ def main(): mkdir(out_dir) lcfg_env = prepare_lconfig_env(out_dir) - lcfg_env.resolve_module(opts.lconfig_file) - lcfg_env.update() - lcfg_env.load() - + require_config = exists(opts.lconfig_file) + try: + if require_config: + lcfg_env.resolve_module(opts.lconfig_file) + lcfg_env.update() + lcfg_env.load() + except Exception as e: + print(e) + if opts.config: - do_config(lcfg_env) + if require_config: + do_config(opts, lcfg_env) + else: + print("No configuration file detected, skipping...") + lcfg_env.save(opts.config_save) + lcfg_env.export() else: do_buildfile_gen(opts, lcfg_env) diff --git a/lunaix-os/scripts/gen_ksymtable.sh b/lunaix-os/scripts/gen_ksymtable.sh index 720dc55..1f974bd 100755 --- a/lunaix-os/scripts/gen_ksymtable.sh +++ b/lunaix-os/scripts/gen_ksymtable.sh @@ -4,9 +4,16 @@ sym_types=$1 bin=$2 nm_out=$(nm -nfbsd "$bin") +class_info=$(readelf -h "$bin" | grep 'Class:' | awk '{print $2}') + allsyms=($nm_out) allsyms_len=${#allsyms[@]} +dtype="4byte" +if [ "$class_info" == 'ELF64' ]; then + dtype="8byte" +fi + syms_idx=() for (( i=0; i None: + self.name = name + self._opt = opt + + def get_qemu_opts(self) -> list: + pass + +class BasicSerialDevice(QEMUPeripherals): + def __init__(self, opt) -> None: + super().__init__("serial", opt) + + def get_qemu_opts(self): + link, logfile = parse_protocol(self._opt) + + cmds = [ link, "server", "nowait" ] + if logfile: + cmds.append(f"logfile={logfile}") + return [ "-serial", join_attrs(cmds) ] + +class PCISerialDevice(QEMUPeripherals): + def __init__(self, opt) -> None: + super().__init__("pci-serial", opt) + + def get_qemu_opts(self): + name = f"chrdev.{hex(self.__hash__())[2:]}" + cmds = [ "pci-serial", f"chardev={name}" ] + chrdev = [ "file", f"id={name}" ] + + logfile = get_config(self._opt, "logfile", required=True) + chrdev.append(f"path={logfile}") + () + return [ + "-chardev", join_attrs(chrdev), + "-device", join_attrs(cmds) + ] + +class AHCIBus(QEMUPeripherals): + def __init__(self, opt) -> None: + super().__init__("ahci", opt) + + def get_qemu_opts(self): + opt = self._opt + name: str = get_config(opt, "name", required=True) + name = name.strip().replace(" ", "_") + cmds = [ "-device", f"ahci,id={name}" ] + + for i, disk in enumerate(get_config(opt, "disks", default=[])): + d_type = get_config(disk, "type", default="ide-hd") + d_img = get_config(disk, "img", required=True) + d_ro = get_config(disk, "ro", default=False) + d_fmt = get_config(disk, "format", default="raw") + d_id = f"disk_{i}" + + cmds += [ + "-drive", join_attrs([ + f"id={d_id}," + f"file={d_img}", + f"readonly={'on' if d_ro else 'off'}", + f"if=none", + f"format={d_fmt}" + ]), + "-device", join_attrs([ + d_type, + f"drive={d_id}", + f"bus={name}.{i}" + ]) + ] + + return cmds + +class RTCDevice(QEMUPeripherals): + def __init__(self, opt) -> None: + super().__init__("rtc", opt) + + def get_qemu_opts(self): + opt = self._opt + base = get_config(opt, "base", default="utc") + return [ "-rtc", f"base={base}" ] + +class QEMUMonitor(QEMUPeripherals): + def __init__(self, opt) -> None: + super().__init__("monitor", opt) + + def get_qemu_opts(self): + link, logfile = parse_protocol(self._opt) + + return [ + "-monitor", join_attrs([ + link, + "server", + "nowait", + f"logfile={logfile}" + ]) + ] + +class QEMUExec: + devices = { + "basic_serial": BasicSerialDevice, + "ahci": AHCIBus, + "rtc": RTCDevice, + "hmp": QEMUMonitor, + "pci-serial": PCISerialDevice + } + + def __init__(self, options) -> None: + self._opt = options + self._devices = [] + + for dev in get_config(options, "devices", default=[]): + dev_class = get_config(dev, "class") + if dev_class not in QEMUExec.devices: + raise Exception(f"device class: {dev_class} is not defined") + + self._devices.append(QEMUExec.devices[dev_class](dev)) + + def get_qemu_exec_name(self): + pass + + def get_qemu_arch_opts(self): + cmds = [ + "-machine", get_config(self._opt, "machine"), + "-cpu", join_attrs([ + get_config(self._opt, "cpu/type", required=True), + *get_config(self._opt, "cpu/features", default=[]), + ]) + ] + + return cmds + + def get_qemu_debug_opts(self): + cmds = [ "-no-reboot", "-no-shutdown" ] + debug = get_config(self._opt, "debug") + if not debug: + return cmds + + cmds.append("-S") + cmds += [ "-gdb", f"tcp::{get_config(debug, 'gdb_port', default=1234)}" ] + + trace_opts = get_config(debug, "traced", []) + for trace in trace_opts: + cmds += [ "-d", f"trace:{trace}"] + + return cmds + + def get_qemu_general_opts(self): + return [ + "-m", get_config(self._opt, "memory", required=True), + "-smp", get_config(self._opt, "ncpu", default=1) + ] + + def add_peripheral(self, peripheral): + self._devices.append(peripheral) + + def start(self, qemu_dir_override=""): + qemu_path = self.get_qemu_exec_name() + qemu_path = os.path.join(qemu_dir_override, qemu_path) + cmds = [ + qemu_path, + *self.get_qemu_arch_opts(), + *self.get_qemu_debug_opts() + ] + + for dev in self._devices: + cmds += dev.get_qemu_opts() + + print(" ".join(cmds), "\n") + + handle = subprocess.Popen(cmds) + + while True: + ret_code = handle.poll() + if ret_code is not None: + return ret_code + time.sleep(5) + +class QEMUx86Exec(QEMUExec): + def __init__(self, options) -> None: + super().__init__(options) + + def get_qemu_exec_name(self): + if get_config(self._opt, "arch") in ["i386", "x86_32"]: + return "qemu-system-i386" + else: + return "qemu-system-x86_64" + +def main(): + global g_lookup + + arg = argparse.ArgumentParser() + + arg.add_argument("config_file") + arg.add_argument("--qemu-dir", default="") + arg.add_argument("-v", "--values", action='append', default=[]) + + arg_opt = arg.parse_args() + + opts = {} + with open(arg_opt.config_file, 'r') as f: + opts.update(json.loads(f.read())) + + for kv in arg_opt.values: + [k, v] = kv.split('=') + g_lookup[k] = v + + arch = get_config(opts, "arch") + + q = None + if arch in ["i386", "x86_32", "x86_64"]: + q = QEMUx86Exec(opts) + else: + raise Exception(f"undefined arch: {arch}") + + q.start(arg_opt.qemu_dir) + +if __name__ == "__main__": + try: + main() + except Exception as e: + print(e) \ No newline at end of file diff --git a/lunaix-os/scripts/qemus/qemu_x86_dev.json b/lunaix-os/scripts/qemus/qemu_x86_dev.json new file mode 100644 index 0000000..474ad1a --- /dev/null +++ b/lunaix-os/scripts/qemus/qemu_x86_dev.json @@ -0,0 +1,58 @@ +{ + "arch": "$ARCH", + "memory": "1G", + "machine": "q35", + "cpu": { + "type": "base", + "features": [ + "rdrand", + "clflush", + "lm", + "nx", + "syscall", + "mca", + "pse36", + "pcid", + "invpcid", + "cmov", + "apic" + ] + }, + "debug": { + "gdb_port": "$GDB_PORT", + "traced": [ + "x86_recv_fault", + "ide_dma_cb" + ] + }, + "devices": [ + { + "class": "basic_serial", + "protocol": "telnet", + "addr": ":12345", + "logfile": "lunaix_ttyS0.log" + }, + { + "class": "rtc", + "base": "utc" + }, + { + "class": "ahci", + "name": "ahci_0", + "disks": [ + { + "type": "ide-cd", + "img": "$KIMG", + "ro": true, + "format": "raw" + } + ] + }, + { + "class": "hmp", + "protocol": "telnet", + "addr": ":$QMPORT", + "logfile": "qm.log" + } + ] +} \ No newline at end of file diff --git a/lunaix-os/usr/.gitignore b/lunaix-os/usr/.gitignore index 8597c11..0d76625 100644 --- a/lunaix-os/usr/.gitignore +++ b/lunaix-os/usr/.gitignore @@ -1,3 +1,5 @@ *.o build/ -.vscode/ \ No newline at end of file +.vscode/ + +uexec.ld \ No newline at end of file diff --git a/lunaix-os/usr/LBuild b/lunaix-os/usr/LBuild new file mode 100644 index 0000000..03a89ee --- /dev/null +++ b/lunaix-os/usr/LBuild @@ -0,0 +1,38 @@ +sources([ + "testp", + "ls", + "signal_demo", + "cat", + "stat", + "test_pthread" +]) + +compile_opts([ + "-ffreestanding", + "-fno-pie" +]) + +linking_opts([ + "-nostdlib", + "-nolibc", + "-z noexecstack", + "-no-pie", +]) + +linking_opts([ + "-Wl,--build-id=none" +]) + +if config("arch") == "x86_64": + compile_opts([ + "-m64", + "-fno-unwind-tables", + "-fno-asynchronous-unwind-tables", + "-mcmodel=large" + ]) + linking_opts([ + "-m64", + ]) +else: + compile_opts("-m32") + linking_opts("-m32") diff --git a/lunaix-os/usr/LConfig b/lunaix-os/usr/LConfig new file mode 100644 index 0000000..ea38d57 --- /dev/null +++ b/lunaix-os/usr/LConfig @@ -0,0 +1,11 @@ +@Term +def arch(): + """ + set the ISA target + """ + type(["i386", "x86_64", "aarch64", "rv64"]) + default("i386") + + env_val = env("ARCH") + if env_val is not None: + set_value(env_val) \ No newline at end of file diff --git a/lunaix-os/usr/execs.list b/lunaix-os/usr/execs.list deleted file mode 100644 index 282adc6..0000000 --- a/lunaix-os/usr/execs.list +++ /dev/null @@ -1,6 +0,0 @@ -testp -ls -signal_demo -cat -stat -test_pthread \ No newline at end of file diff --git a/lunaix-os/usr/init/init.c b/lunaix-os/usr/init/init.c index 45bbf92..2416e07 100644 --- a/lunaix-os/usr/init/init.c +++ b/lunaix-os/usr/init/init.c @@ -42,6 +42,9 @@ init_termios(int fd) { return 0; } +const char* sh_argv[] = { "/usr/bin/sh", 0 }; +const char* sh_envp[] = { 0 }; + int main(int argc, const char** argv) { @@ -64,7 +67,9 @@ main(int argc, const char** argv) pid_t pid; int err = 0; if (!(pid = fork())) { - err = execve("/usr/bin/sh", NULL, NULL); + + + err = execve(sh_argv[0], sh_argv, sh_envp); printf("fail to execute (%d)\n", errno); _exit(err); } diff --git a/lunaix-os/usr/libc/LBuild b/lunaix-os/usr/libc/LBuild new file mode 100644 index 0000000..5c77fe2 --- /dev/null +++ b/lunaix-os/usr/libc/LBuild @@ -0,0 +1,28 @@ +sources([ + "src/string.c", + "src/termios.c", + "src/itoa.c", + "src/_vprintf.c", + "src/readdir.c", + "src/pthread.c", + "src/printf.c" +]) + +sources([ + "src/posix/signal.c", + "src/posix/mount.c", + "src/posix/errno.c", + "src/posix/ioctl.c", + "src/posix/fcntl.c", + "src/posix/dirent.c", + "src/posix/unistd.c", + "src/posix/mann.c", + "src/posix/lunaix.c" +]) + +use({ + env("ARCH"): { + "i386": "arch/i386", + "x86_64": "arch/x86_64", + } +}) \ No newline at end of file diff --git a/lunaix-os/usr/libc/arch/i386/LBuild b/lunaix-os/usr/libc/arch/i386/LBuild new file mode 100644 index 0000000..be547c8 --- /dev/null +++ b/lunaix-os/usr/libc/arch/i386/LBuild @@ -0,0 +1,8 @@ +sources([ + "crt0.S", + "syscall.S", + "trampoline.S", +]) + +compile_opts("-m32") +linking_opts("-m32") \ No newline at end of file diff --git a/lunaix-os/usr/libc/arch/i386/crt0.S b/lunaix-os/usr/libc/arch/i386/crt0.S index a449ac3..1418068 100644 --- a/lunaix-os/usr/libc/arch/i386/crt0.S +++ b/lunaix-os/usr/libc/arch/i386/crt0.S @@ -9,9 +9,17 @@ .section .text .global _start _start: - xorl %eax, %eax xorl %ebp, %ebp + movl %esp, %eax + andl $-16, %esp + + leal 4(%eax), %ebx + pushl %ebx + pushl (%eax) + fninit + + xorl %eax, %eax call main 1: diff --git a/lunaix-os/usr/libc/arch/i386/dirent.c b/lunaix-os/usr/libc/arch/i386/dirent.c deleted file mode 100644 index 1c45242..0000000 --- a/lunaix-os/usr/libc/arch/i386/dirent.c +++ /dev/null @@ -1,4 +0,0 @@ -#include "syscall.h" -#include - -__LXSYSCALL2(int, sys_readdir, int, fd, struct lx_dirent*, dent) diff --git a/lunaix-os/usr/libc/arch/i386/errno.c b/lunaix-os/usr/libc/arch/i386/errno.c deleted file mode 100644 index 3ad6d52..0000000 --- a/lunaix-os/usr/libc/arch/i386/errno.c +++ /dev/null @@ -1,4 +0,0 @@ -#include "syscall.h" -#include - -__LXSYSCALL(int, geterrno); \ No newline at end of file diff --git a/lunaix-os/usr/libc/arch/i386/fcntl.c b/lunaix-os/usr/libc/arch/i386/fcntl.c deleted file mode 100644 index c345ab7..0000000 --- a/lunaix-os/usr/libc/arch/i386/fcntl.c +++ /dev/null @@ -1,6 +0,0 @@ -#include "syscall.h" -#include - -__LXSYSCALL2(int, open, const char*, path, int, options) - -__LXSYSCALL2(int, fstat, int, fd, struct file_stat*, stat) diff --git a/lunaix-os/usr/libc/arch/i386/ioctl.c b/lunaix-os/usr/libc/arch/i386/ioctl.c deleted file mode 100644 index 8675d22..0000000 --- a/lunaix-os/usr/libc/arch/i386/ioctl.c +++ /dev/null @@ -1,4 +0,0 @@ -#include "syscall.h" -#include - -__LXSYSCALL2_VARG(int, ioctl, int, fd, int, req); \ No newline at end of file diff --git a/lunaix-os/usr/libc/arch/i386/lunaix.c b/lunaix-os/usr/libc/arch/i386/lunaix.c deleted file mode 100644 index 87f30bb..0000000 --- a/lunaix-os/usr/libc/arch/i386/lunaix.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "syscall.h" -#include - -__LXSYSCALL(void, yield); - -__LXSYSCALL1(pid_t, wait, int*, status); - -__LXSYSCALL3(pid_t, waitpid, pid_t, pid, int*, status, int, options); - -__LXSYSCALL2_VARG(void, syslog, int, level, const char*, fmt); - -__LXSYSCALL3(int, realpathat, int, fd, char*, buf, size_t, size) diff --git a/lunaix-os/usr/libc/arch/i386/mann.c b/lunaix-os/usr/libc/arch/i386/mann.c deleted file mode 100644 index b21ea3f..0000000 --- a/lunaix-os/usr/libc/arch/i386/mann.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "syscall.h" -#include - -__LXSYSCALL2_VARG(void*, sys_mmap, void*, addr, size_t, length); - -void* -mmap(void* addr, size_t length, int proct, int flags, int fd, off_t offset) -{ - return sys_mmap(addr, length, proct, fd, offset, flags); -} - -__LXSYSCALL2(void, munmap, void*, addr, size_t, length) diff --git a/lunaix-os/usr/libc/arch/i386/mount.c b/lunaix-os/usr/libc/arch/i386/mount.c deleted file mode 100644 index 637f451..0000000 --- a/lunaix-os/usr/libc/arch/i386/mount.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "syscall.h" - -__LXSYSCALL4(int, - mount, - const char*, - source, - const char*, - target, - const char*, - fstype, - int, - options) - -__LXSYSCALL1(int, unmount, const char*, target) \ No newline at end of file diff --git a/lunaix-os/usr/libc/arch/i386/syscall.S b/lunaix-os/usr/libc/arch/i386/syscall.S index 83320ea..9348988 100644 --- a/lunaix-os/usr/libc/arch/i386/syscall.S +++ b/lunaix-os/usr/libc/arch/i386/syscall.S @@ -3,9 +3,7 @@ #define LUNAIX_SYSCALL 33 #define regsize 4 - .struct 8 -saved_registers: - .struct saved_registers + 5 * regsize + .struct 2 * regsize # eip, ebp id: .struct id + regsize a1: @@ -21,29 +19,26 @@ a5: .section .text .type do_lunaix_syscall, @function .global do_lunaix_syscall + do_lunaix_syscall: push %ebp movl %esp, %ebp pushl %ebx - pushl %ecx - pushl %edx pushl %edi pushl %esi - - movl id(%esp), %eax - movl a1(%esp), %ebx - movl a2(%esp), %ecx - movl a3(%esp), %edx - movl a4(%esp), %edi - movl a5(%esp), %esi + + movl id(%ebp), %eax + movl a1(%ebp), %ebx + movl a2(%ebp), %ecx + movl a3(%ebp), %edx + movl a4(%ebp), %edi + movl a5(%ebp), %esi int $LUNAIX_SYSCALL popl %esi popl %edi - popl %edx - popl %ecx popl %ebx leave diff --git a/lunaix-os/usr/libc/arch/i386/syscall.h b/lunaix-os/usr/libc/arch/i386/syscall.h deleted file mode 100644 index 4747678..0000000 --- a/lunaix-os/usr/libc/arch/i386/syscall.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef __LUNAIX_SYSCALL_H -#define __LUNAIX_SYSCALL_H -#include - -#define asmlinkage __attribute__((regparm(0))) - -#define __PARAM_MAP1(t1, p1) t1 p1 -#define __PARAM_MAP2(t1, p1, ...) t1 p1, __PARAM_MAP1(__VA_ARGS__) -#define __PARAM_MAP3(t1, p1, ...) t1 p1, __PARAM_MAP2(__VA_ARGS__) -#define __PARAM_MAP4(t1, p1, ...) t1 p1, __PARAM_MAP3(__VA_ARGS__) -#define __PARAM_MAP5(t1, p1, ...) t1 p1, __PARAM_MAP4(__VA_ARGS__) -#define __PARAM_MAP6(t1, p1, ...) t1 p1, __PARAM_MAP5(__VA_ARGS__) - -#define ___DOINT33(callcode, rettype) \ - int v; \ - asm volatile("int %1\n" : "=a"(v) : "i"(33), "a"(callcode)); \ - return (rettype)v; - -#define __LXSYSCALL(rettype, name) \ - rettype name() \ - { \ - ___DOINT33(__SYSCALL_##name, rettype) \ - } - -#define __LXSYSCALL1(rettype, name, t1, p1) \ - rettype name(__PARAM_MAP1(t1, p1)) \ - { \ - asm("" ::"b"(p1)); \ - ___DOINT33(__SYSCALL_##name, rettype) \ - } - -#define __LXSYSCALL2(rettype, name, t1, p1, t2, p2) \ - rettype name(__PARAM_MAP2(t1, p1, t2, p2)) \ - { \ - asm("\n" ::"b"(p1), "c"(p2)); \ - ___DOINT33(__SYSCALL_##name, rettype) \ - } - -#define __LXSYSCALL3(rettype, name, t1, p1, t2, p2, t3, p3) \ - rettype name(__PARAM_MAP3(t1, p1, t2, p2, t3, p3)) \ - { \ - asm("\n" ::"b"(p1), "c"(p2), "d"(p3)); \ - ___DOINT33(__SYSCALL_##name, rettype) \ - } - -#define __LXSYSCALL4(rettype, name, t1, p1, t2, p2, t3, p3, t4, p4) \ - rettype name(__PARAM_MAP4(t1, p1, t2, p2, t3, p3, t4, p4)) \ - { \ - asm("\n" ::"b"(p1), "c"(p2), "d"(p3), "D"(p4)); \ - ___DOINT33(__SYSCALL_##name, rettype) \ - } - -#define __LXSYSCALL5(rettype, name, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5) \ - rettype name(__PARAM_MAP5(t1, p1, t2, p2, t3, p3, t4, p4, t5, p5)) \ - { \ - asm("" ::"r"(p5), "b"(p1), "c"(p2), "d"(p3), "D"(p4), "S"(p5)); \ - ___DOINT33(__SYSCALL_##name, rettype) \ - } - -#define __LXSYSCALL2_VARG(rettype, name, t1, p1, t2, p2) \ - __attribute__((noinline)) rettype name(__PARAM_MAP2(t1, p1, t2, p2), ...) \ - { \ - /* No inlining! This depends on the call frame assumption */ \ - void* _last = (void*)&p2 + sizeof(void*); \ - asm("\n" ::"b"(p1), "c"(p2), "d"(_last)); \ - ___DOINT33(__SYSCALL_##name, rettype) \ - } - -#endif /* __LUNAIX_SYSCALL_H */ diff --git a/lunaix-os/usr/libc/arch/i386/trampoline.S b/lunaix-os/usr/libc/arch/i386/trampoline.S index 9261e4b..a2d84b6 100644 --- a/lunaix-os/usr/libc/arch/i386/trampoline.S +++ b/lunaix-os/usr/libc/arch/i386/trampoline.S @@ -17,4 +17,16 @@ movl $__SYSCALL_sigreturn, %eax popl %ebx + int $33 + + .global th_trampoline + th_trampoline: + movl (%esp), %eax + movl 4(%esp), %ebx + pushl %ebx + + call *(%eax) + + movl %eax, %ebx + movl $__SYSCALL_th_exit, %eax int $33 \ No newline at end of file diff --git a/lunaix-os/usr/libc/arch/i386/unistd.c b/lunaix-os/usr/libc/arch/i386/unistd.c deleted file mode 100644 index a8c8443..0000000 --- a/lunaix-os/usr/libc/arch/i386/unistd.c +++ /dev/null @@ -1,124 +0,0 @@ -#include "syscall.h" -#include - -__LXSYSCALL(pid_t, fork) - -__LXSYSCALL1(int, brk, void*, addr) - -__LXSYSCALL1(void*, sbrk, ssize_t, size) - -__LXSYSCALL(pid_t, getpid) - -__LXSYSCALL(pid_t, getppid) - -__LXSYSCALL(pid_t, getpgid) - -__LXSYSCALL2(pid_t, setpgid, pid_t, pid, pid_t, pgid) - -__LXSYSCALL1(void, _exit, int, status) - -__LXSYSCALL1(unsigned int, sleep, unsigned int, seconds) - -__LXSYSCALL(int, pause) - -__LXSYSCALL1(unsigned int, alarm, unsigned int, seconds) - -__LXSYSCALL2(int, link, const char*, oldpath, const char*, newpath) - -__LXSYSCALL1(int, rmdir, const char*, pathname) - -__LXSYSCALL3(int, read, int, fd, void*, buf, size_t, count) - -__LXSYSCALL3(int, write, int, fd, void*, buf, size_t, count) - -__LXSYSCALL3(int, readlink, const char*, path, char*, buf, size_t, size) - -__LXSYSCALL3(int, lseek, int, fd, off_t, offset, int, options) - -__LXSYSCALL1(int, unlink, const char*, pathname) - -__LXSYSCALL1(int, close, int, fd) - -__LXSYSCALL2(int, dup2, int, oldfd, int, newfd) - -__LXSYSCALL1(int, dup, int, oldfd) - -__LXSYSCALL1(int, fsync, int, fildes) - -__LXSYSCALL2(int, symlink, const char*, pathname, const char*, link_target) - -__LXSYSCALL1(int, chdir, const char*, path) - -__LXSYSCALL1(int, fchdir, int, fd) - -__LXSYSCALL2(char*, getcwd, char*, buf, size_t, size) - -__LXSYSCALL2(int, rename, const char*, oldpath, const char*, newpath) - -__LXSYSCALL4(int, - getxattr, - const char*, - path, - const char*, - name, - void*, - value, - size_t, - len) - -__LXSYSCALL4(int, - setxattr, - const char*, - path, - const char*, - name, - void*, - value, - size_t, - len) - -__LXSYSCALL4(int, - fgetxattr, - int, - fd, - const char*, - name, - void*, - value, - size_t, - len) - -__LXSYSCALL4(int, - fsetxattr, - int, - fd, - const char*, - name, - void*, - value, - size_t, - len) - -__LXSYSCALL4(int, - readlinkat, - int, - dirfd, - const char*, - pathname, - char*, - buf, - size_t, - size) - -__LXSYSCALL2(int, unlinkat, int, fd, const char*, pathname) - -__LXSYSCALL1(int, mkdir, const char*, path) - -__LXSYSCALL3(int, - execve, - const char*, - filename, - const char**, - argv, - const char**, - envp) \ No newline at end of file diff --git a/lunaix-os/usr/libc/arch/x86_64/LBuild b/lunaix-os/usr/libc/arch/x86_64/LBuild new file mode 100644 index 0000000..8e0ed54 --- /dev/null +++ b/lunaix-os/usr/libc/arch/x86_64/LBuild @@ -0,0 +1,8 @@ +sources([ + "crt0.S", + "syscall.S", + "trampoline.S", +]) + +compile_opts("-m64") +linking_opts("-m64") \ No newline at end of file diff --git a/lunaix-os/usr/libc/arch/x86_64/crt0.S b/lunaix-os/usr/libc/arch/x86_64/crt0.S new file mode 100644 index 0000000..25786df --- /dev/null +++ b/lunaix-os/usr/libc/arch/x86_64/crt0.S @@ -0,0 +1,27 @@ +#define __ASM__ +#include + +.section .data + .global environ + environ: + .long 0 + +.section .text + .global _start + _start: + xorq %rbp, %rbp + + movq %rsp, %rax + movq (%rax), %rdi + leaq 8(%rax), %rsi + + fninit + xorq %rax, %rax + call main + + 1: + movq %rax, %rbx + movq $__SYSCALL__exit, %rax + int $33 + + ud2 // should not reach \ No newline at end of file diff --git a/lunaix-os/usr/libc/arch/x86_64/syscall.S b/lunaix-os/usr/libc/arch/x86_64/syscall.S new file mode 100644 index 0000000..def99e5 --- /dev/null +++ b/lunaix-os/usr/libc/arch/x86_64/syscall.S @@ -0,0 +1,43 @@ +#include + +#define LUNAIX_SYSCALL 33 +#define regsize 8 + + .struct 2 * regsize # rip, rbp +id: + .struct id + regsize +a1: + .struct a1 + regsize +a2: + .struct a2 + regsize +a3: + .struct a3 + regsize +a4: + .struct a4 + regsize +a5: + +.section .text + .type do_lunaix_syscall, @function + .global do_lunaix_syscall + + do_lunaix_syscall: + pushq %rbp + movq %rsp, %rbp + + pushq %rbx + + movq %rcx, %r10 + + movq %rdi, %rax + movq %rsi, %rbx + movq %rdx, %rcx + movq %r10, %rdx + movq %r8, %rdi + movq %r9, %rsi + + int $LUNAIX_SYSCALL + + popq %rbx + + leave + ret \ No newline at end of file diff --git a/lunaix-os/usr/libc/arch/x86_64/trampoline.S b/lunaix-os/usr/libc/arch/x86_64/trampoline.S new file mode 100644 index 0000000..86bdfd1 --- /dev/null +++ b/lunaix-os/usr/libc/arch/x86_64/trampoline.S @@ -0,0 +1,36 @@ +#include + +.section .text + /* + stack structure: + + ...saved_state \ + void* sighand; > struct siguctx + void* sigact; / + int sig_num; <--- %rsp + */ + .global sigtrampoline + sigtrampoline: + movq %rsp, %rax + andq $-16, %rsp + pushq %rax + + movl (%rax), %edi // signum + xorq %rsi, %rsi // siginfo = NULL + leaq 4(%rax), %rdx // (struct siguctx*)&sigact + call sig_dohandling + + movq $__SYSCALL_sigreturn, %rax + popq %rbx + int $33 + + .global th_trampoline + th_trampoline: + movq (%rsp), %rax + movq 8(%rsp), %rdi + + callq %rax + + movq %rax, %rbx + movq $__SYSCALL_th_exit, %rax + int $33 \ No newline at end of file diff --git a/lunaix-os/usr/libc/includes/lunaix/mann.h b/lunaix-os/usr/libc/includes/lunaix/mann.h index fb34d99..2527572 100644 --- a/lunaix-os/usr/libc/includes/lunaix/mann.h +++ b/lunaix-os/usr/libc/includes/lunaix/mann.h @@ -5,8 +5,8 @@ #include #include -extern void* mmap(void* addr, size_t length, int proct, int flags, int fd, off_t offset); +void* mmap(void* addr, size_t length, int proct, int flags, int fd, off_t offset); -extern void munmap(void* addr, size_t length); +int munmap(void* addr, size_t length); #endif /* __LUNAIX_MANN_H */ diff --git a/lunaix-os/usr/libc/includes/lunaix/syscall.h b/lunaix-os/usr/libc/includes/lunaix/syscall.h index 9449999..26ab167 100644 --- a/lunaix-os/usr/libc/includes/lunaix/syscall.h +++ b/lunaix-os/usr/libc/includes/lunaix/syscall.h @@ -3,7 +3,7 @@ #include -extern unsigned long +extern unsigned long do_lunaix_syscall(unsigned long call_id, ...); #endif /* __LUNAIX_OSDEPS_SYSCALL_H */ diff --git a/lunaix-os/usr/libc/includes/stdio.h b/lunaix-os/usr/libc/includes/stdio.h index 26c9b56..f62e46e 100644 --- a/lunaix-os/usr/libc/includes/stdio.h +++ b/lunaix-os/usr/libc/includes/stdio.h @@ -1,10 +1,18 @@ #ifndef __LUNAIX_USTDIO_H #define __LUNAIX_USTDIO_H +#include + #define stdout 0 #define stdin 1 -extern int +int printf(const char* fmt, ...); +int +vsnprintf(char* buffer, unsigned int size, const char* fmt, va_list ap); + +int +snprintf(char* buffer, unsigned int size, const char* fmt, ...); + #endif /* __LUNAIX_USTDIO_H */ diff --git a/lunaix-os/usr/libc/makefile b/lunaix-os/usr/libc/makefile index 5c4d3b0..d2f2a06 100644 --- a/lunaix-os/usr/libc/makefile +++ b/lunaix-os/usr/libc/makefile @@ -1,20 +1,22 @@ +include lunabuild.mkinc + +include $(lbuild_mkinc) + libc_include := $(CURDIR)/includes -ARCH ?= i386 BUILD_DIR ?= bin BUILD_NAME ?= liblunac src_dirs := src src_dirs += arch/$(ARCH) -src_files := $(foreach f, $(src_dirs), $(shell find $(f) -name "*.[cS]")) -obj_files := $(addsuffix .o, $(src_files)) +obj_files := $(addsuffix .o, $(_LBUILD_SRCS)) build_lib := $(BUILD_DIR)/lib build_include := $(BUILD_DIR)/includes libc_include_opt = $(addprefix -I, $(libc_include)) -global_include_opt = $(addprefix -I, $(INCLUDES)) +global_include_opt = $(addprefix -I, $(INCLUDES) $(_LBUILD_INCS)) check_folders := $(src_dirs) check_folders += $(build_lib) $(build_include) @@ -40,6 +42,7 @@ $(build_lib)/$(BUILD_NAME): $(obj_files) @$(AR) rcs $@ $^ clean: + @rm -rf $(lbuild_dir) @rm -f $(obj_files) headers: $(libc_include) diff --git a/lunaix-os/usr/libc/src/_vprintf.c b/lunaix-os/usr/libc/src/_vprintf.c index 28dea37..16d8133 100644 --- a/lunaix-os/usr/libc/src/_vprintf.c +++ b/lunaix-os/usr/libc/src/_vprintf.c @@ -2,6 +2,7 @@ #include #include #include +#include #define NUMBUFSIZ 24 @@ -196,3 +197,19 @@ __vprintf_internal(char* buffer, const char* fmt, size_t max_len, va_list vargs) return ptr; } + +int +vsnprintf(char* buffer, unsigned int size, const char* fmt, va_list ap) +{ + return __vprintf_internal(buffer, fmt, size, ap); +} + +int +snprintf(char* buffer, unsigned int size, const char* fmt, ...) +{ + va_list l; + va_start(l, fmt); + int r = __vprintf_internal(buffer, fmt, size, l); + va_end(l); + return r; +} \ No newline at end of file diff --git a/lunaix-os/usr/libc/src/posix/dirent.c b/lunaix-os/usr/libc/src/posix/dirent.c new file mode 100644 index 0000000..6651d5e --- /dev/null +++ b/lunaix-os/usr/libc/src/posix/dirent.c @@ -0,0 +1,8 @@ +#include +#include + +int +sys_readdir(int fd, struct lx_dirent* dirent) +{ + return do_lunaix_syscall(__SYSCALL_sys_readdir, fd, dirent); +} \ No newline at end of file diff --git a/lunaix-os/usr/libc/src/posix/errno.c b/lunaix-os/usr/libc/src/posix/errno.c new file mode 100644 index 0000000..1652995 --- /dev/null +++ b/lunaix-os/usr/libc/src/posix/errno.c @@ -0,0 +1,8 @@ +#include +#include + +int +geterrno() +{ + return do_lunaix_syscall(__SYSCALL_geterrno); +} \ No newline at end of file diff --git a/lunaix-os/usr/libc/src/posix/fcntl.c b/lunaix-os/usr/libc/src/posix/fcntl.c new file mode 100644 index 0000000..28f1ff3 --- /dev/null +++ b/lunaix-os/usr/libc/src/posix/fcntl.c @@ -0,0 +1,14 @@ +#include +#include + +int +open(const char* path, int options) +{ + return do_lunaix_syscall(__SYSCALL_open, path, options); +} + +int +fstat(int fd, struct file_stat* stat) +{ + return do_lunaix_syscall(__SYSCALL_fstat, fd, stat); +} \ No newline at end of file diff --git a/lunaix-os/usr/libc/src/posix/ioctl.c b/lunaix-os/usr/libc/src/posix/ioctl.c new file mode 100644 index 0000000..d3a89a8 --- /dev/null +++ b/lunaix-os/usr/libc/src/posix/ioctl.c @@ -0,0 +1,15 @@ +#include +#include +#include + +int __attribute__((noinline)) +ioctl(int fd, int req, ...) +{ + va_list ap; + va_start(ap, req); + + int ret = do_lunaix_syscall(__SYSCALL_ioctl, fd, req, &ap); + + va_end(ap); + return ret; +} \ No newline at end of file diff --git a/lunaix-os/usr/libc/src/posix/lunaix.c b/lunaix-os/usr/libc/src/posix/lunaix.c new file mode 100644 index 0000000..452f02d --- /dev/null +++ b/lunaix-os/usr/libc/src/posix/lunaix.c @@ -0,0 +1,40 @@ +#include +#include +#include + +void +yield() +{ + do_lunaix_syscall(__SYSCALL_yield); +} + +pid_t +wait(int* status) +{ + return do_lunaix_syscall(__SYSCALL_wait, status); +} + +pid_t +waitpid(pid_t pid, int* status, int options) +{ + return do_lunaix_syscall(__SYSCALL_waitpid, pid, status, options); +} + +void +syslog(int level, const char* fmt, ...) +{ + char buf[1024]; + va_list ap; + va_start(ap, fmt); + + unsigned int size = vsnprintf(buf, 1024, fmt, ap); + do_lunaix_syscall(__SYSCALL_syslog, level, buf, size); + + va_end(ap); +} + +int +realpathat(int fd, char* buf, size_t size) +{ + return do_lunaix_syscall(__SYSCALL_realpathat, fd, buf, size); +} \ No newline at end of file diff --git a/lunaix-os/usr/libc/src/posix/mann.c b/lunaix-os/usr/libc/src/posix/mann.c new file mode 100644 index 0000000..f2fe186 --- /dev/null +++ b/lunaix-os/usr/libc/src/posix/mann.c @@ -0,0 +1,24 @@ +#include +#include +#include + +void* +mmap(void* addr, size_t length, int proct, int flags, int fd, off_t offset) +{ + struct usr_mmap_param mparam = { + .addr = addr, + .length = length, + .proct = proct, + .flags = flags, + .fd = fd, + .offset = offset + }; + + return (void*)do_lunaix_syscall(__SYSCALL_sys_mmap, &mparam); +} + +int +munmap(void* addr, size_t length) +{ + return do_lunaix_syscall(__SYSCALL_munmap, addr, length); +} diff --git a/lunaix-os/usr/libc/src/posix/mount.c b/lunaix-os/usr/libc/src/posix/mount.c new file mode 100644 index 0000000..930930c --- /dev/null +++ b/lunaix-os/usr/libc/src/posix/mount.c @@ -0,0 +1,14 @@ +#include + +int +mount(const char* source, const char* target, + const char* fstype, int options) +{ + return do_lunaix_syscall(__SYSCALL_mount, source, target, fstype, options); +} + +int +unmount(const char* target) +{ + return do_lunaix_syscall(__SYSCALL_unmount, target); +} \ No newline at end of file diff --git a/lunaix-os/usr/libc/arch/i386/signal.c b/lunaix-os/usr/libc/src/posix/signal.c similarity index 58% rename from lunaix-os/usr/libc/arch/i386/signal.c rename to lunaix-os/usr/libc/src/posix/signal.c index 2434fc9..8c93fa2 100644 --- a/lunaix-os/usr/libc/arch/i386/signal.c +++ b/lunaix-os/usr/libc/src/posix/signal.c @@ -1,26 +1,43 @@ -#include "syscall.h" +#include #include #include -__LXSYSCALL1(int, sigpending, sigset_t, *set); -__LXSYSCALL1(int, sigsuspend, const sigset_t, *mask); +int +sigpending(sigset_t *set) +{ + return do_lunaix_syscall(__SYSCALL_sigpending, set); +} -__LXSYSCALL3(int, - sigprocmask, - int, - how, - const sigset_t, - *set, - sigset_t, - *oldset); +int +sigsuspend(const sigset_t *mask) +{ + return do_lunaix_syscall(__SYSCALL_sigsuspend, mask); +} -__LXSYSCALL2(int, sys_sigaction, int, signum, struct sigaction*, action); +int +sigprocmask(int how, const sigset_t *set, sigset_t *oldset) +{ + return do_lunaix_syscall(__SYSCALL_sigprocmask, how, set, oldset); +} + +int +sys_sigaction(int signum, struct sigaction* action) +{ + return do_lunaix_syscall(__SYSCALL_sys_sigaction, signum, action); +} -__LXSYSCALL2(int, kill, pid_t, pid, int, signum); +int +kill(pid_t pid, int signum) +{ + return do_lunaix_syscall(__SYSCALL_kill, pid, signum); +} extern void sigtrampoline(); +extern pid_t +getpid(); + sighandler_t signal(int signum, sighandler_t handler) { @@ -33,9 +50,6 @@ signal(int signum, sighandler_t handler) return handler; } -extern pid_t -getpid(); - int raise(int signum) { diff --git a/lunaix-os/usr/libc/src/posix/unistd.c b/lunaix-os/usr/libc/src/posix/unistd.c new file mode 100644 index 0000000..8e17324 --- /dev/null +++ b/lunaix-os/usr/libc/src/posix/unistd.c @@ -0,0 +1,211 @@ +#include +#include + +pid_t +fork() +{ + return do_lunaix_syscall(__SYSCALL_fork); +} + +int +brk(void* addr) +{ + return do_lunaix_syscall(__SYSCALL_brk, addr); +} + +void* +sbrk(ssize_t size) +{ + return (void*)do_lunaix_syscall(__SYSCALL_sbrk, size); +} + +pid_t +getpid() +{ + return do_lunaix_syscall(__SYSCALL_getpid); +} + +pid_t +getppid() +{ + return do_lunaix_syscall(__SYSCALL_getppid); +} + +pid_t +getpgid() +{ + return do_lunaix_syscall(__SYSCALL_getpgid); +} + +pid_t +setpgid(pid_t pid, pid_t pgid) +{ + return do_lunaix_syscall(__SYSCALL_setpgid, pid, pgid); +} +void +_exit(int status) +{ + do_lunaix_syscall(__SYSCALL__exit, status); +} + +unsigned int +sleep(unsigned int seconds) +{ + return do_lunaix_syscall(__SYSCALL_sleep, seconds); +} + +int +pause() +{ + return do_lunaix_syscall(__SYSCALL_pause); +} + +unsigned int +alarm(unsigned int seconds) +{ + return do_lunaix_syscall(__SYSCALL_alarm, seconds); +} + +int +link(const char* oldpath, const char* newpath) +{ + return do_lunaix_syscall(__SYSCALL_link, oldpath, newpath); +} + +int +rmdir(const char* pathname) +{ + return do_lunaix_syscall(__SYSCALL_rmdir, pathname); +} + +int +read(int fd, void* buf, size_t count) +{ + return do_lunaix_syscall(__SYSCALL_read, fd, buf, count); +} + +int +write(int fd, void* buf, size_t count) +{ + return do_lunaix_syscall(__SYSCALL_write, fd, buf, count); +} + +int +readlink(const char* path, char* buf, size_t size) +{ + return do_lunaix_syscall(__SYSCALL_readlink, path, buf, size); +} + +int +lseek(int fd, off_t offset, int options) +{ + return do_lunaix_syscall(__SYSCALL_lseek, fd, offset, options); +} + +int +unlink(const char* pathname) +{ + return do_lunaix_syscall(__SYSCALL_unlink, pathname); +} + +int +close(int fd) +{ + return do_lunaix_syscall(__SYSCALL_close, fd); +} + +int +dup2(int oldfd, int newfd) +{ + return do_lunaix_syscall(__SYSCALL_dup2, oldfd, newfd); +} + +int +dup(int oldfd) +{ + return do_lunaix_syscall(__SYSCALL_dup, oldfd); +} + +int +fsync(int fildes) +{ + return do_lunaix_syscall(__SYSCALL_fsync, fildes); +} + +int +symlink(const char* pathname, const char* link_target) +{ + return do_lunaix_syscall(__SYSCALL_symlink, pathname, link_target); +} + +int +chdir(const char* path) +{ + return do_lunaix_syscall(__SYSCALL_chdir, path); +} + +int +fchdir(int fd) +{ + return do_lunaix_syscall(__SYSCALL_fchdir, fd); +} + +char* +getcwd(char* buf, size_t size) +{ + return (char*)do_lunaix_syscall(__SYSCALL_getcwd, buf, size); +} + +int +rename(const char* oldpath, const char* newpath) +{ + return do_lunaix_syscall(__SYSCALL_rename, oldpath, newpath); +} + +int +getxattr(const char* path, const char* name, void* value, size_t len) +{ + return do_lunaix_syscall(__SYSCALL_getxattr, path, name, value, len); +} + +int +setxattr(const char* path, const char* name, void* value, size_t len) +{ + return do_lunaix_syscall(__SYSCALL_setxattr, path, name, value, len); +} + +int +fgetxattr(int fd, const char* name, void* value, size_t len) +{ + return do_lunaix_syscall(__SYSCALL_fgetxattr, fd, name, value, len); +} + +int +fsetxattr(int fd, const char* name, void* value, size_t len) +{ + return do_lunaix_syscall(__SYSCALL_fsetxattr, fd, name, value, len); +} + +int +readlinkat(int dirfd, const char* pathname, char* buf, size_t size) +{ + return do_lunaix_syscall(__SYSCALL_readlinkat, dirfd, pathname, buf, size); +} + +int +unlinkat(int fd, const char* pathname) +{ + return do_lunaix_syscall(__SYSCALL_unlinkat, fd, pathname); +} + +int +mkdir(const char* path) +{ + return do_lunaix_syscall(__SYSCALL_mkdir, path); +} + +int +execve(const char* filename, const char** argv, const char** envp) +{ + return do_lunaix_syscall(__SYSCALL_execve, filename, argv, envp); +} diff --git a/lunaix-os/usr/libc/src/pthread.c b/lunaix-os/usr/libc/src/pthread.c index 08c82e0..26d6abf 100644 --- a/lunaix-os/usr/libc/src/pthread.c +++ b/lunaix-os/usr/libc/src/pthread.c @@ -1,37 +1,21 @@ #include #include -static void* -__pthread_routine_wrapper(void *(*start_routine)(void*), void* arg) -{ - void* ret = start_routine(arg); - - do_lunaix_syscall(__SYSCALL_th_exit, ret); - - return ret; // should not reach -} - int pthread_create(pthread_t* thread, const pthread_attr_t* attr, void *(*start_routine)(void*), void* arg) { // FIXME attr currently not used + int ret; + struct uthread_param th_param; - struct uthread_info th_info; - int ret = do_lunaix_syscall(__SYSCALL_th_create, thread, &th_info, __pthread_routine_wrapper, NULL); - - if (ret) { - return ret; - } - - // FIXME we should encapsulate these parameter into struct - // and pass it as a single thread param. - - void** th_stack = (void**) th_info.th_stack_top; - th_stack[1] = (void*)start_routine; - th_stack[2] = arg; + th_param.th_handler = start_routine; + th_param.arg1 = arg; + extern void th_trampoline(); + ret = do_lunaix_syscall(__SYSCALL_th_create, thread, + &th_param, th_trampoline); return ret; } diff --git a/lunaix-os/usr/makefile b/lunaix-os/usr/makefile index 4dc8d0d..54f7260 100644 --- a/lunaix-os/usr/makefile +++ b/lunaix-os/usr/makefile @@ -1,25 +1,34 @@ include utils.mkinc include toolchain.mkinc +include lunabuild.mkinc -task := all +include $(lbuild_mkinc) + +ifndef ARCH +$(error ARCH is not set) +endif -# TODO make this use LBuild -CFLAGS += -m32 -ffreestanding -fno-pie -LDFLAGS += -m32 -nostdlib -nolibc -z noexecstack -no-pie -Wl,--build-id=none +task := all sys_include := $(CURDIR)/includes build_dir := $(CURDIR)/build libc_name := liblunac libc_files := $(libc_name).a libc := $(addprefix $(build_dir)/lib/,$(libc_files)) -ldscript := $(CURDIR)/link-usr.ld -common_param := CC AR INCLUDES BUILD_DIR BUILD_NAME CFLAGS LDFLAGS +common_param := CC AR INCLUDES BUILD_DIR BUILD_NAME\ + CFLAGS LDFLAGS ARCH LBUILD INCLUDES := $(sys_include) BUILD_DIR := $(build_dir) BUILD_NAME := $(libc_name).a +mkapp-list := $(addprefix app-, $(shell cat apps.list)) +mkexec-list := $(addprefix $(build_dir)/bin/, $(_LBUILD_SRCS)) + +uexec_ld := $(CURDIR)/uexec.ld + +# Directory structure prerequisites $(build_dir)/bin: @mkdir -p $(build_dir)/bin @@ -29,43 +38,48 @@ $(build_dir)/lib: $(build_dir)/includes: @mkdir -p $(build_dir)/includes +# LibC export $(common_param) $(build_dir)/$(libc_name).a: $(build_dir)/bin $(build_dir)/lib $(build_dir)/includes $(call status,TASK,$(BUILD_NAME)) @$(MAKE) $(MKFLAGS) -C libc/ $(task) -app-list = $(shell cat apps.list) -exec-list = $(shell cat execs.list) +$(uexec_ld): $(uexec_ld)x + @$(CC) -include $(lbuild_config_h) -x c -P -E $< -o $@ -mkapp-list := $(addprefix app-, $(app-list)) -mkexec-list := $(addprefix $(build_dir)/bin/, $(exec-list)) - -export LD_SCRIPT := $(ldscript) +# Application (with standalone makefile) +export LD_SCRIPT := $(uexec_ld) export LIBC := $(libc) -app-%: +export $(common_param) +app-%: $(uexec_ld) $(call status,TASK,$*) @$(MAKE) $(MKFLAGS) -C $* $(task) BUILD_NAME="$*" +app: task := all +app: INCLUDES += $(build_dir)/includes +app: $(mkapp-list) + + +# Programs (single file) exec_%.o: %.c $(call status,CC,$<) @$(CC) $(CFLAGS) $(addprefix -I,$(INCLUDES)) -c $< -o $@ -$(build_dir)/bin/%: exec_%.o +$(build_dir)/bin/%: exec_%.o $(uexec_ld) $(call status,LD,$(@F)) - @$(CC) -T $(ldscript) -o $@ $< $(libc) $(LDFLAGS) - -app: task := all -app: INCLUDES += $(build_dir)/includes -app: $(mkapp-list) + @$(CC) -T $(uexec_ld) -o $@ $< $(libc) $(LDFLAGS) exec: task := all exec: INCLUDES += $(build_dir)/includes exec: $(mkexec-list) + +# General recipes clean: task := clean clean: $(mkapp-list) - @rm -rf $(build_dir) + @rm -rf $(build_dir) $(lbuild_dir) $(uexec_ld) @$(MAKE) $(MKFLAGS) -C libc/ $(task) +.NOTPARALLEL: all: task := all all: $(build_dir)/$(libc_name).a exec app \ No newline at end of file diff --git a/lunaix-os/usr/sh/sh.c b/lunaix-os/usr/sh/sh.c index 2c9bb8d..2ac473a 100644 --- a/lunaix-os/usr/sh/sh.c +++ b/lunaix-os/usr/sh/sh.c @@ -46,8 +46,8 @@ strltrim_safe(char* str) return strcpy(str, str + l); } -void -parse_cmdline(char* line, char** cmd, char** arg_part) +int +parse_cmdline(char* line, char** args) { strrtrim(line); line = strltrim_safe(line); @@ -60,12 +60,15 @@ parse_cmdline(char* line, char** cmd, char** arg_part) } l++; } - *cmd = line; - if (c) { - *arg_part = strltrim_safe(line + l); + + args[0] = line; + if (c && l) { + args[1] = strltrim_safe(line + l); } else { - *arg_part = NULL; + args[1] = NULL; } + + return !!l; } void @@ -108,17 +111,19 @@ sigint_handle(int signum) } void -sh_exec(const char* name, const char** argv) +sh_exec(const char** argv) { + const char* envp[] = { 0 }; + char* name = argv[0]; if (!strcmp(name, "cd")) { - chdir(argv[0] ? argv[0] : "."); + chdir(argv[1] ? argv[1] : "."); sh_printerr(); return; } pid_t p; if (!(p = fork())) { - if (execve(name, argv, NULL)) { + if (execve(name, argv, envp)) { sh_printerr(); } _exit(1); @@ -139,7 +144,7 @@ sh_loop() // stdout (by default, unless user did smth) is the tty we are currently at ioctl(stdout, TIOCSPGRP, getpgid()); - char* argv[] = {0, 0}; + char* argv[] = {0, 0, 0}; while (1) { getcwd(pwd, 512); @@ -154,19 +159,17 @@ sh_loop() buf[sz] = '\0'; // currently, this shell only support single argument - parse_cmdline(buf, &cmd, &argv[0]); - - if (cmd[0] == 0) { + if (!parse_cmdline(buf, argv)) { printf("\n"); goto cont; } // cmd=="exit" - if (*(unsigned int*)cmd == 0x74697865U) { + if (*(unsigned int*)argv[0] == 0x74697865U) { break; } - sh_exec(cmd, (const char**)&argv); + sh_exec((const char**)argv); cont: printf("\n"); } diff --git a/lunaix-os/usr/test_pthread.c b/lunaix-os/usr/test_pthread.c index 247c368..0c1dfe6 100644 --- a/lunaix-os/usr/test_pthread.c +++ b/lunaix-os/usr/test_pthread.c @@ -8,11 +8,14 @@ Test payloads */ +#define __int(ptr) ((int)(unsigned long)(ptr)) +#define __ptr(ptr) ((void*)(unsigned long)(ptr)) + static void* __print_and_sleep_randsec(void* value) { pthread_t tid = pthread_self(); - printf("thread %d: gets number %d\n", tid, (int)value); + printf("thread %d: gets number %d\n", tid, __int(value)); int fd = open("/dev/rand", O_RDONLY | O_DIRECT); if (fd < 0) { @@ -40,9 +43,9 @@ static void* __print_and_sleep_seq(void* value) { pthread_t tid = pthread_self(); - printf("thread %d: gets number %d\n", tid, (int)value); + printf("thread %d: gets number %d\n", tid, __int(value)); - int second = (int)value % 30; + int second = __int(value) % 30; printf("thread %d: going to sleep %ds\n", tid, second); sleep(second); @@ -55,7 +58,7 @@ static void* __print_and_sleep(void* value) { pthread_t tid = pthread_self(); - printf("thread %d: gets number %d\n", tid, (int)value); + printf("thread %d: gets number %d\n", tid, __int(value)); sleep(1); printf("thread %d: exit\n", tid); @@ -95,7 +98,7 @@ spawn_detached_thread(void* (*fn)(void *), int amount) int err; pthread_t created; for (int i = 0; i < amount; i++) { - err = pthread_create(&created, NULL, fn, (void*)i); + err = pthread_create(&created, NULL, fn, __ptr(i)); if (err) { printf("unable to create thread: %d\n", err); continue; @@ -136,7 +139,7 @@ pthread_test_join(int param) void* v; for (int i = 0; i < param; i++) { - err = pthread_create(&created, NULL, __print_and_sleep, (void*)i); + err = pthread_create(&created, NULL, __print_and_sleep, __ptr(i)); if (err) { printf("unable to create thread: %d\n", err); } @@ -169,7 +172,7 @@ pthread_test_quit(int param) do { \ printf("** [%s] test start\n", note); \ pthread_test_##testn(__VA_ARGS__); \ - printf("** [%s] test passed\n"); \ + printf("** [%s] test passed\n", note); \ } while (0) int main() diff --git a/lunaix-os/usr/link-usr.ld b/lunaix-os/usr/uexec.ldx similarity index 62% rename from lunaix-os/usr/link-usr.ld rename to lunaix-os/usr/uexec.ldx index ab77bb4..6703b9e 100644 --- a/lunaix-os/usr/link-usr.ld +++ b/lunaix-os/usr/uexec.ldx @@ -1,7 +1,13 @@ ENTRY(_start) +#ifdef CONFIG_ARCH_X86_64 +# define EXEC_START 0x0000008000000000 +#else +# define EXEC_START 0x400000 +#endif + SECTIONS { - . = 0x400000; + . = EXEC_START; .text BLOCK(4K) : { *(.text) -- 2.27.0