]> Zhao Yanbai Git Server - kernel.git/commitdiff
支持以特权级3运行boot加载的简单的二进制程序
authoracevest <zhaoyanbai@126.com>
Sun, 20 Oct 2024 11:39:18 +0000 (19:39 +0800)
committeracevest <zhaoyanbai@126.com>
Sun, 20 Oct 2024 11:39:24 +0000 (19:39 +0800)
16 files changed:
.gitignore
bin/Makefile
bin/init.S [new file with mode: 0644]
boot/boot.c
fs/file.c
gdbscript
include/mm.h
kernel/entry.S
kernel/fork.c
kernel/innerint.c
kernel/system.c
kernel/task_init.c
kernel/task_root.c
lib/syscall.c
mkiso.sh
scripts/iso.grub.cfg

index 518d400bd2554f48db3f3965b14fe27566716761..bd17c85f026a51f4a38779ba2d3522c129c0758a 100644 (file)
@@ -43,3 +43,4 @@ bochsout.txt
 initrd
 initfs
 rootfs
+**/init
index 013ad00ba71ef3a2db34eee2c3045007bb065cf2..9fce26c1b9d2b0db78caf2ee5c116d29f81d7e7a 100644 (file)
@@ -41,6 +41,12 @@ hello: hello.o
        $(CC) $(CFLAGS) hello.c -o hello.o
        $(LD)  -m elf_i386 $(LIBC_OBJS) hello.o -o hello
 
+init: init.o
+       $(CC) $(CFLAGS) init.S -o init.o
+       #$(LD)  -m elf_i386 $(LIBC_OBJS) hello.o -o hello
+       #$(LD)  -m elf_i386 init.o -o init
+       #$(LD)  -m elf_i386 -Ttext 0xc017f000 --oformat binary init.o -o init
+       $(LD)  -m elf_i386 -Ttext 0x0017f000 --oformat binary init.o -o init
 
 .PHONY:clean
 clean:
diff --git a/bin/init.S b/bin/init.S
new file mode 100644 (file)
index 0000000..e06a06b
--- /dev/null
@@ -0,0 +1,34 @@
+# 仅用来调试
+
+.global _start
+.section .text
+_start:
+    nop;
+    nop;
+    nop;
+    #leal 1f,%eax;
+    #pushl %eax
+    pushl $1f; # 这里push 1f和$1f意义不一样
+    pushl %ecx;
+    pushl %edx;
+    pushl %ebp;
+    nop;
+    nop;
+    movl %esp,%ebp;
+    nop;
+    movl $123,%ebx 
+    movl $5,%eax # SYSC_WAIT
+    sysenter;
+1:
+    nop;
+    nop;
+    nop;
+    movl $300000000, %ecx
+2:
+    nop
+    nop
+    nop
+    nop
+    nop
+    loop 2b
+    jmp _start
index dd1a0ef43f206085c71a568ce0f9b8f86950f7a4..78b4774c8e43696ee21198ea7391a861911b8c86 100644 (file)
@@ -116,7 +116,7 @@ void check_kernel(unsigned long addr, unsigned long magic) {
             printk("module 0x%08x - 0x%08x size %u cmdline %s\n", m->mod_start, m->mod_end, m->size, m->cmdline);
             boot_params.boot_module_begin = (void *)m->mod_start;
             boot_params.boot_module_end = (void *)m->mod_end;
-
+#if 0
             const uint32_t mod_magic = *(uint32_t *)(mod_start + 0);
             const uint32_t mod_head_size = *(uint32_t *)(mod_start + 4);
             const uint32_t mod_timestamp = *(uint32_t *)(mod_start + 8);
@@ -148,7 +148,9 @@ void check_kernel(unsigned long addr, unsigned long magic) {
                     printk("%02X ", c);
                 }
                 printk("\n");
+
             }
+#endif
             break;
         case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
             mminfo = (struct multiboot_tag_basic_meminfo *)tag;
index 779a11d15fb569bc1a8155d3030e3ca0ce11b4a3..e315c7868d1e7cd727934b63e7b3a89612dc0748 100644 (file)
--- a/fs/file.c
+++ b/fs/file.c
@@ -120,9 +120,7 @@ void vfs_page_cache_init() {
 
 ///
 #define MAX_FILES 1024
-static file_t g_files[MAX_FILES] = {
-    0,
-};
+file_t g_files[MAX_FILES];
 
 void init_file(file_t *fp) {
     fp->f_dentry = NULL;
index fdab9116840d30dbd408ca4bf30636f210e011cd..252fc3b73790f42e4c0fb2e937908f8e8218ba6d 100644 (file)
--- a/gdbscript
+++ b/gdbscript
@@ -34,6 +34,9 @@ set pagination off
 
 #b init_task_entry
 
+#b task_init.c:216
+#b *0xC017F000
+#b *0x0017F000
 c
 
 
index 156d3cf39a091da67d62ef804f2be61df2319e71..d16d93a1ef73253f274c596e3ca32134f93d2dfa 100644 (file)
@@ -21,3 +21,18 @@ unsigned long bootmem_page_state(unsigned long pfn);
 kmem_cache_t *kmem_cache_create(const char *name, size_t size, size_t align);
 void *kmem_cache_alloc(kmem_cache_t *cache, gfp_t gfpflags);
 void *kmem_cache_zalloc(kmem_cache_t *cache, gfp_t gfpflags);
+
+#define VM_READ 0x00000001
+#define VM_WRITE 0x00000002
+#define VM_EXEC 0x00000004
+#define VM_GROW_UP 0x10000000
+#define VM_GROW_DOWN 0x20000000
+
+typedef struct vm_area {
+    uint32_t vm_bgn;
+    uint32_t vm_end;
+
+    uint32_t vm_flags;
+
+    struct vma *vm_next;
+} vm_area_t;
index 4c0089503f0f2685c896be52a72fab1044550df0..333035926045c117e73dbeccbf0c6cffe66bc946 100644 (file)
@@ -68,5 +68,5 @@ ERRORCODE    (InvalidTss)
 ERRORCODE    (SegNotPresent)
 ERRORCODE    (StackFault)
 ERRORCODE    (GeneralProtection)
-ERRORCODE    (PageFault)
+ERRORCODE    (_page_fault)
 NOERRCODE    (CoprocError)
index 07046e6dc3cf6c261f259b751f2399a1bcef2e0e..81309af2c059021cb10e24ae5b779762517f2540 100644 (file)
@@ -65,7 +65,7 @@ int do_fork(pt_regs_t *regs, unsigned long flags) {
         pde_dst[i] = pde_src[i] & (~PDE_RW);
 #else
         // 这里不用再为每个PDE拷贝一次PageTable,只需要拷贝PageDirectory并将其低于768的写权限去掉
-        // 同时需要修改缺页异常doPageFault的逻辑
+        // 同时需要修改缺页异常do_page_fault的逻辑
         if (PAGE_ALIGN(spde) != 0) {
             dpde = page2va(alloc_one_page(0));
             assert(dpde != 0);
index c8ad001a5e07381001aee1e30167abd583ef9e58..b92da0ac5625a3d957996f181698fa82bbf4161f 100644 (file)
@@ -23,8 +23,7 @@
     do {                                                                                                 \
         printk("Unsupport Now...[%s]\n", __FUNCTION__);                                                  \
         printk("EFLAGS:%08x CS:%02x EIP:%08x ERRCODE:%x", regs.eflags, regs.cs, regs.eip, regs.errcode); \
-        while (1)                                                                                        \
-            ;                                                                                            \
+        while (1);                                                                                       \
     } while (0);
 
 void doDivideError(pt_regs_t regs) { DIE_MSG(); }
@@ -44,7 +43,7 @@ void doGeneralProtection(pt_regs_t regs) { DIE_MSG(); }
 
 void do_no_page(void *);
 void do_wp_page(void *);
-void doPageFault(pt_regs_t regs) {
+void do_page_fault(pt_regs_t regs) {
 #if 0
 US RW  P - Description
 0  0  0 - Supervisory process tried to read a non-present page entry
@@ -55,6 +54,11 @@ US RW  P - Description
 1  0  1 - User process tried to read a page and caused a protection fault
 1  1  0 - User process tried to write to a non-present page entry
 1  1  1 - User process tried to write a page and caused a protection fault
+#endif
+#if 0
+    bit 0: 0 non-present page entry; 1 protection fault
+    bit 1: 0 read; 1 write
+    bit 2: 0 supervisor mode; 1 user mode
 #endif
     // DIE_MSG();
     void *addr;
@@ -66,6 +70,7 @@ US RW  P - Description
 
     // assert(errcode != 2 && errcode != 6);
 
+    printk("errcode %x addr %x\n", errcode, addr);
     if ((errcode & PAGE_P) == 0) {
         do_no_page(addr);
     } else {
index eab8ccb9006716415468f0c78ff8ac960c3bd7d9..8c354143d480a0bf9efebbd409aecd1b525c113d 100644 (file)
@@ -82,7 +82,7 @@ void setup_gates() {
     set_sys_int(0x0B, TRAP_GATE, PRIVILEGE_KRNL, SegNotPresent);
     set_sys_int(0x0C, TRAP_GATE, PRIVILEGE_KRNL, StackFault);
     set_sys_int(0x0D, TRAP_GATE, PRIVILEGE_KRNL, GeneralProtection);
-    set_sys_int(0x0E, TRAP_GATE, PRIVILEGE_KRNL, PageFault);
+    set_sys_int(0x0E, TRAP_GATE, PRIVILEGE_KRNL, _page_fault);
     set_sys_int(0x10, TRAP_GATE, PRIVILEGE_KRNL, CoprocError);
 
     for (int i = 0x11; i < 0x20; i++) {
index 1bc234ec58fa9ec31df9d0aaa54e4a95d0931398..ba87691a955fe259e545fdb75cf3d308f789ae64 100644 (file)
@@ -1,3 +1,4 @@
+#include <boot.h>
 #include <disk.h>
 #include <fcntl.h>
 #include <io.h>
@@ -199,13 +200,61 @@ void init_task_entry() {
     kernel_task("tskC", taskC_entry, NULL);
 #endif
 
+#if 1
+    void *mod_start = pa2va(boot_params.boot_module_begin);
+
+    mod_start = (void *)va2pa(mod_start);
+
+    unsigned long text_at = (unsigned long)mod_start;
+    text_at &= 0xFFFFF000;
+
+    int pgd_index = (text_at >> 22) & 0x3FF;
+    int pt_index = (text_at >> 12) & 0x3FF;
+
+    unsigned long *pgd = (unsigned long *)(pa2va(current->cr3));
+
+    unsigned long *pt_page = (unsigned long *)page2va(alloc_one_page(0));
+    memset(pt_page, 0, PAGE_SIZE);
+
+    pgd[pgd_index] = va2pa(pt_page) | PAGE_P | PAGE_WR | PAGE_US;
+
+    pt_page[pt_index] = text_at | PAGE_P | PAGE_WR | PAGE_US;
+
+    printk("RING3 ENTRY %x page %x pgd inx %u pt inx %u\n", mod_start, text_at, pgd_index, pt_index);
+
+    LoadCR3(current->cr3);
+
+    asm("sysexit;" ::"d"(mod_start), "c"(mod_start + PAGE_SIZE - 4));
+#else
+    void *mod_start = pa2va(boot_params.boot_module_begin);
+    printk("RING3 ENTRY %x\n", mod_start);
+
+    unsigned long text_at = mod_start;
+    int pgd_index = (text_at >> 22) & 0x3FF;
+    int pt_index = (text_at >> 12) & 0x3FF;
+    unsigned long *pgd = (unsigned long *)(pa2va(current->cr3));
+    pgd[pgd_index] = pgd[pgd_index] | PAGE_WR | PAGE_US;
+
+    unsigned long pgde = pgd[pgd_index];
+    pgde &= 0xFFFFF000;
+
+    unsigned long *pt = (unsigned long *)pa2va(pgde);
+    pt[pt_index] = pt[pt_index] | PAGE_WR | PAGE_US;
+
+    asm("sysexit;" ::"d"(mod_start), "c"(mod_start + PAGE_SIZE - 4));
+#endif
+
     while (1) {
+        asm("nop;");
+        asm("nop;");
+        asm("nop;");
+        asm("nop;");
         sysc_wait(1);
     }
 }
 
-#include <boot.h>
 void init_rootfs() {
+#if 0
     void *mod_start = pa2va(boot_params.boot_module_begin);
 
     const uint32_t mod_magic = *(uint32_t *)(mod_start + 0);
@@ -280,4 +329,5 @@ void init_rootfs() {
             printk("\n");
         }
     }
+#endif
 }
index 7b4c1b057ba3678846c4990ade92f8319d58d986..cccf543e66a4800d835dda833693dedbaa314545 100644 (file)
@@ -78,6 +78,8 @@ void root_task_entry() {
 
     kernel_task("init", init_task_entry, NULL);
 
+    strcpy(current->name, "idle");
+
     current->priority = 1;
     while (1) {
         asm("hlt;");
index ed679459bf93bff43693b79633d7686b1d7f9573..e16be0e3f36ca3beff66e37a54b8b52e4cdab19c 100644 (file)
@@ -56,4 +56,6 @@ int _syscall2(int nr, unsigned long a, unsigned long b) { return __syscall2(nr,
 
 int _syscall3(int nr, unsigned long a, unsigned long b, unsigned long c) { return __syscall3(nr, a, b, c); }
 
-int _syscall4(int nr, unsigned long a, unsigned long b, unsigned long c, unsigned long d) { return __syscall4(nr, a, b, c, d); }
+int _syscall4(int nr, unsigned long a, unsigned long b, unsigned long c, unsigned long d) {
+    return __syscall4(nr, a, b, c, d);
+}
index d0fcbc80cf0463b040789551ded54d1b262ddab4..9026e71685dc73b571d8808b36c87c42efead7ba 100755 (executable)
--- a/mkiso.sh
+++ b/mkiso.sh
@@ -46,7 +46,7 @@ docker exec -it $CONTAINER_ID mkdir -p $grub2_boot_dir/grub/
 files[0]="KERNEL.ELF:$grub2_boot_dir/Kernel"
 files[1]="scripts/iso.grub.cfg:$grub2_boot_dir/grub/grub.cfg"
 files[2]="rootfs:$grub2_boot_dir/rootfs"
-
+files[3]="bin/init:$grub2_boot_dir/init"
 
 for i in "${!files[@]}"; do
     file_line="${files[$i]}"
index 614e154b0aab1c0e71facf8ab0f51443a8adbfaf..13c0b97bfa7ea8816f30e3783f5d47ac3f9ce740 100644 (file)
@@ -11,6 +11,7 @@ menuentry 'Kernel' --class os {
     #set gfxpayload=1024x768x32
     #insmod all_video
     multiboot2 /boot/Kernel root=hda7 delay=2
-    module2 /boot/rootfs rootfs
+    #module2 /boot/rootfs rootfs
+    module2 /boot/init init
     boot
 }