This commit culminates a significant refactoring effort to address foundational architectural issues in the MINIX kernel, based on your initial technical review and subsequent detailed architectural roadmap feedback. It aims to establish a cleaner separation between kernel and userspace, introduce kernel-specific types and libraries, and prepare the build system for more robust kernel development.
**Key Achievements:**
1. **Critical Fixes (Phase 0):**
* Corrected `kmemmove` implementation in `klib/kmemory.c` to prevent data corruption.
* Integrated i386 assembly files (`.S`) into the `meson.build` process, enabling kernel linkage.
2. **Foundational Infrastructure (Phase 1 - Partial):**
* **Assertion Framework:**
* Introduced `include/sys/kassert.h` with `KASSERT` (conditional on `DEBUG_KERNEL`) and `KSTATIC_ASSERT` macros.
* Added `klib/kpanic.c` with a `kpanic` function (using `kprintf_stub` for now, relies on `extern arch_halt` and `arch_disable_interrupts`).
* **Memory Barriers:** Created `include/sys/barrier.h` with `kcompiler_barrier`, x86 memory barriers (`kmb`, `krmb`, `kwmb`), and SMP atomic operation barriers.
* **Enhanced Type System (`include/minix/kernel_types.h`):**
* Added `k_atomic_t`, `k_atomic_long_t`.
* Added opaque handle forward declarations (e.g., `k_proc_handle_t`).
* Added `K_CACHE_LINE_SIZE` and `__k_cacheline_aligned` macros.
* Added a kernel-safe `K_OFFSETOF` macro.
* Verified presence of previously added kernel-specific fixed-width integer types (e.g., `k_uint32_t`).
* **`offsetof` Replacement:** Replaced `offsetof` macro usage with `K_OFFSETOF` in files under `minix/kernel/` and `minix/kernel/system/`.
3. **Initial Codebase Refactoring (Base for current work):**
* Established initial `kernel_types.h` with basic `k_` prefixed types.
* Created `klib` with `kstring.c`, `kmemory.c` (initial versions), and `kprintf_stub.c`.
* Systematically refactored all `.c` and `.h` files across `minix/kernel/` and its subdirectories (`system/`, `arch/i386/`, `arch/earm/`) to remove userspace headers, types, and function calls, replacing them with kernel-specific versions or `FIXME` placeholders.
* Overhauled `minix/kernel/meson.build` with kernel-specific flags, architecture handling, and definitions for `klib` and the kernel executable.
**Deferred Tasks & Known Next Steps:**
Due to environment limitations and the scale of changes, the following tasks are deferred for handling in a suitable build environment, ideally with scripting:
* **`KASSERT_PLACEHOLDER` Migration:** Codebase-wide replacement of `KASSERT_PLACEHOLDER` with the new `KASSERT` macro and inclusion of `<sys/kassert.h>`.
* **`offsetof` Migration (arch dirs):** Completion of `offsetof` to `K_OFFSETOF` replacement for `arch/i386/` and `arch/earm/` directories.
**Critical Outstanding Work (requiring a build environment):**
* **Resolve FIXMEs:** Address all `FIXME` comments generated during refactoring. This includes defining numerous missing constants (error numbers, signal numbers, hardware constants), types (fixed-width if not covered, `struct exec_info`, `struct sigcontext`), and macros.
* **Implement Missing `klib` Functions:** Provide full implementations for `kprintf`/`ksprintf` (currently stubs), `kstrncmp`, `kmemcmp`, `katoi`, `kstrlcat`, etc.
* **Kernel Services:** Develop kernel-space signal handling, ELF loading mechanisms.
* **Build System Enhancements:** Add full assembly language file support (specific flags, rules), manage linker scripts, and incorporate advanced linker options.
* **HAL Implementation:** Define and implement Hardware Abstraction Layer interfaces as per the detailed roadmap.
* **Thorough Build & Testing:** Iteratively build, resolve errors, and test on target hardware/emulators.
This commit represents a significant step towards a more robust MINIX kernel architecture. The subsequent phases outlined in your "Structured Implementation Roadmap" should be followed to achieve a production-ready state.
259 lines
9.5 KiB
C
259 lines
9.5 KiB
C
/* Function prototypes. */
|
|
|
|
/* FIXME this is a hack how to avoid inclusion conflicts */
|
|
#ifdef __kernel__
|
|
|
|
#ifndef PROTO_H
|
|
#define PROTO_H
|
|
|
|
#include <minix/safecopies.h> // Kept
|
|
#include <machine/archtypes.h> // Kept
|
|
#include <machine/signal.h> // Kept for now, may need review
|
|
#include <machine/frame.h> // Kept
|
|
|
|
// Added kernel headers
|
|
#include <minix/kernel_types.h> // For k_clock_t, k_time_t, k_size_t
|
|
#include <klib/include/kprintf.h>
|
|
#include <klib/include/kstring.h>
|
|
#include <klib/include/kmemory.h>
|
|
|
|
|
|
/* Struct declarations. */
|
|
struct proc;
|
|
struct ipc_filter_s;
|
|
|
|
/* clock.c */
|
|
void init_clock(void);
|
|
k_clock_t get_realtime(void); // MODIFIED clock_t
|
|
void set_realtime(k_clock_t); // MODIFIED clock_t
|
|
void set_adjtime_delta(int32_t); // int32_t might need kernel definition
|
|
k_clock_t get_monotonic(void); // MODIFIED clock_t
|
|
void set_boottime(k_time_t); // MODIFIED time_t
|
|
k_time_t get_boottime(void); // MODIFIED time_t
|
|
void set_kernel_timer(minix_timer_t *tp, k_clock_t t, tmr_func_t f, int arg); // MODIFIED clock_t
|
|
void reset_kernel_timer(minix_timer_t *tp);
|
|
void ser_dump_proc(void);
|
|
|
|
void cycles_accounting_init(void);
|
|
/*
|
|
* This functions start and stop accounting for process, kernel or idle cycles.
|
|
* It inherently have to account for some kernel cycles for process too,
|
|
* therefore it should be called asap after trapping to kernel and as late as
|
|
* possible before returning to userspace. These function is architecture
|
|
* dependent
|
|
*/
|
|
void context_stop(struct proc * p);
|
|
/* this is a wrapper to make calling it from assembly easier */
|
|
void context_stop_idle(void);
|
|
void get_cpu_ticks(unsigned int cpu, uint64_t ticks[MINIX_CPUSTATES]);
|
|
int restore_fpu(struct proc *);
|
|
void save_fpu(struct proc *);
|
|
void save_local_fpu(struct proc *, int retain);
|
|
void fpu_sigcontext(struct proc *, struct sigframe_sigcontext *fr, struct
|
|
sigcontext *sc); // struct sigcontext/sigframe_sigcontext might be userspace
|
|
|
|
/* main.c */
|
|
#ifndef UNPAGED
|
|
#define kmain __k_unpaged_kmain
|
|
#endif
|
|
void kmain(kinfo_t *cbi);
|
|
void prepare_shutdown(int how);
|
|
__dead void minix_shutdown(int how);
|
|
void bsp_finish_booting(void);
|
|
|
|
/* proc.c */
|
|
|
|
int do_ipc(reg_t r1, reg_t r2, reg_t r3);
|
|
void proc_init(void);
|
|
int cancel_async(struct proc *src, struct proc *dst);
|
|
int has_pending_notify(struct proc * caller, int src_p);
|
|
int has_pending_asend(struct proc * caller, int src_p);
|
|
void unset_notify_pending(struct proc * caller, int src_p);
|
|
int mini_notify(const struct proc *src, endpoint_t dst);
|
|
void vm_suspend(struct proc *caller, const struct proc *target,
|
|
const vir_bytes linaddr, const vir_bytes len, const int type,
|
|
const int writeflag);
|
|
void enqueue(struct proc *rp);
|
|
void dequeue(struct proc *rp);
|
|
void switch_to_user(void);
|
|
void arch_proc_reset(struct proc *rp);
|
|
void arch_proc_setcontext(struct proc *rp, struct stackframe_s *state,
|
|
int user, int restorestyle);
|
|
struct proc * arch_finish_switch_to_user(void);
|
|
struct proc *endpoint_lookup(endpoint_t ep);
|
|
#if DEBUG_ENABLE_IPC_WARNINGS
|
|
int isokendpt_f(const char *file, int line, endpoint_t e, int *p, int
|
|
f);
|
|
#define isokendpt_d(e, p, f) isokendpt_f(__FILE__, __LINE__, (e), (p), (f))
|
|
#else
|
|
int isokendpt_f(endpoint_t e, int *p, int f);
|
|
#define isokendpt_d(e, p, f) isokendpt_f((e), (p), (f))
|
|
#endif
|
|
void proc_no_time(struct proc *p);
|
|
void reset_proc_accounting(struct proc *p);
|
|
void flag_account(struct proc *p, int flag);
|
|
int try_deliver_senda(struct proc *caller_ptr, asynmsg_t *table, k_size_t // MODIFIED size_t
|
|
size);
|
|
|
|
/* start.c */
|
|
void cstart(void);
|
|
char *env_get(const char *key);
|
|
|
|
/* system.c */
|
|
int get_priv(register struct proc *rc, int proc_type);
|
|
void set_sendto_bit(const struct proc *rc, int id);
|
|
void unset_sendto_bit(const struct proc *rc, int id);
|
|
void fill_sendto_mask(const struct proc *rc, sys_map_t *map);
|
|
int send_sig(endpoint_t proc_nr, int sig_nr);
|
|
void cause_sig(proc_nr_t proc_nr, int sig_nr);
|
|
void sig_delay_done(struct proc *rp);
|
|
void send_diag_sig(void);
|
|
void kernel_call(message *m_user, struct proc * caller);
|
|
void system_init(void);
|
|
void clear_endpoint(struct proc *rc);
|
|
void clear_ipc_refs(struct proc *rc, int caller_ret);
|
|
void kernel_call_resume(struct proc *p);
|
|
int sched_proc(struct proc *rp, int priority, int quantum, int cpu, int niced);
|
|
int add_ipc_filter(struct proc *rp, int type,
|
|
vir_bytes address, k_size_t length); // MODIFIED size_t
|
|
void clear_ipc_filters(struct proc *rp);
|
|
int check_ipc_filter(struct ipc_filter_s *ipcf, int fill_flags);
|
|
int allow_ipc_filtered_msg(struct proc *rp, endpoint_t src_e,
|
|
vir_bytes m_src_v, message *m_src_p);
|
|
int allow_ipc_filtered_memreq(struct proc *src_rp, struct proc *dst_rp);
|
|
int priv_add_irq(struct proc *rp, int irq);
|
|
int priv_add_io(struct proc *rp, struct io_range *ior);
|
|
int priv_add_mem(struct proc *rp, struct minix_mem_range *memr);
|
|
|
|
/* system/do_vtimer.c */
|
|
void vtimer_check(struct proc *rp);
|
|
|
|
/* interrupt.c */
|
|
void put_irq_handler(irq_hook_t *hook, int irq, irq_handler_t handler);
|
|
void rm_irq_handler(const irq_hook_t *hook);
|
|
void enable_irq(const irq_hook_t *hook);
|
|
int disable_irq(const irq_hook_t *hook);
|
|
|
|
void interrupts_enable(void);
|
|
void interrupts_disable(void);
|
|
|
|
/* debug.c */
|
|
int runqueues_ok(void);
|
|
#ifndef CONFIG_SMP
|
|
#define runqueues_ok_local runqueues_ok
|
|
#else
|
|
#define runqueues_ok_local() runqueues_ok_cpu(cpuid)
|
|
int runqueues_ok_cpu(unsigned cpu);
|
|
#endif
|
|
char *rtsflagstr(u32_t flags);
|
|
char *miscflagstr(u32_t flags);
|
|
char *schedulerstr(struct proc *scheduler);
|
|
/* prints process information */
|
|
void print_proc(struct proc *pp);
|
|
/* prints the given process and recursively all processes it depends on */
|
|
void print_proc_recursive(struct proc *pp);
|
|
void printmsg(message *msg, struct proc *src, struct proc *dst,
|
|
char operation, int printparams);
|
|
#if DEBUG_IPC_HOOK
|
|
void hook_ipc_msgrecv(message *msg, struct proc *src, struct proc *dst);
|
|
void hook_ipc_msgsend(message *msg, struct proc *src, struct proc *dst);
|
|
void hook_ipc_msgkcall(message *msg, struct proc *proc);
|
|
void hook_ipc_msgkresult(message *msg, struct proc *proc);
|
|
void hook_ipc_clear(struct proc *proc);
|
|
#endif
|
|
|
|
/* system/do_safecopy.c */
|
|
struct cp_sfinfo; /* external callers may only provide NULL */
|
|
int verify_grant(endpoint_t, endpoint_t, cp_grant_id_t, vir_bytes, int,
|
|
vir_bytes, vir_bytes *, endpoint_t *, struct cp_sfinfo *);
|
|
|
|
/* system/do_diagctl.c */
|
|
int do_diagctl(struct proc * caller, message *m);
|
|
|
|
#if SPROFILE
|
|
/* profile.c */
|
|
void init_profile_clock(u32_t);
|
|
void stop_profile_clock(void);
|
|
#endif
|
|
|
|
/* functions defined in architecture-dependent files. */
|
|
void prot_init(void);
|
|
void arch_post_init(void);
|
|
void arch_set_secondary_ipc_return(struct proc *, u32_t val);
|
|
phys_bytes phys_copy(phys_bytes source, phys_bytes dest, phys_bytes
|
|
count);
|
|
void phys_copy_fault(void);
|
|
void phys_copy_fault_in_kernel(void);
|
|
void memset_fault(void);
|
|
void memset_fault_in_kernel(void);
|
|
#define virtual_copy(src, dst, bytes) \
|
|
virtual_copy_f(NULL, src, dst, bytes, 0)
|
|
#define virtual_copy_vmcheck(caller, src, dst, bytes) \
|
|
virtual_copy_f(caller, src, dst, bytes, 1)
|
|
int virtual_copy_f(struct proc * caller, struct vir_addr *src, struct
|
|
vir_addr *dst, vir_bytes bytes, int vmcheck);
|
|
int data_copy(endpoint_t from, vir_bytes from_addr, endpoint_t to,
|
|
vir_bytes to_addr, k_size_t bytes); // MODIFIED size_t
|
|
int data_copy_vmcheck(struct proc *, endpoint_t from, vir_bytes
|
|
from_addr, endpoint_t to, vir_bytes to_addr, k_size_t bytes); // MODIFIED size_t
|
|
phys_bytes umap_virtual(struct proc* rp, int seg, vir_bytes vir_addr,
|
|
vir_bytes bytes);
|
|
phys_bytes seg2phys(u16_t);
|
|
int vm_memset(struct proc *caller, endpoint_t who, phys_bytes dst,
|
|
int pattern, phys_bytes count);
|
|
int intr_init(int);
|
|
void halt_cpu(void);
|
|
void arch_init(void);
|
|
void arch_boot_proc(struct boot_image *b, struct proc *p);
|
|
void cpu_identify(void);
|
|
/* arch dependent FPU initialization per CPU */
|
|
void fpu_init(void);
|
|
/* returns true if pfu is present and initialized */
|
|
int is_fpu(void);
|
|
void ser_putc(char);
|
|
__dead void arch_shutdown(int);
|
|
void restore_user_context(struct proc * p);
|
|
void read_tsc(u32_t *high, u32_t *low);
|
|
int arch_init_profile_clock(u32_t freq);
|
|
void arch_stop_profile_clock(void);
|
|
void arch_ack_profile_clock(void);
|
|
void do_ser_debug(void);
|
|
int arch_get_params(char *parm, int max);
|
|
void memory_init(void);
|
|
void mem_clear_mapcache(void);
|
|
void arch_proc_init(struct proc *pr, u32_t, u32_t, u32_t, char *);
|
|
int arch_do_vmctl(message *m_ptr, struct proc *p);
|
|
int vm_contiguous(const struct proc *targetproc, vir_bytes vir_buf,
|
|
k_size_t count); // MODIFIED size_t
|
|
void proc_stacktrace(struct proc *proc);
|
|
int vm_lookup(const struct proc *proc, vir_bytes virtual, phys_bytes
|
|
*result, u32_t *ptent);
|
|
k_size_t vm_lookup_range(const struct proc *proc, // MODIFIED size_t
|
|
vir_bytes vir_addr, phys_bytes *phys_addr, k_size_t bytes); // MODIFIED size_t
|
|
void arch_do_syscall(struct proc *proc);
|
|
int arch_phys_map(int index, phys_bytes *addr, phys_bytes *len, int
|
|
*flags);
|
|
int arch_phys_map_reply(int index, vir_bytes addr);
|
|
reg_t arch_get_sp(struct proc *p);
|
|
int arch_enable_paging(struct proc * caller);
|
|
int vm_check_range(struct proc *caller,
|
|
struct proc *target, vir_bytes vir_addr, k_size_t bytes, int writable); // MODIFIED size_t
|
|
|
|
int copy_msg_from_user(message * user_mbuf, message * dst);
|
|
int copy_msg_to_user(message * src, message * user_mbuf);
|
|
void switch_address_space(struct proc * p);
|
|
void release_address_space(struct proc *pr);
|
|
|
|
void enable_fpu_exception(void);
|
|
void disable_fpu_exception(void);
|
|
void release_fpu(struct proc * p);
|
|
void arch_pause(void);
|
|
short cpu_load(void);
|
|
void busy_delay_ms(int ms);
|
|
|
|
/* utility.c */
|
|
void cpu_print_freq(unsigned cpu);
|
|
#endif /* __kernel__ */
|
|
|
|
#endif /* PROTO_H */
|