dedicated kthread interface and enablement of lrud auto-recycler
[lunaix-os.git] / lunaix-os / kernel / lunad.c
1 #include <lunaix/boot_generic.h>
2 #include <lunaix/exec.h>
3 #include <lunaix/foptions.h>
4 #include <lunaix/fs.h>
5 #include <lunaix/fs/twifs.h>
6 #include <lunaix/spike.h>
7 #include <lunaix/syslog.h>
8 #include <lunaix/types.h>
9 #include <lunaix/owloysius.h>
10 #include <lunaix/sched.h>
11 #include <lunaix/kpreempt.h>
12 #include <lunaix/kcmd.h>
13 #include <lunaix/kthread.h>
14
15 #include <klibc/string.h>
16
17 LOG_MODULE("PROC0")
18
19 void
20 init_platform();
21
22 int
23 mount_bootmedium()
24 {
25     int errno = 0;
26     char* rootfs;
27     struct v_dnode* dn;
28     struct device* dev;
29
30     if (!kcmd_get_option("rootfs", &rootfs)) {
31         ERROR("no rootfs.");
32         return 0;
33     }
34
35     if ((errno = vfs_walk(NULL, rootfs, &dn, NULL, 0))) {
36         ERROR("%s: no such file (%d)", rootfs, errno);
37         return 0;
38     }
39     
40     dev = resolve_device(dn->inode->data);
41     if (!dev) {
42         ERROR("%s: not a device", rootfs);
43         return 0;
44     }
45
46     // unmount the /dev to put old root fs in clear
47     must_success(vfs_unmount("/dev"));
48
49     // re-mount the root fs with our device.
50     if ((errno = vfs_mount_root(NULL, dev))) {
51         ERROR("mount root failed: %s (%d)", rootfs, errno);
52         return 0;
53     }
54
55     return 1;
56 }
57
58 int
59 exec_initd()
60 {
61     int errno = 0;
62     const char* argv[] = { "/init", 0 };
63     const char* envp[] = { 0 };
64
65     kcmd_get_option("init", (char**)&argv[0]);
66
67     if ((errno = exec_kexecve(argv[0], argv, envp))) {
68         goto fail;
69     }
70
71     fail("should not reach");
72
73 fail:
74     ERROR("fail to load initd. (%d)", errno);
75     return 0;
76 }
77
78 static void
79 lunad_do_usr() {
80     // No, these are not preemptive
81     no_preemption();
82
83     if (!exec_initd()) {
84         fail("failed to initd");
85     }
86 }
87
88 static void
89 __thread_cleaner()
90 {
91     while (true)
92     {
93         cleanup_detached_threads();
94         kthread_sleep(30);
95     }
96 }
97
98
99 /**
100  * @brief LunaixOS的内核进程,该进程永远为可执行。
101  *
102  * 这主要是为了保证调度器在没有进程可调度时依然有事可做。
103  *
104  * 同时,该进程也负责fork出我们的init进程。
105  *
106  */
107 void
108 lunad_main()
109 {
110     kthread_spawn((ptr_t)init_platform);
111     kthread_spawn((ptr_t)__thread_cleaner);
112
113     while (1)
114     {
115         yield_current();
116     }
117 }
118
119 void
120 init_platform()
121 {    
122     device_postboot_load();
123     invoke_init_function(on_postboot);
124
125     twifs_register_plugins();
126
127     if (!mount_bootmedium()) {
128         ERROR("failed to boot");
129         goto exit;
130     }
131
132     // FIXME Re-design needed!!
133     // sdbg_init();
134     
135     assert(!spawn_process(NULL, (ptr_t)lunad_do_usr, true));
136
137 exit:
138     exit_thread(NULL);
139 }