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
5#include "mos/mm/mm.hpp"
10#include "mos/tasks/elf.hpp"
11
12#include <mos/allocator.hpp>
15#include <mos/interrupt/ipi.hpp>
16#include <mos/ipc/ipc.hpp>
17#include <mos/lib/cmdline.hpp>
18#include <mos/list.hpp>
19#include <mos/misc/cmdline.hpp>
20#include <mos/misc/setup.hpp>
22#include <mos/shared_ptr.hpp>
23#include <mos/syslog/printk.hpp>
24#include <mos/tasks/kthread.hpp>
26#include <mos/type_utils.hpp>
27#include <mos_stdio.hpp>
28#include <mos_stdlib.hpp>
29#include <mos_string.hpp>
30
32
34
35static bool init_sysfs_argv(sysfs_file_t *file)
36{
37 for (u32 i = 0; i < init_args.size(); i++)
38 sysfs_printf(file, "%s ", init_args[i].c_str());
39 sysfs_printf(file, "\n");
40 return true;
41}
42
43SYSFS_ITEM_RO_STRING(kernel_sysfs_version, MOS_KERNEL_VERSION)
44SYSFS_ITEM_RO_STRING(kernel_sysfs_revision, MOS_KERNEL_REVISION)
45SYSFS_ITEM_RO_STRING(kernel_sysfs_build_date, __DATE__)
46SYSFS_ITEM_RO_STRING(kernel_sysfs_build_time, __TIME__)
47SYSFS_ITEM_RO_STRING(kernel_sysfs_compiler, __VERSION__)
48SYSFS_ITEM_RO_STRING(kernel_sysfs_arch, MOS_ARCH)
49SYSFS_ITEM_RO_STRING(init_sysfs_path, init_args[0].c_str())
50SYSFS_ITEM_RO_PRINTF(initrd_sysfs_info, "pfn: " PFN_FMT "\nnpages: %zu\n", platform_info->initrd_pfn, platform_info->initrd_npages)
51
53 SYSFS_RO_ITEM("arch", kernel_sysfs_arch), //
54 SYSFS_RO_ITEM("build_date", kernel_sysfs_build_date), //
55 SYSFS_RO_ITEM("build_time", kernel_sysfs_build_time), //
56 SYSFS_RO_ITEM("compiler", kernel_sysfs_compiler), //
57 SYSFS_RO_ITEM("init_argv", init_sysfs_argv), //
58 SYSFS_RO_ITEM("init_path", init_sysfs_path), //
59 SYSFS_RO_ITEM("initrd", initrd_sysfs_info), //
60 SYSFS_RO_ITEM("revision", kernel_sysfs_revision), //
61 SYSFS_RO_ITEM("version", kernel_sysfs_version), //
62};
63
65
66MOS_SETUP("init", setup_init_path)
67{
68 if (arg.empty())
69 {
70 pr_warn("init path not specified");
71 return false;
72 }
73
74 if (init_args.empty())
75 init_args.push_back(arg.data());
76 else
77 init_args[0] = arg;
78
79 return true;
80}
81
82MOS_SETUP("init_args", setup_init_args)
83{
84 char *var_arg = strdup(arg.data());
85 string_unquote(var_arg);
86 for (const auto &cmd : cmdline_parse_vector(var_arg, strlen(var_arg)))
87 init_args.push_back(cmd);
88 kfree(var_arg);
89 return true;
90}
91
129
131{
133 mInfo << "Welcome to MOS!";
134 mInfo << fmt("MOS {}-{} on ({}, {}), compiler {}", MOS_KERNEL_VERSION, MOS_ARCH, MOS_KERNEL_REVISION, __DATE__, __VERSION__);
135
136 if (platform_info->n_cmdlines)
137 {
138 mInfo << "MOS Kernel cmdline";
139 for (u32 i = 0; i < platform_info->n_cmdlines; i++)
140 {
141 const cmdline_option_t *opt = &platform_info->cmdlines[i];
142 if (opt->arg)
143 pr_info2(" %-2d: %-10s = %s", i, opt->name, opt->arg);
144 else
145 pr_info2(" %-2d: %s", i, opt->name);
146 }
147 }
148
149 // power management
151
152 // register builtin filesystems
156
158
161 {
162 const auto ret = vfs_mount("none", "/", "tmpfs", NULL);
163 if (ret.isErr())
164 mos_panic("failed to mount rootfs, vfs_mount returns %ld", ret.getErr());
165 }
166 {
167 const auto ret = vfs_mkdir("/initrd");
168 if (ret.isErr())
169 mos_panic("failed to create /initrd, vfs_mkdir returns %ld", ret.getErr());
170 }
171 {
172 const auto ret = vfs_mount("none", "/initrd/", "cpiofs", NULL);
173 if (ret.isErr())
174 mos_panic("failed to mount initrd, vfs_mount returns %ld", ret.getErr());
175 }
176 ipc_init();
178
179 const auto init_con = platform_info->boot_console;
180 if (unlikely(!init_con))
181 mos_panic("failed to get console");
182
183 const stdio_t init_io = { .in = init_con, .out = init_con, .err = init_con };
184 const mos::vector<mos::string> init_envp = {
185 "PATH=/initrd/programs:/initrd/bin:/bin",
186 "HOME=/",
187 "TERM=linux",
188 };
189
190 mInfo << "running '" << init_args[0] << "' as init process.";
191 mInfo << " with arguments:";
192 for (u32 i = 0; i < init_args.size(); i++)
193 mInfo << fmt(" argv[{}] = {}", i, init_args[i].c_str());
194 mInfo << " with environment:";
195 for (u32 i = 0; i < init_envp.size(); i++)
196 mInfo << " " << init_envp[i].c_str();
197
198 const auto init = elf_create_process(init_args[0], NULL, init_args, init_envp, &init_io);
199 if (unlikely(!init))
200 mos_panic("failed to create init process");
201
202 const auto m = mm_map_user_pages(init->mm, MOS_INITRD_BASE, platform_info->initrd_pfn, platform_info->initrd_npages, VM_USER_RO, VMAP_TYPE_SHARED, VMAP_FILE, true);
203 pmm_ref(platform_info->initrd_pfn, platform_info->initrd_npages);
204 pmm_ref(platform_info->initrd_pfn, platform_info->initrd_npages);
205
206 MOS_ASSERT_X(m, "failed to map initrd into init process");
207
208 kthread_init(); // must be called after creating the first init process
210
212
213 mInfo << "\n";
216}
#define MOS_ASSERT_X(cond, msg,...)
Definition assert.hpp:12
#define MOS_UNREACHABLE()
Definition assert.hpp:10
#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
auto size() const noexcept
Definition vector.hpp:98
Process * elf_create_process(mos::string_view path, Process *parent, const mos::vector< mos::string > &argv, const mos::vector< mos::string > &envp, const stdio_t *ios)
Definition elf.cpp:384
MOSAPI char * strdup(const char *src)
@ VMAP_TYPE_SHARED
Definition mm.hpp:34
@ VMAP_FILE
Definition mm.hpp:26
void mm_map_kernel_pages(MMContext *mmctx, ptr_t vaddr, pfn_t pfn, size_t npages, VMFlags 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, VMFlags flags, vmap_type_t type, vmap_content_t content, bool exact=false)
Definition paging.cpp:92
#define pmm_ref(thing, npages)
Definition pmm.hpp:155
void pmm_init()
Definition pmm.cpp:20
PtrResult< void > 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:464
PtrResult< void > vfs_mkdir(const char *path)
Create a directory.
Definition vfs.cpp:679
void ipc_init(void)
Definition ipc.cpp:191
mos::vector< mos::string > init_args
Definition kmain.cpp:33
static sysfs_item_t kernel_sysfs_items[]
Definition kmain.cpp:52
static void setup_sane_environment()
Definition kmain.cpp:92
void mos_start_kernel(void)
Definition kmain.cpp:130
static bool init_sysfs_argv(sysfs_file_t *file)
Definition kmain.cpp:35
void kthread_init(void)
Definition kthread.cpp:30
mos::vector< mos::string > cmdline_parse_vector(char *inbuf, size_t length)
Definition cmdline.cpp:107
void string_unquote(char *str)
Definition cmdline.cpp:121
@ VM_GLOBAL
Definition mm_types.hpp:20
@ VM_READ
Definition mm_types.hpp:13
@ VM_EXEC
Definition mm_types.hpp:15
@ VM_WRITE
Definition mm_types.hpp:14
@ VM_USER_RO
Definition mm_types.hpp:28
#define ALIGN_UP_TO_PAGE(addr)
Definition mos_global.h:76
#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:129
const char __MOS_KERNEL_RW_START[]
const char __MOS_KERNEL_RODATA_END[]
Definition platform.hpp:130
#define MOS_KERNEL_PFN(vaddr)
Definition platform.hpp:121
MMContext mos_kernel_mm
Definition kmain.cpp:31
const char __MOS_KERNEL_CODE_START[]
const char __MOS_KERNEL_RW_END[]
Definition platform.hpp:131
#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_dinfo(feat, fmt,...)
Definition printk.hpp:28
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:49
void unblock_scheduler(void)
Unblock the scheduler, so that APs can start scheduling.
Definition schedule.cpp:59
void enter_scheduler(void)
Enter the scheduler and switch to the next thread.
Definition schedule.cpp:66
@ INIT_TARGET_PRE_VFS
Definition setup.hpp:11
@ INIT_TARGET_KTHREAD
Definition setup.hpp:14
@ INIT_TARGET_POWER
Definition setup.hpp:10
@ INIT_TARGET_VFS
Definition setup.hpp:12
@ INIT_TARGET_SYSFS
Definition setup.hpp:13
void startup_invoke_cmdline_hooks(void)
Definition setup.cpp:49
#define MOS_SETUP(_param, _fn)
Definition setup.hpp:34
void startup_invoke_autoinit(init_target_t target)
Definition setup.cpp:8
void slab_init()
initialise the slab allocator
Definition slab.cpp:112
const char * name
Definition cmdline.hpp:10
const char * arg
Definition cmdline.hpp:11
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:73
#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)
constexpr auto mInfo
Definition syslog.hpp:152
#define fmt(_fmt,...)
Definition syslog.hpp:161
unsigned int u32
Definition types.h:17
#define PFN_FMT
Definition types.h:38
unsigned long ptr_t
Definition types.h:21