MOS Source Code
Loading...
Searching...
No Matches
kmain.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2
6#include "mos/mm/mm.hpp"
9#include "mos/tasks/elf.hpp"
10
11#include <mos/allocator.hpp>
14#include <mos/interrupt/ipi.hpp>
15#include <mos/ipc/ipc.hpp>
16#include <mos/lib/cmdline.hpp>
17#include <mos/list.hpp>
18#include <mos/misc/cmdline.hpp>
19#include <mos/misc/setup.hpp>
21#include <mos/shared_ptr.hpp>
22#include <mos/syslog/printk.hpp>
23#include <mos/tasks/kthread.hpp>
25#include <mos/type_utils.hpp>
26#include <mos_stdlib.hpp>
27#include <mos_string.hpp>
28
30
31static struct
32{
33 size_t argc = 0; // size of argv, does not include the terminating NULL
34 const char **argv = nullptr;
36
37static bool init_sysfs_argv(sysfs_file_t *file)
38{
39 for (u32 i = 0; i < init_args.argc; i++)
40 sysfs_printf(file, "%s ", init_args.argv[i]);
41 sysfs_printf(file, "\n");
42 return true;
43}
44
45SYSFS_ITEM_RO_STRING(kernel_sysfs_version, MOS_KERNEL_VERSION)
46SYSFS_ITEM_RO_STRING(kernel_sysfs_revision, MOS_KERNEL_REVISION)
47SYSFS_ITEM_RO_STRING(kernel_sysfs_build_date, __DATE__)
48SYSFS_ITEM_RO_STRING(kernel_sysfs_build_time, __TIME__)
49SYSFS_ITEM_RO_STRING(kernel_sysfs_compiler, __VERSION__)
50SYSFS_ITEM_RO_STRING(kernel_sysfs_arch, MOS_ARCH)
51SYSFS_ITEM_RO_STRING(init_sysfs_path, init_args.argv[0])
52SYSFS_ITEM_RO_PRINTF(initrd_sysfs_info, "pfn: " PFN_FMT "\nnpages: %zu\n", platform_info->initrd_pfn, platform_info->initrd_npages)
53
55 SYSFS_RO_ITEM("arch", kernel_sysfs_arch), //
56 SYSFS_RO_ITEM("build_date", kernel_sysfs_build_date), //
57 SYSFS_RO_ITEM("build_time", kernel_sysfs_build_time), //
58 SYSFS_RO_ITEM("compiler", kernel_sysfs_compiler), //
59 SYSFS_RO_ITEM("init_argv", init_sysfs_argv), //
60 SYSFS_RO_ITEM("init_path", init_sysfs_path), //
61 SYSFS_RO_ITEM("initrd", initrd_sysfs_info), //
62 SYSFS_RO_ITEM("revision", kernel_sysfs_revision), //
63 SYSFS_RO_ITEM("version", kernel_sysfs_version), //
64};
65
67
68MOS_SETUP("init", setup_init_path)
69{
70 if (!arg)
71 {
72 pr_warn("init path not specified");
73 return false;
74 }
75
76 if (init_args.argv)
77 kfree(init_args.argv[0]); // free the old init path
78
79 init_args.argv[0] = strdup(arg);
80 return true;
81}
82
83MOS_SETUP("init_args", setup_init_args)
84{
85 char *var_arg = strdup(arg);
86 string_unquote(var_arg);
87 init_args.argv = cmdline_parse(init_args.argv, var_arg, strlen(var_arg), &init_args.argc);
88 kfree(var_arg);
89 return true;
90}
91
93{
94 pr_info("Welcome to MOS!");
95 pr_emph("MOS %s on %s (%s, %s), compiler %s", MOS_KERNEL_VERSION, MOS_ARCH, MOS_KERNEL_REVISION, __DATE__, __VERSION__);
96
97 if (platform_info->n_cmdlines)
98 pr_emph("MOS Kernel cmdline");
99
100 for (u32 i = 0; i < platform_info->n_cmdlines; i++)
101 {
102 const cmdline_option_t *opt = &platform_info->cmdlines[i];
103 if (opt->arg)
104 pr_info2(" %-2d: %-10s = %s", i, opt->name, opt->arg);
105 else
106 pr_info2(" %-2d: %s", i, opt->name);
107 }
108
110 pmm_init();
111
112 pr_dinfo2(vmm, "initializing paging...");
116 platform_info->kernel_mm = &mos_kernel_mm;
117 current_cpu->mm_context = platform_info->kernel_mm;
118
120
121 pr_dinfo2(vmm, "mapping kernel space...");
123 platform_info->kernel_mm, //
128 );
129
131 platform_info->kernel_mm, //
135 VM_READ | VM_GLOBAL //
136 );
137
139 platform_info->kernel_mm, //
144 );
145
147 slab_init(); // now mos::create<T>, kmalloc<T>, etc. are available
148
149 // power management
151
152 // register builtin filesystems
156
158
159 init_args.argc = 1;
160 init_args.argv = kcalloc<const char *>(1); // init_argv[0] is the init path
163 init_args.argv = krealloc(init_args.argv, (init_args.argc + 1) * sizeof(char *));
164 init_args.argv[init_args.argc] = NULL;
165
166 long ret = vfs_mount("none", "/", "tmpfs", NULL);
167 if (IS_ERR_VALUE(ret))
168 mos_panic("failed to mount rootfs, vfs_mount returns %ld", ret);
169
170 vfs_mkdir("/initrd");
171 ret = vfs_mount("none", "/initrd/", "cpiofs", NULL);
172 if (IS_ERR_VALUE(ret))
173 mos_panic("failed to mount initrd, vfs_mount returns %ld", ret);
174
175 ipc_init();
177
178 Console *const init_con = platform_info->boot_console;
179 if (unlikely(!init_con))
180 mos_panic("failed to get console");
181
182 const stdio_t init_io = { .in = &init_con->io, .out = &init_con->io, .err = &init_con->io };
183 const char *const init_envp[] = {
184 "PATH=/initrd/programs:/initrd/bin:/bin",
185 "HOME=/",
186 "TERM=linux",
187 NULL,
188 };
189
190 pr_info("run '%s' as init process", init_args.argv[0]);
191 pr_info2(" with arguments:");
192 for (u32 i = 0; i < init_args.argc; i++)
193 pr_info2(" argv[%d] = %s", i, init_args.argv[i]);
194 pr_info2(" with environment:");
195 for (u32 i = 0; init_envp[i]; i++)
196 pr_info2(" %s", init_envp[i]);
197
198 const auto init = elf_create_process(init_args.argv[0], NULL, init_args.argv, init_envp, &init_io);
199 if (unlikely(!init))
200 mos_panic("failed to create init process");
201
202 auto initrd_map = mm_map_user_pages( //
203 init->mm, //
205 platform_info->initrd_pfn, //
206 platform_info->initrd_npages, //
207 VM_USER_RO, //
208 VALLOC_EXACT, //
210 VMAP_FILE //
211 );
212
213 pmm_ref(platform_info->initrd_pfn, platform_info->initrd_npages);
214 pmm_ref(platform_info->initrd_pfn, platform_info->initrd_npages);
215
216 MOS_ASSERT_X(initrd_map, "failed to map initrd into init process");
217
218 kthread_init(); // must be called after creating the first init process
220
222
223 pr_cont("\n");
226}
#define MOS_ASSERT_X(cond, msg,...)
Definition assert.hpp:15
#define MOS_UNREACHABLE()
Definition assert.hpp: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 * elf_create_process(const char *path, Process *parent, const char *const argv[], const char *const envp[], const stdio_t *ios)
Definition elf.cpp:420
MOSAPI char * strdup(const char *src)
MOSAPI void linked_list_init(list_node_t *head_node)
Initialise a circular double linked list.
Definition list.cpp:15
@ VMAP_TYPE_SHARED
Definition mm.hpp:33
@ VMAP_FILE
Definition mm.hpp:25
void mm_map_kernel_pages(MMContext *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.cpp:82
PtrResult< vmap_t > mm_map_user_pages(MMContext *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.cpp:92
@ VALLOC_EXACT
Allocate pages at the exact address.
Definition paging.hpp:22
#define pmm_ref(thing, npages)
Definition pmm.hpp:155
void pmm_init()
Definition pmm.cpp: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.cpp:460
long vfs_mkdir(const char *path)
Create a directory.
Definition vfs.cpp:675
void ipc_init(void)
Definition ipc.cpp:181
static sysfs_item_t kernel_sysfs_items[]
Definition kmain.cpp:54
static struct @274354113332067226201353316121227275173061230210 init_args
void mos_start_kernel(void)
Definition kmain.cpp:92
static MMContext mos_kernel_mm
Definition kmain.cpp:29
static bool init_sysfs_argv(sysfs_file_t *file)
Definition kmain.cpp:37
const char ** argv
Definition kmain.cpp:34
size_t argc
Definition kmain.cpp:33
void kthread_init(void)
Definition kthread.cpp:30
void string_unquote(char *str)
Definition cmdline.cpp:107
const char ** cmdline_parse(const char **inargv, char *inbuf, size_t length, size_t *out_count)
Definition cmdline.cpp:98
#define ALIGN_UP_TO_PAGE(addr)
Definition mos_global.h:76
#define IS_ERR_VALUE(x)
Definition mos_global.h:137
#define unlikely(x)
Definition mos_global.h:40
#define mos_panic(fmt,...)
Definition panic.hpp:51
#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[]
const char __MOS_KERNEL_CODE_END[]
Definition platform.hpp:150
const char __MOS_KERNEL_RW_START[]
const char __MOS_KERNEL_RODATA_END[]
Definition platform.hpp:151
#define MOS_KERNEL_PFN(vaddr)
Definition platform.hpp:142
const char __MOS_KERNEL_CODE_START[]
@ VM_GLOBAL
Definition platform.hpp:51
@ VM_READ
Definition platform.hpp:44
@ VM_EXEC
Definition platform.hpp:46
@ VM_WRITE
Definition platform.hpp:45
@ VM_USER_RO
Definition platform.hpp:59
#define current_cpu
Definition platform.hpp:31
const char __MOS_KERNEL_RW_END[]
Definition platform.hpp:152
#define pgd_create(top)
Definition pml_types.hpp:89
#define pml_create_table(x)
#define MOS_PMLTOP
Definition pml_types.hpp:82
#define pr_info2(fmt,...)
Definition printk.hpp:36
#define pr_warn(fmt,...)
Definition printk.hpp:38
#define pr_info(fmt,...)
Definition printk.hpp:35
#define pr_cont(fmt,...)
Definition printk.hpp:41
#define pr_emph(fmt,...)
Definition printk.hpp:37
#define pr_dinfo2(feat, fmt,...)
Definition printk.hpp: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 MMContext *new_mm)
void scheduler_init()
Definition schedule.cpp:50
void unblock_scheduler(void)
Unblock the scheduler, so that APs can start scheduling.
Definition schedule.cpp:60
void enter_scheduler(void)
Enter the scheduler and switch to the next thread.
Definition schedule.cpp:67
@ INIT_TARGET_PRE_VFS
Definition setup.hpp:10
@ INIT_TARGET_KTHREAD
Definition setup.hpp:13
@ INIT_TARGET_POWER
Definition setup.hpp:9
@ INIT_TARGET_VFS
Definition setup.hpp:11
@ INIT_TARGET_SYSFS
Definition setup.hpp:12
void startup_invoke_cmdline_hooks(void)
Definition setup.cpp:49
#define MOS_SETUP(_param, _fn)
Definition setup.hpp:33
void startup_invoke_autoinit(init_target_t target)
Definition setup.cpp:8
void slab_init()
initialise the slab allocator
Definition slab.cpp:112
#define spinlock_init(lock)
Definition spinlock.hpp:24
io_t io
Definition console.hpp:36
const char * name
Definition cmdline.hpp:9
const char * arg
Definition cmdline.hpp:10
A wrapper type for the standard I/O streams.
Definition process.hpp:17
ssize_t sysfs_printf(sysfs_file_t *file, const char *fmt,...)
Definition sysfs.cpp:74
#define SYSFS_ITEM_RO_STRING(name, value)
Definition sysfs.hpp:57
#define SYSFS_ITEM_RO_PRINTF(name, fmt,...)
Definition sysfs.hpp:50
#define SYSFS_RO_ITEM(_name, _show_fn)
Definition sysfs.hpp:42
#define SYSFS_AUTOREGISTER(sysfs_name, sysfs_items)
unsigned int u32
Definition types.h:17
#define PFN_FMT
Definition types.h:38
unsigned long ptr_t
Definition types.h:21