cp bin/hello /kernel/bin/
cp bin/shell /kernel/bin/
cp:
+ cd bin && make
./scripts/copy.sh
int systest();
int main()
{
+ char x[10];
+ x[0] = 'a';
+ x[1] = 'b';
+ x[2] = 'c';
+ x[3] = '\n';
+#if 1
+ //while(1) write(0, x, 4);
+ //while(1) systest();
+ int pid = fork();
-
- while(1)
+ if(pid > 0)
{
- char buf[256];
- read(0, buf, 256);
- write(0, buf, 256);
-#if 0
- asm("movl $11, %eax;" \
- "pushl $1f;" \
- "pushl %ecx;" \
- "pushl %edx;" \
- "pushl %ebp;" \
- "movl %esp,%ebp;" \
- "sysenter;" \
- "1:");
+ //write(0, "parent\n", 7);
+ //write(0, x, 4);
+ while(1)
+ ; systest();
+ }
+ else if(pid == 0)
#endif
- systest();
- asm("nop;nop;nop;");
+ {
+ //write(0, "child\n", 6);
+ //write(0, x, 4);
+ while(1)
+ {
+ systest();
+ }
}
return 0;
void vga_puts(unsigned int nr, const char *buf, unsigned char color)
{
+ assert(buf != 0);
if(nr >= VGA_MAX_SCREEN_CNT)
return ;
static ext2_inode_t boot_inode;
static ext2_inode_t krnl_inode;
+unsigned long ext2_block_size()
+{
+ return (EXT2_MIN_BLOCK_SIZE << (EXT2_SB)->s_log_block_size);
+}
+
void *ext2_alloc_block()
{
return (void *) kmem_cache_alloc(ext2_block_cache, 0);
for(i=0; i<blkcnt; ++i)
{
BLKRW(inode->i_block[i], 1, buf+i*EXT2_BLOCK_SIZE);
- printk("read block\n");
+ printd("read block\n");
}
unsigned int left = inode->i_size % EXT2_BLOCK_SIZE;
if(left)
{
- printk("read left %u bytes\n", left);
+ printd("read left %u bytes\n", left);
void *blk = ext2_alloc_block();
ext2_free_block(blk);
}
- printk("read file done\n");
+ printd("read file done\n");
+}
+
+void ext2_read_data(const ext2_inode_t *inode, unsigned int offset, size_t size, char *buf)
+{
+ assert(inode != 0);
+ assert(buf != 0);
+ assert(inode->i_size > 0 && inode->i_size<=MAX_SUPT_FILE_SIZE);
+ assert(offset+size <= inode->i_size);
+ assert(offset % EXT2_BLOCK_SIZE == 0); // for easy
+ printk("offset %x size %x %x\n", offset, size, offset+size);
+ assert((offset+size) % EXT2_BLOCK_SIZE == 0);
+
+ unsigned int blkid = offset / EXT2_BLOCK_SIZE;
+ unsigned int blkcnt = size / EXT2_BLOCK_SIZE;
+ printk("id %u cnt %u\n", blkid, blkcnt);
+ BLKRW(inode->i_block[blkid], blkcnt, buf);
}
+
unsigned int ext2_search_indir(const char *name, const ext2_inode_t *inode)
{
unsigned int ino = 0;
*--------------------------------------------------------------------------
*/
+#include<assert.h>
extern void vga_puts(unsigned int nr, const char *buf, unsigned char color);
int sysc_write(int fd, const char *buf, unsigned long size)
#define EXT2_SB (&ext2_fs.ext2_sb)
#define EXT2_GD (ext2_fs.ext2_gd)
-#define EXT2_BLOCK_SIZE (EXT2_MIN_BLOCK_SIZE << (EXT2_SB)->s_log_block_size)
+
+unsigned long ext2_block_size();
+#define EXT2_BLOCK_SIZE ext2_block_size()
+//#define EXT2_BLOCK_SIZE (EXT2_MIN_BLOCK_SIZE << (EXT2_SB)->s_log_block_size)
#define EXT2_SECT_PER_BLOCK (EXT2_BLOCK_SIZE/512)
void ext2_read_inode(unsigned int ino, ext2_inode_t *inode);
void ext2_read_file(const ext2_inode_t *inode, char *buf);
+void ext2_read_data(const ext2_inode_t *inode, unsigned int offset, size_t size, char *buf);
#endif //_EXT2_H
#define BOOTMEM_PAGE_USED 1
void *alloc_bootmem(unsigned long size, unsigned long align);
-unsigned long bootmem_total_pages();
+unsigned long bootmem_max_pfn();
unsigned long bootmem_page_state(unsigned long pfn);
#define bootmem_alloc_pages(n) alloc_bootmem((n)*PAGE_SIZE, PAGE_SIZE)
#define PTECNT_PER_PAGE (PAGE_SIZE/sizeof(pte_t))
#define PAGE_ITEMS (PAGE_SIZE/sizeof(unsigned long))
-#define PAGE_ALIGN(page) (page & PAGE_MASK)
+#define PAGE_ALIGN(page) (((unsigned long)(page)) & PAGE_MASK)
#define PAGE_UP(page) (((unsigned long)page + PAGE_SIZE -1) & PAGE_MASK)
#define PAGE_DOWN PAGE_ALIGN
int _syscall2(int nr, unsigned long a, unsigned long b);
int _syscall3(int nr, unsigned long a, unsigned long b, unsigned long c);
int _syscall4(int nr, unsigned long a, unsigned long b, unsigned long c, unsigned long d);
-int _syscall5(int nr, unsigned long a, unsigned long b, unsigned long c, unsigned long d, unsigned long e);
#define syscall0(nr) _syscall0(nr)
#define syscall1(nr, a) _syscall1(nr, (unsigned long)a)
#define syscall2(nr, a, b) _syscall2(nr, (unsigned long)a, (unsigned long)b)
#define syscall3(nr, a, b, c) _syscall3(nr, (unsigned long)a, (unsigned long)b, (unsigned long)c)
#define syscall4(nr, a, b, c, d) _syscall4(nr, (unsigned long)a, (unsigned long)b, (unsigned long)c, (unsigned long)d)
-#define syscall5(nr, a, b, c, d, e) _syscall5(nr, (unsigned long)a, (unsigned long)b, (unsigned long)c, (unsigned long)d, (unsigned long)e)
enum
{
#include <assert.h>
#define KRNLADDR PAGE_OFFSET
-#define PT_REGS_EDI 0
-#define PT_REGS_ESI 4
-#define PT_REGS_EBP 8
-#define PT_REGS_EBX 12
-#define PT_REGS_EDX 16
-#define PT_REGS_ECX 20
+#define PT_REGS_EBX 0
+#define PT_REGS_ECX 4
+#define PT_REGS_EDX 8
+#define PT_REGS_ESI 12
+#define PT_REGS_EDI 16
+#define PT_REGS_EBP 20
#define PT_REGS_EAX 24
#define PT_REGS_DS 28
#define PT_REGS_ES 32
INDEX_EMP8,
INDEX_TSS,
};
+#if 0
// pushal push eax, ecx, edx, ebx, esp, ebp, esi, edi
typedef struct pt_regs
{
u32 esp;
u16 ss, _ss;
} __attribute__((packed)) pt_regs_t;
+#else
+typedef struct pt_regs
+{
+ u32 ebx;
+ u32 ecx;
+ u32 edx;
+ u32 esi;
+ u32 edi;
+ u32 ebp;
+ u32 eax;
+ u16 ds, _ds;
+ u16 es, _es;
+ u16 fs, _fs;
+ u16 gs, _gs;
+ union
+ {
+ u32 irq;
+ u32 errcode;
+ };
+ u32 eip;
+ u16 cs, _cs;
+ u32 eflags;
+ u32 esp;
+ u16 ss, _ss;
+} __attribute__((packed)) pt_regs_t;
+#endif
typedef unsigned long dev_t;
typedef struct system
{
u32 mmap_addr;
- u32 mmap_size; // Byte
+ u32 mmap_size; // Byte
- u32 mm_lower; // KB
- u32 mm_upper; // KB
+ u32 mm_lower; // KB
+ u32 mm_upper; // KB
u64 mm_size; // Byte
u32 page_count;
pushl %es; \
pushl %ds; \
pushl %eax; \
- pushl %ecx; \
- pushl %edx; \
- pushl %ebx; \
pushl %ebp; \
pushl %esi; \
- pushl %edi;
+ pushl %edi; \
+ pushl %edx; \
+ pushl %ecx; \
+ pushl %ebx;
#define RESTORE_REGS \
+ popl %ebx; \
+ popl %ecx; \
+ popl %edx; \
popl %edi; \
popl %esi; \
popl %ebp; \
- popl %ebx; \
- popl %edx; \
- popl %ecx; \
popl %eax; \
popl %ds; \
popl %es; \
#include <elf.h>
#include <fs.h>
#include <ext2.h>
+#include <page.h>
extern void *syscall_exit;
+void put_paging(unsigned long vaddr, unsigned long paddr, unsigned long flags)
+{
+ assert(PAGE_ALIGN(vaddr) == vaddr);
+ assert(PAGE_ALIGN(paddr) == paddr);
+
+ unsigned int npde = get_npd(vaddr);
+ unsigned int npte = get_npt(vaddr);
+
+ pde_t *page_dir = (pde_t *) current->cr3;
+ pte_t *page_table = (pte_t *) PAGE_ALIGN(page_dir[npde]);
+
+ if(page_table == 0)
+ {
+ page_table = (pte_t *) va2pa(alloc_one_page(0));
+ assert(page_table != 0);
+ }
+
+
+ page_dir[npde] = (unsigned long) page_table | flags;
+ page_table = pa2va(page_table);
+ page_table[npte] = paddr | flags;
+}
+
int sysc_exec(const char *path, char *const argv[])
{
assert(argv == NULL); // unsupport now
ext2_read_inode(ino, &inode);
- //void *buf = (void*)kmalloc(inode.i_size, 0);
- void *buf = (void *) alloc_pages(0, 5);
- assert(buf != 0);
+ Elf32_Ehdr *ehdr= (Elf32_Ehdr *)alloc_one_page(0);
+ assert(ehdr != 0);
+ ext2_read_data(&inode, 0, PAGE_SIZE, (char *)ehdr);
+ printk("%08x\n", *((unsigned long *)ehdr->e_ident));
+ assert(strncmp(ELFMAG, ehdr->e_ident, sizeof(ELFMAG)-1) == 0);
+ printk("Elf Entry: %08x\n", ehdr->e_entry);
- printk("exec buf %08x \n", buf);
- printd("begin read elf\n");
- ext2_read_file(&inode, buf);
- printd("end read elf\n");
- pElf32_Ehdr ehdr = (pElf32_Ehdr) buf;
- //assert(strncmp(ELFMAG, ehdr->e_ident, sizeof(ELFMAG)-1) == 0);
- if(strncmp(ELFMAG, ehdr->e_ident, sizeof(ELFMAG)-1) != 0)
+ int i, j;
+ for(i=0; i<ehdr->e_phnum; ++i)
{
- printk("file %s can not execute\n", path);
- kfree(buf);
- return -ENOEXEC;
- }
- //printk("Entry: %08x phnum:%d\n", ehdr->e_entry, ehdr->e_phnum);
-
- int size = 0;
- int i;
- for(i=0; i<ehdr->e_phnum; i++)
- {
- pElf32_Phdr phdr;
- phdr = (pElf32_Phdr)(buf+ehdr->e_phoff+(i*ehdr->e_phentsize));
+ Elf32_Phdr *phdr;
+ phdr = (Elf32_Phdr*)(((unsigned long)ehdr) + ehdr->e_phoff + (i*ehdr->e_phentsize));
printk("Type %08x Off %08x Va %08x Pa %08x Fsz %08x Mmsz %08x\n",
- phdr->p_type, phdr->p_offset, phdr->p_vaddr, phdr->p_paddr,
- phdr->p_filesz, phdr->p_memsz);
+ phdr->p_type, phdr->p_offset, phdr->p_vaddr, phdr->p_paddr,
+ phdr->p_filesz, phdr->p_memsz);
- if(phdr->p_type == PT_LOAD)
- {
- if(phdr->p_offset > 0 && phdr->p_memsz > 0)
- {
- size = ALIGN(phdr->p_offset + phdr->p_memsz, 0x1000);
- }
- }
- }
- printk("ELF MEM SIZE %u\n", size);
+ unsigned long vaddr = phdr->p_vaddr;
+ unsigned long offset= phdr->p_offset;
+ unsigned long mmsz = phdr->p_memsz;
+ unsigned long filesz= phdr->p_filesz;
- char *exe = (char *) kmalloc(size, 0);
- assert(exe != 0);
- printk("EXE ADDR %08x\n", exe);
- for(i=0; i<ehdr->e_phnum; i++)
- {
- pElf32_Phdr phdr;
- phdr = (pElf32_Phdr)(buf+ehdr->e_phoff+(i*ehdr->e_phentsize));
if(phdr->p_type != PT_LOAD)
continue;
- if(phdr->p_filesz != 0)
+
+ assert(mmsz >= filesz);
+
+ unsigned int pgcnt = (mmsz + PAGE_SIZE - 1) / PAGE_SIZE;
+ unsigned int blkcnt= (filesz + EXT2_BLOCK_SIZE - 1) / EXT2_BLOCK_SIZE;
+
+ void *buf = kmalloc(pgcnt*PAGE_SIZE, PAGE_SIZE);
+ assert(PAGE_ALIGN(buf) == (unsigned long)buf);
+ assert(buf != 0);
+
+
+ printk("vvvbufsz %08x datasz %08x\n", pgcnt*PAGE_SIZE, blkcnt*EXT2_BLOCK_SIZE);
+
+ if(filesz > 0)
+ ext2_read_data(&inode, offset, blkcnt*EXT2_BLOCK_SIZE, buf);
+
+ for(j=0; j<pgcnt; ++j)
{
- memcpy((void*)(exe+phdr->p_offset), (void*)(buf+phdr->p_offset), phdr->p_filesz);
+ put_paging(vaddr + j*PAGE_SIZE, (unsigned long) (va2pa(buf)) + j*PAGE_SIZE, 7);
}
}
-
- /*
- * 因为目前文件支持最大为12*EXT2_BLOCK_SIZE
- * 即12K~48K之间
- * 所以就以一个页目录项来简化处理
- */
- u32 *pd = (u32*) current->cr3;
- u32 *pt;
- u32 pa_exe;
- u32 npd, npt;
- int c;
- pa_exe = va2pa(exe);
- npd = get_npd(ehdr->e_entry);
- npt = get_npt(ehdr->e_entry);
- pt = (u32*)va2pa(alloc_one_page(0));
- if(pt == NULL)
- panic("out of memory");
-
- //printk("npd: %d pt:%08x\n", npd, pt);
- memset(pa2va(pt), 0, PAGE_SIZE);
- pd[npd] = (u32) pt | 7;
- pt = pa2va(pt);
- for(i=npt, c=0; i<1024; i++, c++)
- {
- pt[i] = va2pa(PAGE_ALIGN((unsigned long)exe)) + c * PAGE_SIZE;
- pt[i] |= 7;
- }
-
load_cr3(current);
- printk("exe : %08x cr3:%08x\n", exe, pd);
+
+ disable_irq();
pt_regs_t *regs = ((pt_regs_t *)(TASK_SIZE+(unsigned long)current)) - 1;
memset((void*)regs, 0, sizeof(pt_regs_t));
regs->edx = regs->eip;
regs->ecx = (0xC0000000 - 16);
- kfree(buf);
+ //kfree(buf);
+
+ free_pages((unsigned long)ehdr);
asm("movl $0, %%eax; movl %%ebx,%%ebp; movl %%ebp,%%esp;jmp syscall_exit;"::"b"((unsigned long)(regs)));
*/
#include <sched.h>
+#include <page.h>
int sysc_fork(pt_regs_t regs)
{
int do_fork(pt_regs_t *regs, unsigned long flags)
{
+ static int forkcnt = 7;
task_union *tsk;
tsk = alloc_task_union();
printk("fork task %08x flags %08x\n", tsk, flags);
memcpy(tsk, current, sizeof(task_union));
- {
+ //{
tsk->cr3 = (unsigned long) alloc_one_page(0);
if(tsk->cr3 == 0)
panic("failed init tsk cr3");
continue;
}
- if(spde != 0)
- dpde = PAGE_FLAGS(spde) | (unsigned long) va2pa(alloc_one_page(0));
+ if(pde_src[i] == 0)
+ continue;
+
+ if(PAGE_ALIGN(spde) != 0)
+ {
+ dpde = alloc_one_page(0);
+ assert(dpde != 0);
+ memset((void*)dpde, 0, PAGE_SIZE);
+ dpde = PAGE_FLAGS(spde) | (unsigned long) va2pa(dpde);
+ }
+ else
+ {
+ pde_dst[i] = 0;
+ continue;
+ }
pde_dst[i] = dpde;
pte_t *pte_src = pa2va(PAGE_ALIGN(spde));
pte_t *pte_dst = pa2va(PAGE_ALIGN(dpde));
for(j=0; j< PAGE_PTE_CNT; ++j)
{
+
+ //printl(20, "[%d %d]", i, j);
pte_src[j] &= ~PAGE_WR;
pte_dst[j] = pte_src[j];
page_t *page = pa2page(pte_src[j]);
page->count ++;
}
+
}
- }
+ //}
tsk->pid = get_next_pid();
tsk->ppid = current->pid;
child_regs->eax = 0;
child_regs->eflags |= 0x200; //enable IF
-
tsk->esp0 = TASK_SIZE + (unsigned long) tsk;
tsk->esp = (unsigned long) child_regs;
tsk->eip = (unsigned long) ret_from_fork_user;
list_add(&tsk->list, &root_task.list);
irq_restore(iflags);
+
+ printk("%s:%d\n", __func__, __LINE__);
return (int)tsk->pid;
}
//printd("do page fault errcode %x addr %08x\n", errcode, addr);
- if(errcode & PAGE_US)
+ if(errcode == 0 || errcode == 2)
{
- //panic("user program try to access a page and cause a protection fault. addr %08x", addr);
+ unsigned long *pde_src = (unsigned long *) current->cr3;
+ printk("p=%x\n", pde_src[796]);
+ //panic("errcode %08x addr %08x", errcode, addr);
}
if((errcode & PAGE_P) == 0)
setup_fs();
printk("%s\n", version);
+ //vga_dbg_toggle();
}
call *sysc_handler_table(,%eax,4)
+normal_syscall_exit:
leal sysexit, %edx
movl %edx, PT_REGS_EDX(%esp)
- movl %ebp, PT_REGS_ECX(%esp)
+ movl PT_REGS_EBP(%esp), %edx
+ movl %edx, PT_REGS_ECX(%esp)
syscall_exit:
movl %eax, PT_REGS_EAX(%esp)
ret_from_fork_user:
xorl %eax, %eax
- jmp syscall_exit
+ jmp normal_syscall_exit
ret_from_fork_krnl:
movl PT_REGS_EDX(%esp), %edx
{
static unsigned int cnt=0;
printl(MPL_TEST, "sysc_test %u", cnt++);
+
+ //unsigned long *pde = (unsigned long *)current->cr3;
+ //printk("sysctest %08x\n", pde[797]);
}
void init_sysc_handler_table()
for(i=0; i<SYSC_NUM; i++)
sysc_handler_table[i] = (unsigned long) sysc_none;
-#define _sysc_(nr, sym) \
- do \
- { \
- extern int sym (); \
- sysc_handler_table[nr] = (unsigned long) sym; \
+#define _sysc_(nr, sym) \
+ do \
+ { \
+ extern int sym (); \
+ sysc_handler_table[nr] = (unsigned long) sym; \
}while(0);
_sysc_(SYSC_WRITE, sysc_write);
* ------------------------------------------------------------------------
*/
-
+// "movl $1f, %%edi;"
+//
#define SYSENTER_ASM \
- "pushl $1f;" \
+ "pushl $1f;" \
"pushl %%ecx;" \
"pushl %%edx;" \
"pushl %%ebp;" \
return __sysc_ret__;
}
-static int __syscall5(int nr, unsigned long a, unsigned long b, unsigned long c, unsigned long d, unsigned long e)
-{
- int __sysc_ret__ = 0;
- asm(SYSENTER_ASM:"=a"(__sysc_ret__):"a"(nr), "b"(a), "c"(b), "d"(c), "S"(d), "D"(e));
- return __sysc_ret__;
-}
-
-
-
int _syscall0(int nr)
{
return __syscall0(nr);
{
return __syscall4(nr, a, b, c, d);
}
-
-int _syscall5(int nr, unsigned long a, unsigned long b, unsigned long c, unsigned long d, unsigned long e)
-{
- return __syscall5(nr, a, b, c, d, e);
-}
//sysenter(0);
//syscall3(0, fd, buf, size);
//asm("nop;nop;nop;");
-
+
syscall3(SYSC_WRITE, fd, buf, size);
return size;
page_t *va2page(unsigned long addr)
{
- return buddy_system.page_map + va2pfn(addr);
+ page_t *page = buddy_system.page_map + va2pfn(addr);
+ return page;
}
void *page2va(page_t *page)
page_t *page = __alloc_pages(order);
irq_restore(flags);
- return (unsigned long) page2va(page);
+ unsigned long addr = (unsigned long) page2va(page);
+ return addr;
}
void __free_pages(page_t *page, unsigned int order)
{
page_t *page;
unsigned long i;
- unsigned long pfn_cnt = bootmem_total_pages();
+ unsigned long pfn_cnt = bootmem_max_pfn();
// init free area
memset(&buddy_system, 0, sizeof(buddy_system));
while(1);
}
- printk("page_map begin %08x end %08x\n", buddy_system.page_map, buddy_system.page_map + pfn_cnt);
-
+ printk("page_map begin %08x end %08x pfncnt %u page_t size %u\n", buddy_system.page_map, buddy_system.page_map + pfn_cnt + 1, pfn_cnt, sizeof(page_t));
for(i=0; i<pfn_cnt; ++i)
{
page = buddy_system.page_map + i;
bootmem_data_t bootmem_data;
-unsigned long bootmem_total_pages()
+unsigned long bootmem_max_pfn()
{
return bootmem_data.max_pfn;
}
void init_paging()
{
+ printk("max_pfn %u", bootmem_data.max_pfn);
+ //while(1);
unsigned int i;
unsigned long pfn = 0;
pte_t *pte = 0;
*pte = (pte_t) (page_addr | PAGE_P | PAGE_WR);
}
-
// paging for kernel space
unsigned long delta = get_npd(PAGE_OFFSET);
for(i=delta; i<PDECNT_PER_PAGE; ++i)
void do_no_page(void *addr)
{
+ printk("%s addr %08x\n", __func__, (unsigned long)addr);
pde_t *pde = (pde_t *)current->cr3;
pte_t *pte;
unsigned long page = alloc_one_page(0);
void do_wp_page(void *addr)
{
+ //printk("%s addr %08x\n", __func__, (unsigned long)addr);
int npde = get_npd(addr);
int npte = get_npt(addr);
dst = va2pa(dst);
pt[npte] = dst | flags;
+ pt[npte] |= PAGE_WR;
+ pd[npde] |= PAGE_WR;
dst = (unsigned long)pa2va(PAGE_ALIGN(dst));
}
else
{
- //pd[npde] |= PAGE_WR;
+ pd[npde] |= PAGE_WR;
pt[npte] |= PAGE_WR;
//pd[npde] |= PAGE_US;
//pt[npte] |= PAGE_US;