MOS Source Code
Loading...
Searching...
No Matches
kmain.c
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2
6#include "mos/mm/mm.h"
9#include "mos/tasks/elf.h"
10
11#include <mos/device/console.h>
12#include <mos/filesystem/vfs.h>
13#include <mos/interrupt/ipi.h>
14#include <mos/ipc/ipc.h>
15#include <mos/lib/cmdline.h>
16#include <mos/misc/cmdline.h>
17#include <mos/misc/setup.h>
19#include <mos/syslog/printk.h>
20#include <mos/tasks/kthread.h>
21#include <mos/tasks/schedule.h>
22#include <mos_stdio.h>
23#include <mos_stdlib.h>
24#include <mos_string.h>
25
27
28static void invoke_constructors(void)
29{
30 typedef void (*init_function_t)(void);
31 extern const init_function_t __init_array_start[], __init_array_end;
32
33 pr_dinfo2(setup, "invoking constructors...");
34 for (const init_function_t *func = __init_array_start; func != &__init_array_end; func++)
35 {
36 pr_dinfo2(setup, " %ps", (void *) (ptr_t) *func);
37 (*func)();
38 }
39}
40
41static struct
42{
43 size_t argc; // size of argv, does not include the terminating NULL
44 const char **argv;
45} init_args = { 0 };
46
47static bool init_sysfs_argv(sysfs_file_t *file)
48{
49 for (u32 i = 0; i < init_args.argc; i++)
50 sysfs_printf(file, "%s ", init_args.argv[i]);
51 sysfs_printf(file, "\n");
52 return true;
53}
54
55SYSFS_ITEM_RO_STRING(kernel_sysfs_version, MOS_KERNEL_VERSION)
56SYSFS_ITEM_RO_STRING(kernel_sysfs_revision, MOS_KERNEL_REVISION)
57SYSFS_ITEM_RO_STRING(kernel_sysfs_build_date, __DATE__)
58SYSFS_ITEM_RO_STRING(kernel_sysfs_build_time, __TIME__)
59SYSFS_ITEM_RO_STRING(kernel_sysfs_compiler, __VERSION__)
60SYSFS_ITEM_RO_STRING(kernel_sysfs_arch, MOS_ARCH)
61SYSFS_ITEM_RO_STRING(init_sysfs_path, init_args.argv[0])
62SYSFS_ITEM_RO_PRINTF(initrd_sysfs_info, "pfn: " PFN_FMT "\nnpages: %zu\n", platform_info->initrd_pfn, platform_info->initrd_npages)
63
65 SYSFS_RO_ITEM("arch", kernel_sysfs_arch), //
66 SYSFS_RO_ITEM("build_date", kernel_sysfs_build_date), //
67 SYSFS_RO_ITEM("build_time", kernel_sysfs_build_time), //
68 SYSFS_RO_ITEM("compiler", kernel_sysfs_compiler), //
69 SYSFS_RO_ITEM("init_argv", init_sysfs_argv), //
70 SYSFS_RO_ITEM("init_path", init_sysfs_path), //
71 SYSFS_RO_ITEM("initrd", initrd_sysfs_info), //
72 SYSFS_RO_ITEM("revision", kernel_sysfs_revision), //
73 SYSFS_RO_ITEM("version", kernel_sysfs_version), //
74};
75
77
78MOS_SETUP("init", setup_init_path)
79{
80 if (!arg)
81 {
82 pr_warn("init path not specified");
83 return false;
84 }
85
86 if (init_args.argv)
87 kfree(init_args.argv[0]); // free the old init path
88
89 init_args.argv[0] = strdup(arg);
90 return true;
91}
92
93MOS_SETUP("init_args", setup_init_args)
94{
95 char *var_arg = strdup(arg);
96 string_unquote(var_arg);
97 init_args.argv = cmdline_parse(init_args.argv, var_arg, strlen(var_arg), &init_args.argc);
98 kfree(var_arg);
99 return true;
100}
101
103{
104 pr_info("Welcome to MOS!");
105 pr_emph("MOS %s on %s (%s, %s), compiler %s", MOS_KERNEL_VERSION, MOS_ARCH, MOS_KERNEL_REVISION, __DATE__, __VERSION__);
106
108 pr_emph("MOS Kernel cmdline");
109
110 for (u32 i = 0; i < platform_info->n_cmdlines; i++)
111 {
112 const cmdline_option_t *opt = &platform_info->cmdlines[i];
113 if (opt->arg)
114 pr_info2(" %-2d: %-10s = %s", i, opt->name, opt->arg);
115 else
116 pr_info2(" %-2d: %s", i, opt->name);
117 }
118
120 pmm_init();
121
122 pr_dinfo2(vmm, "initializing paging...");
127 current_cpu->mm_context = platform_info->kernel_mm;
128
130
131 pr_dinfo2(vmm, "mapping kernel space...");
138 );
139
145 VM_READ | VM_GLOBAL //
146 );
147
154 );
155
157
160
161 // power management
163
164 // register builtin filesystems
168
171
172 init_args.argc = 1;
173 init_args.argv = kcalloc(1, sizeof(char *)); // init_argv[0] is the init path
176 init_args.argv = krealloc(init_args.argv, (init_args.argc + 1) * sizeof(char *));
177 init_args.argv[init_args.argc] = NULL;
178
179 long ret = vfs_mount("none", "/", "tmpfs", NULL);
180 if (IS_ERR_VALUE(ret))
181 mos_panic("failed to mount rootfs, vfs_mount returns %ld", ret);
182
183 vfs_mkdir("/initrd");
184 ret = vfs_mount("none", "/initrd/", "cpiofs", NULL);
185 if (IS_ERR_VALUE(ret))
186 mos_panic("failed to mount initrd, vfs_mount returns %ld", ret);
187
188 ipc_init();
189 tasks_init();
191
192 console_t *const init_con = platform_info->boot_console;
193 if (unlikely(!init_con))
194 mos_panic("failed to get console");
195
196 const stdio_t init_io = { .in = &init_con->io, .out = &init_con->io, .err = &init_con->io };
197 const char *const init_envp[] = {
198 "PATH=/initrd/programs:/initrd/bin:/bin",
199 "HOME=/",
200 "TERM=linux",
201 NULL,
202 };
203
204 pr_info("run '%s' as init process", init_args.argv[0]);
205 pr_info2(" with arguments:");
206 for (u32 i = 0; i < init_args.argc; i++)
207 pr_info2(" argv[%d] = %s", i, init_args.argv[i]);
208 pr_info2(" with environment:");
209 for (u32 i = 0; init_envp[i]; i++)
210 pr_info2(" %s", init_envp[i]);
211
212 process_t *init = elf_create_process(init_args.argv[0], NULL, init_args.argv, init_envp, &init_io);
213 if (unlikely(!init))
214 mos_panic("failed to create init process");
215
216 vmap_t *initrd_map = mm_map_user_pages( //
217 init->mm, //
221 VM_USER_RO, //
222 VALLOC_EXACT, //
224 VMAP_FILE //
225 );
226
229
230 MOS_ASSERT_X(initrd_map, "failed to map initrd into init process");
231
232 kthread_init(); // must be called after creating the first init process
234
236
237 pr_cont("\n");
240}
#define MOS_ASSERT_X(cond, msg,...)
Definition assert.h:15
#define MOS_UNREACHABLE()
Definition assert.h:11
#define MOS_PAGE_SIZE
Definition autoconf.h:6
#define MOS_INITRD_BASE
Definition autoconf.h:22
#define MOS_DEFAULT_INIT_PATH
Definition autoconf.h:13
process_t * elf_create_process(const char *path, process_t *parent, const char *const argv[], const char *const envp[], const stdio_t *ios)
Definition elf.c:408
MOSAPI char * strdup(const char *src)
MOSAPI void(1, 2) fatal_abort(const char *fmt
MOSAPI void linked_list_init(list_node_t *head_node)
Initialise a circular double linked list.
Definition list.c:15
@ VMAP_TYPE_SHARED
Definition mm.h:32
@ VMAP_FILE
Definition mm.h:24
vmap_t * mm_map_user_pages(mm_context_t *mmctx, ptr_t vaddr, pfn_t pfn, size_t npages, vm_flags flags, valloc_flags vaflags, vmap_type_t type, vmap_content_t content)
Definition paging.c:92
void mm_map_kernel_pages(mm_context_t *mmctx, ptr_t vaddr, pfn_t pfn, size_t npages, vm_flags flags)
Map a block of virtual memory to a block of physical memory.
Definition paging.c:82
@ VALLOC_EXACT
Allocate pages at the exact address.
Definition paging.h:22
#define pmm_ref(thing, npages)
Definition pmm.h:143
void pmm_init()
Definition pmm.c:20
long vfs_mount(const char *device, const char *path, const char *fs, const char *options)
Mount a filesystem at a given existing path.
Definition vfs.c:466
long vfs_mkdir(const char *path)
Create a directory.
Definition vfs.c:664
void ipc_init(void)
Definition ipc.c:170
static sysfs_item_t kernel_sysfs_items[]
Definition kmain.c:64
static void invoke_constructors(void)
Definition kmain.c:28
static mm_context_t mos_kernel_mm
Definition kmain.c:26
static struct @25 init_args
void mos_start_kernel(void)
Definition kmain.c:102
static bool init_sysfs_argv(sysfs_file_t *file)
Definition kmain.c:47
const char ** argv
Definition kmain.c:44
size_t argc
Definition kmain.c:43
void kthread_init(void)
Definition kthread.c:29
void string_unquote(char *str)
Definition cmdline.c:107
const char ** cmdline_parse(const char **inargv, char *inbuf, size_t length, size_t *out_count)
Definition cmdline.c:98
#define ALIGN_UP_TO_PAGE(addr)
Definition mos_global.h:75
#define IS_ERR_VALUE(x)
Definition mos_global.h:126
#define unlikely(x)
Definition mos_global.h:40
#define mos_panic(fmt,...)
Definition panic.h:55
#define NULL
Definition pb_syshdr.h:46
static size_t strlen(const char *s)
Definition pb_syshdr.h:80
const char __MOS_KERNEL_RODATA_START[]
__BEGIN_DECLS const char __MOS_KERNEL_CODE_START[]
__BEGIN_DECLS const char __MOS_KERNEL_CODE_END[]
Definition platform.h:147
const char __MOS_KERNEL_RW_START[]
const char __MOS_KERNEL_RODATA_END[]
Definition platform.h:148
@ VM_GLOBAL
Definition platform.h:48
@ VM_READ
Definition platform.h:41
@ VM_EXEC
Definition platform.h:43
@ VM_WRITE
Definition platform.h:42
@ VM_USER_RO
Definition platform.h:56
#define MOS_KERNEL_PFN(vaddr)
Definition platform.h:137
#define current_cpu
Definition platform.h:29
const char __MOS_KERNEL_RW_END[]
Definition platform.h:149
#define pgd_create(top)
Definition pml_types.h:89
#define pml_create_table(x)
Definition pml_types.h:107
#define MOS_PMLTOP
Definition pml_types.h:82
#define pr_info2(fmt,...)
Definition printk.h:36
#define pr_warn(fmt,...)
Definition printk.h:38
#define pr_info(fmt,...)
Definition printk.h:35
#define pr_cont(fmt,...)
Definition printk.h:41
#define pr_emph(fmt,...)
Definition printk.h:37
#define pr_dinfo2(feat, fmt,...)
Definition printk.h:27
void platform_startup_setup_kernel_mm()
void platform_startup_late()
void platform_startup_early()
mos_platform_info_t *const platform_info
void platform_switch_mm(const mm_context_t *new_mm)
void scheduler_init()
Definition schedule.c:50
void unblock_scheduler(void)
Unblock the scheduler, so that APs can start scheduling.
Definition schedule.c:60
void enter_scheduler(void)
Enter the scheduler and switch to the next thread.
Definition schedule.c:67
__BEGIN_DECLS void tasks_init()
Definition tasks.c:46
@ INIT_TARGET_POST_MM
Definition setup.h:9
@ INIT_TARGET_PRE_VFS
Definition setup.h:12
@ INIT_TARGET_KTHREAD
Definition setup.h:15
@ INIT_TARGET_POWER
Definition setup.h:11
@ INIT_TARGET_SLAB_AUTOINIT
Definition setup.h:10
@ INIT_TARGET_VFS
Definition setup.h:13
@ INIT_TARGET_SYSFS
Definition setup.h:14
#define MOS_SETUP(_param, _fn)
Definition setup.h:35
__BEGIN_DECLS void startup_invoke_cmdline_hooks(void)
Definition setup.c:49
void startup_invoke_autoinit(init_target_t target)
Definition setup.c:8
#define spinlock_init(lock)
Definition spinlock.h:21
const char * name
Definition cmdline.h:9
const char * arg
Definition cmdline.h:10
io_t io
Definition console.h:29
spinlock_t mm_lock
protects [pgd] and the [mmaps] list (the list itself, not the vmap_t objects)
Definition platform.h:81
list_head mmaps
Definition platform.h:83
pgd_t pgd
Definition platform.h:82
console_t * boot_console
Definition platform.h:134
mm_context_t * kernel_mm
Definition platform.h:118
cmdline_option_t cmdlines[MOS_MAX_CMDLINE_COUNT]
Definition platform.h:130
mm_context_t * mm
Definition task_types.h:59
A wrapper type for the standard I/O streams.
Definition process.h:17
Definition mm.h:58
ssize_t sysfs_printf(sysfs_file_t *file, const char *fmt,...)
Definition sysfs.c:73
#define SYSFS_ITEM_RO_STRING(name, value)
Definition sysfs.h:63
#define SYSFS_ITEM_RO_PRINTF(name, fmt,...)
Definition sysfs.h:56
#define SYSFS_RO_ITEM(_name, _show_fn)
Definition sysfs.h:48
#define SYSFS_AUTOREGISTER(sysfs_name, sysfs_items)
unsigned int u32
Definition types.h:21
#define PFN_FMT
Definition types.h:42
unsigned long ptr_t
Definition types.h:25