Browse Source

feat(init): execute init script using busybox sh

greatbridf 1 year ago
parent
commit
4ac28ae9a7
5 changed files with 63 additions and 37 deletions
  1. 12 21
      include/kernel/process.hpp
  2. 0 3
      src/kernel/interrupt.cpp
  3. 38 10
      src/kernel/process.cpp
  4. 1 1
      src/kernel/syscall.cpp
  5. 12 2
      src/kernel/vfs.cpp

+ 12 - 21
include/kernel/process.hpp

@@ -276,34 +276,25 @@ public:
     void send_signal(kernel::signal_list::signo_type signal);
 };
 
-class proclist final {
-public:
-    using list_type = std::map<pid_t, process>;
-    using iterator = list_type::iterator;
-    using const_iterator = list_type::const_iterator;
+namespace kernel::kinit {
+
+// in process.cpp
+void create_kthreadd_process();
+
+} // namespace kernel::kinit
 
+class proclist final {
 private:
-    list_type m_procs;
+    std::map<pid_t, process> m_procs;
     pid_t m_nextpid = 1;
 
     constexpr pid_t next_pid() { return m_nextpid++; }
+    process& real_emplace(pid_t pid, pid_t ppid);
 
-public:
-    process& emplace(pid_t ppid)
-    {
-        pid_t pid = next_pid();
-        auto [ iter, inserted ] = m_procs.try_emplace(pid, pid, ppid);
-        assert(inserted);
-
-        if (try_find(ppid)) {
-            bool success = false;
-            std::tie(std::ignore, success) =
-                find(ppid).children.insert(pid);
-            assert(success);
-        }
+    friend void kernel::kinit::create_kthreadd_process();
 
-        return iter->second;
-    }
+public:
+    process& emplace(pid_t ppid);
 
     process& copy_from(process& proc)
     {

+ 0 - 3
src/kernel/interrupt.cpp

@@ -218,9 +218,6 @@ static inline void _int14_panic(void* eip, void* cr2, struct page_fault_error_co
 
 static inline void NORETURN _int14_kill_user(void)
 {
-    char buf[256] {};
-    snprintf(buf, 256, "Segmentation Fault (pid%d killed)\n", current_process->pid);
-    kmsg(buf);
     kill_current(SIGSEGV);
 }
 

+ 38 - 10
src/kernel/process.cpp

@@ -311,6 +311,26 @@ int thread::load_thread_area() const
     return 0;
 }
 
+process& proclist::real_emplace(pid_t pid, pid_t ppid)
+{
+    auto [ iter, inserted ] = m_procs.try_emplace(pid, pid, ppid);
+    assert(inserted);
+
+    if (ppid && try_find(ppid)) {
+        bool success = false;
+        std::tie(std::ignore, success) =
+            find(ppid).children.insert(pid);
+        assert(success);
+    }
+
+    return iter->second;
+}
+
+process& proclist::emplace(pid_t ppid)
+{
+    return real_emplace(next_pid(), ppid);
+}
+
 void proclist::kill(pid_t pid, int exit_code)
 {
     auto& proc = this->find(pid);
@@ -384,10 +404,13 @@ void kernel_threadd_main(void)
             void (*func)(void*) = nullptr;
             void* data = nullptr;
 
-            {
+            if (1) {
                 types::lock_guard lck(kthreadd_mtx);
-                func = std::exchange(kthreadd_new_thd_func, nullptr);
-                data = std::exchange(kthreadd_new_thd_data, nullptr);
+
+                if (kthreadd_new_thd_func) {
+                    func = std::exchange(kthreadd_new_thd_func, nullptr);
+                    data = std::exchange(kthreadd_new_thd_data, nullptr);
+                }
             }
 
             // TODO
@@ -429,11 +452,14 @@ static void release_kinit()
     }
 }
 
-static void create_kthreadd_process()
+namespace kernel::kinit {
+
+SECTION(".text.kinit")
+void create_kthreadd_process()
 {
     // pid 2 is kernel thread daemon
-    auto& proc = procs->emplace(1);
-    assert(proc.pid == 2);
+    auto& proc = procs->real_emplace(0, 0);
+    assert(proc.pid == 0);
 
     // create thread
     auto [ iter_thd, inserted] =
@@ -462,9 +488,11 @@ static void create_kthreadd_process()
     readythds->push(&thd);
 }
 
+} // namespace kernel::kinit
+
 void NORETURN _kernel_init(void)
 {
-    create_kthreadd_process();
+    kernel::kinit::create_kthreadd_process();
 
     release_kinit();
 
@@ -502,15 +530,15 @@ void NORETURN _kernel_init(void)
     current_process->attr.system = 0;
     current_thread->attr.system = 0;
 
-    const char* argv[] = { "/mnt/init", "/mnt/sh", nullptr };
-    const char* envp[] = { "LANG=C", "HOME=/", nullptr };
+    const char* argv[] = { "/mnt/busybox", "sh", "/init" };
+    const char* envp[] = { "LANG=C", "HOME=/", "PATH=/mnt", "PWD=/", nullptr };
 
     types::elf::elf32_load_data d;
     d.argv = argv;
     d.envp = envp;
     d.system = false;
 
-    d.exec_dent = fs::vfs_open(*fs::fs_root, "/mnt/init");
+    d.exec_dent = fs::vfs_open(*fs::fs_root, argv[0]);
     if (!d.exec_dent) {
         console->print("kernel panic: init not found!\n");
         freeze();

+ 1 - 1
src/kernel/syscall.cpp

@@ -203,7 +203,7 @@ int NORETURN _syscall_exit(interrupt_stack* data)
         assert(false);
 
     // terminating a whole process:
-    procs->kill(current_process->pid, exit_code & 0xff);
+    procs->kill(current_process->pid, (exit_code & 0xff) << 8);
 
     // switch to new process and continue
     schedule_noreturn();

+ 12 - 2
src/kernel/vfs.cpp

@@ -946,13 +946,23 @@ void init_vfs(void)
     fs_root = rootfs->root();
 
     vfs_mkdir(fs_root, "dev", 0755);
-    vfs_mkdir(fs_root, "root", 0755);
     vfs_mkdir(fs_root, "mnt", 0755);
     vfs_mkfile(fs_root, "init", 0755);
 
     auto* init = vfs_open(*fs_root, "/init");
     assert(init);
-    const char* str = "#/bin/sh\nexec /bin/sh\n";
+    const char* str = "#!/mnt/busybox sh\n"
+                      "cd /\n"
+                      "busybox mkdir etc\n"
+                      "busybox mkdir root\n"
+                      "busybox cat > /etc/passwd <<EOF\n"
+                      "root:x:0:0:root:/root:/mnt/busybox_ sh\n"
+                      "EOF\n"
+                      "busybox cat > /etc/group <<EOF\n"
+                      "root:x:0:root\n"
+                      "EOF\n"
+                      "exec /mnt/init /mnt/busybox_ sh < /dev/console"
+                      "    >> /dev/console 2>>/dev/console\n";
     vfs_write(init->ind, str, 0, strlen(str));
 
     auto* dev = vfs_open(*fs_root, "/dev");