From: acevest Date: Sun, 20 Oct 2024 11:39:18 +0000 (+0800) Subject: 支持以特权级3运行boot加载的简单的二进制程序 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/zlib_tech.html?a=commitdiff_plain;h=1370f7b7429770907c1c43b7e21064ba0e69de2f;p=kernel.git 支持以特权级3运行boot加载的简单的二进制程序 --- diff --git a/.gitignore b/.gitignore index 518d400..bd17c85 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,4 @@ bochsout.txt initrd initfs rootfs +**/init diff --git a/bin/Makefile b/bin/Makefile index 013ad00..9fce26c 100644 --- a/bin/Makefile +++ b/bin/Makefile @@ -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 index 0000000..e06a06b --- /dev/null +++ b/bin/init.S @@ -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 diff --git a/boot/boot.c b/boot/boot.c index dd1a0ef..78b4774 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -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; diff --git a/fs/file.c b/fs/file.c index 779a11d..e315c78 100644 --- 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; diff --git a/gdbscript b/gdbscript index fdab911..252fc3b 100644 --- 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 diff --git a/include/mm.h b/include/mm.h index 156d3cf..d16d93a 100644 --- a/include/mm.h +++ b/include/mm.h @@ -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; diff --git a/kernel/entry.S b/kernel/entry.S index 4c00895..3330359 100644 --- a/kernel/entry.S +++ b/kernel/entry.S @@ -68,5 +68,5 @@ ERRORCODE (InvalidTss) ERRORCODE (SegNotPresent) ERRORCODE (StackFault) ERRORCODE (GeneralProtection) -ERRORCODE (PageFault) +ERRORCODE (_page_fault) NOERRCODE (CoprocError) diff --git a/kernel/fork.c b/kernel/fork.c index 07046e6..81309af 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -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); diff --git a/kernel/innerint.c b/kernel/innerint.c index c8ad001..b92da0a 100644 --- a/kernel/innerint.c +++ b/kernel/innerint.c @@ -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 { diff --git a/kernel/system.c b/kernel/system.c index eab8ccb..8c35414 100644 --- a/kernel/system.c +++ b/kernel/system.c @@ -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++) { diff --git a/kernel/task_init.c b/kernel/task_init.c index 1bc234e..ba87691 100644 --- a/kernel/task_init.c +++ b/kernel/task_init.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -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 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 } diff --git a/kernel/task_root.c b/kernel/task_root.c index 7b4c1b0..cccf543 100644 --- a/kernel/task_root.c +++ b/kernel/task_root.c @@ -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;"); diff --git a/lib/syscall.c b/lib/syscall.c index ed67945..e16be0e 100644 --- a/lib/syscall.c +++ b/lib/syscall.c @@ -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); +} diff --git a/mkiso.sh b/mkiso.sh index d0fcbc8..9026e71 100755 --- 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]}" diff --git a/scripts/iso.grub.cfg b/scripts/iso.grub.cfg index 614e154..13c0b97 100644 --- a/scripts/iso.grub.cfg +++ b/scripts/iso.grub.cfg @@ -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 }