diff --git a/fs/Makefile b/fs/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..a843017d97b836aebec3ed76ec2bcc8ee9bf7e16 --- /dev/null +++ b/fs/Makefile @@ -0,0 +1,16 @@ +GCC := gcc +LD := ld +CCFLAG := -I../include -nostdinc -ffreestanding -Wall -fomit-frame-pointer -fno-stack-protector -c -m32 +LDFLAG := -Ttext 0x0 -s --oformat binary -m elf_i386 +INCDIR := ../include +OBJS := read_write.o + +fs.o : $(OBJS) + $(LD) -m elf_i386 -r -o $@ $^ + +read_write.o : read_write.c + $(GCC) $(CCFLAG) -o $@ $< + +clean : + rm *.o + diff --git a/fs/read_write.c b/fs/read_write.c new file mode 100644 index 0000000000000000000000000000000000000000..bfe0317bb6d139a4c5fd472b4107c1e9aa77432b --- /dev/null +++ b/fs/read_write.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include +#include + +extern int tty_write(int channel, const char* buf, int count); + +int sys_write(unsigned int fd,char * buf,int count) { + if (fd == 1) { + return tty_write(0, buf, count); + } + + return 0; +} + diff --git a/include/asm/segment.h b/include/asm/segment.h new file mode 100644 index 0000000000000000000000000000000000000000..4e111aa282798dd9be28aa657ab1eae9ba1f533c --- /dev/null +++ b/include/asm/segment.h @@ -0,0 +1,11 @@ +#ifndef _SEGMENT_H +#define _SEGMENT_H + +extern inline unsigned char get_fs_byte(const char * addr) { + unsigned register char _v; + __asm__ ("movb %%fs:%1,%0":"=r" (_v):"m" (*addr)); + return _v; +} + +#endif + diff --git a/include/ctype.h b/include/ctype.h new file mode 100644 index 0000000000000000000000000000000000000000..974b192c6cd3e93aa765bea3f36c11a37cfb6718 --- /dev/null +++ b/include/ctype.h @@ -0,0 +1,21 @@ +#ifndef _CTYPE_H +#define _CTYPE_H + +#define _U 0x01 /* upper */ +#define _L 0x02 /* lower */ +#define _D 0x04 /* digit */ +#define _C 0x08 /* cntrl */ +#define _P 0x10 /* punct */ +#define _S 0x20 /* white space (space/lf/tab) */ +#define _X 0x40 /* hex digit */ +#define _SP 0x80 /* hard space (0x20) */ + + +extern unsigned char _ctype[]; +extern char _ctmp; + +#define islower(c) ((_ctype+1)[c]&(_L)) + +#define toupper(c) (_ctmp=c,islower(_ctmp)?_ctmp-('a'-'A'):_ctmp) + +#endif diff --git a/include/linux/mm.h b/include/linux/mm.h index ade08d0bf49cf364d8a0740b2e920d268301fae7..7030a243bdd688ec03d0557415e7c57f33504980 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1,9 +1,15 @@ #ifndef _MM_H #define _MM_H +#include + #define PAGE_SIZE 4096 extern unsigned long get_free_page(); +extern void free_page(unsigned long addr); + +#define invalidate() \ +__asm__("movl %%eax,%%cr3"::"a" (0)) #define LOW_MEM 0x100000 extern unsigned long HIGH_MEMORY; diff --git a/include/linux/sched.h b/include/linux/sched.h index 2bd53a7b7ee8b0b1cadf5866fa5df1f0baa67f11..fc6d7ea310f2168be77c3e2103473ed2e3b3056e 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -4,6 +4,15 @@ #define HZ 100 #define NR_TASKS 64 +#define TASK_SIZE 0x04000000 + +#if (TASK_SIZE & 0x3fffff) +#error "TASK_SIZE must be multiple of 4M" +#endif + +#if (((TASK_SIZE>>16)*NR_TASKS) != 0x10000) +#error "TASK_SIZE*NR_TASKS must be 4GB" +#endif #define FIRST_TASK task[0] #define LAST_TASK task[NR_TASKS-1] @@ -11,16 +20,29 @@ #include #include +#define TASK_RUNNING 0 +#define TASK_INTERRUPTIBLE 1 +#define TASK_UNINTERRUPTIBLE 2 +#define TASK_ZOMBIE 3 +#define TASK_STOPPED 4 + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +extern int copy_page_tables(unsigned long from, unsigned long to, long size); +extern int free_page_tables(unsigned long from, unsigned long size); void trap_init(); void sched_init(); void test_a(); void test_b(); -int create_second_process(); extern struct task_struct *task[NR_TASKS]; extern struct task_struct *current; +typedef int (*fn_ptr)(); + struct tss_struct { long back_link; long esp0; @@ -48,12 +70,18 @@ struct tss_struct { }; struct task_struct { + long state; + long pid; + struct task_struct *p_pptr; struct desc_struct ldt[3]; struct tss_struct tss; }; #define INIT_TASK \ { \ + 0, \ + 0, \ + &init_task.task,\ { \ {0, 0}, \ {0xfff, 0xc0fa00}, \ @@ -89,6 +117,31 @@ struct task_struct { "d" (_TSS(n)),"c" ((long) task[n])); \ } +#define _set_base(addr,base) \ +__asm__("movw %%dx,%0\n\t" \ + "rorl $16,%%edx\n\t" \ + "movb %%dl,%1\n\t" \ + "movb %%dh,%2" \ + ::"m" (*((addr)+2)), \ + "m" (*((addr)+4)), \ + "m" (*((addr)+7)), \ + "d" (base) \ + :) + +#define _set_limit(addr,limit) \ +__asm__("movw %%dx,%0\n\t" \ + "rorl $16,%%edx\n\t" \ + "movb %1,%%dh\n\t" \ + "andb $0xf0,%%dh\n\t" \ + "orb %%dh,%%dl\n\t" \ + "movb %%dl,%1" \ + ::"m" (*(addr)), \ + "m" (*((addr)+6)), \ + "d" (limit) \ + :"dx") + +#define set_base(ldt,base) _set_base( ((char *)&(ldt)) , base ) +#define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , (limit-1)>>12 ) #define _get_base(addr) ({\ unsigned long __base; \ diff --git a/include/linux/sys.h b/include/linux/sys.h new file mode 100644 index 0000000000000000000000000000000000000000..69cd49b04b628f851d02e373231aa519124af5f3 --- /dev/null +++ b/include/linux/sys.h @@ -0,0 +1,191 @@ +//extern int sys_setup(); +//extern int sys_exit(); +extern int sys_fork(); +//extern int sys_read(); +extern int sys_write(); +//extern int sys_open(); +//extern int sys_close(); +//extern int sys_waitpid(); +//extern int sys_creat(); +//extern int sys_link(); +//extern int sys_unlink(); +//extern int sys_execve(); +//extern int sys_chdir(); +//extern int sys_time(); +//extern int sys_mknod(); +//extern int sys_chmod(); +//extern int sys_chown(); +//extern int sys_break(); +//extern int sys_stat(); +//extern int sys_lseek(); +//extern int sys_getpid(); +//extern int sys_mount(); +//extern int sys_umount(); +//extern int sys_setuid(); +//extern int sys_getuid(); +//extern int sys_stime(); +//extern int sys_ptrace(); +//extern int sys_alarm(); +//extern int sys_fstat(); +//extern int sys_pause(); +//extern int sys_utime(); +//extern int sys_stty(); +//extern int sys_gtty(); +//extern int sys_access(); +//extern int sys_nice(); +//extern int sys_ftime(); +//extern int sys_sync(); +//extern int sys_kill(); +//extern int sys_rename(); +//extern int sys_mkdir(); +//extern int sys_rmdir(); +//extern int sys_dup(); +//extern int sys_pipe(); +//extern int sys_times(); +//extern int sys_prof(); +//extern int sys_brk(); +//extern int sys_setgid(); +//extern int sys_getgid(); +//extern int sys_signal(); +//extern int sys_geteuid(); +//extern int sys_getegid(); +//extern int sys_acct(); +//extern int sys_phys(); +//extern int sys_lock(); +//extern int sys_ioctl(); +//extern int sys_fcntl(); +//extern int sys_mpx(); +//extern int sys_setpgid(); +//extern int sys_ulimit(); +//extern int sys_uname(); +//extern int sys_umask(); +//extern int sys_chroot(); +//extern int sys_ustat(); +//extern int sys_dup2(); +//extern int sys_getppid(); +//extern int sys_getpgrp(); +//extern int sys_setsid(); +//extern int sys_sigaction(); +//extern int sys_sgetmask(); +//extern int sys_ssetmask(); +//extern int sys_setreuid(); +//extern int sys_setregid(); +//extern int sys_sigpending(); +//extern int sys_sigsuspend(); +//extern int sys_sethostname(); +//extern int sys_setrlimit(); +//extern int sys_getrlimit(); +//extern int sys_getrusage(); +//extern int sys_gettimeofday(); +//extern int sys_settimeofday(); +//extern int sys_getgroups(); +//extern int sys_setgroups(); +//extern int sys_select(); +//extern int sys_symlink(); +//extern int sys_lstat(); +//extern int sys_readlink(); +//extern int sys_uselib(); + +fn_ptr sys_call_table[] = { + 0, /*sys_setup*/ + 0, /*sys_exit*/ + sys_fork, + 0, /*sys_read,*/ + sys_write, +// sys_open, +// sys_close, +// sys_waitpid, +// sys_creat, +// sys_link, +// +// sys_unlink, +// sys_execve, +// sys_chdir, +// sys_time, +// sys_mknod, +// sys_chmod, +// +// sys_chown, +// sys_break, +// sys_stat, +// sys_lseek, +// sys_getpid, +// sys_mount, +// +// sys_umount, +// sys_setuid, +// sys_getuid, +// sys_stime, +// sys_ptrace, +// sys_alarm, +// +// sys_fstat, +// sys_pause, +// sys_utime, +// sys_stty, +// sys_gtty, +// sys_access, +// +// sys_nice, +// sys_ftime, +// sys_sync, +// sys_kill, +// sys_rename, +// sys_mkdir, +// +// sys_rmdir, +// sys_dup, +// sys_pipe, +// sys_times, +// sys_prof, +// sys_brk, +// sys_setgid, +// +// sys_getgid, +// sys_signal, +// sys_geteuid, +// sys_getegid, +// sys_acct, +// sys_phys, +// +// sys_lock, +// sys_ioctl, +// sys_fcntl, +// sys_mpx, +// sys_setpgid, +// sys_ulimit, +// +// sys_uname, +// sys_umask, +// sys_chroot, +// sys_ustat, +// sys_dup2, +// sys_getppid, +// +// sys_getpgrp, +// sys_setsid, +// sys_sigaction, +// sys_sgetmask, +// sys_ssetmask, +// +// sys_setreuid, +// sys_setregid, +// sys_sigsuspend, +// sys_sigpending, +// sys_sethostname, +// sys_setrlimit, +// sys_getrlimit, +// sys_getrusage, +// sys_gettimeofday, +// sys_settimeofday, +// sys_getgroups, +// sys_setgroups, +// sys_select, +// sys_symlink, +// sys_lstat, +// sys_readlink, +// sys_uselib +}; + +int NR_syscalls = sizeof(sys_call_table)/sizeof(fn_ptr); + diff --git a/include/linux/tty.h b/include/linux/tty.h index 7142292917fe985ece98114d4fe4bd020e645037..839c5765b57ac5127d410325c88d99fc0c55b81f 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -1,9 +1,46 @@ #ifndef _TTY_H #define _TTY_H +#include + +#define TTY_BUF_SIZE 1024 + +struct tty_queue { + unsigned long data; + unsigned long head; + unsigned long tail; + struct task_struct * proc_list; + char buf[TTY_BUF_SIZE]; +}; + +#define INC(a) ((a) = ((a)+1) & (TTY_BUF_SIZE-1)) +#define DEC(a) ((a) = ((a)-1) & (TTY_BUF_SIZE-1)) +#define EMPTY(a) ((a).head == (a).tail) +#define LEFT(a) (((a).tail-(a).head-1)&(TTY_BUF_SIZE-1)) +#define LAST(a) ((a).buf[(TTY_BUF_SIZE-1)&((a).head-1)]) +#define FULL(a) (!LEFT(a)) +#define CHARS(a) (((a).head-(a).tail)&(TTY_BUF_SIZE-1)) +#define GETCH(queue,c) \ +(void)({c=(queue).buf[(queue).tail];INC((queue).tail);}) +#define PUTCH(c,queue) \ +(void)({(queue).buf[(queue).head]=(c);INC((queue).head);}) + +struct tty_struct { + struct termios termios; + int pgrp; + int stopped; + void (*write)(struct tty_struct * tty); + struct tty_queue read_q; + struct tty_queue write_q; + struct tty_queue secondary; +}; + +#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" + void con_init(); void tty_init(); -void con_write(); +int tty_write(unsigned c, char * buf, int n); +void con_write(struct tty_struct * tty); #endif diff --git a/include/sys/stat.h b/include/sys/stat.h new file mode 100644 index 0000000000000000000000000000000000000000..cf474a0d551ea9dee27970e74d870b16540531d4 --- /dev/null +++ b/include/sys/stat.h @@ -0,0 +1,6 @@ +#ifndef _SYS_STAT_H +#define _SYS_STAT_H + +#include + +#endif diff --git a/include/sys/types.h b/include/sys/types.h new file mode 100644 index 0000000000000000000000000000000000000000..b667b459c6b3cc7546351a349f315398d9cdab8e --- /dev/null +++ b/include/sys/types.h @@ -0,0 +1,10 @@ +#ifndef _SYS_TYPES_H +#define _SYS_TYPES_H + +typedef long off_t; + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned long tcflag_t; + +#endif diff --git a/include/termios.h b/include/termios.h new file mode 100644 index 0000000000000000000000000000000000000000..b39ce107cca976ef1e4af51d0fc08711b14b183a --- /dev/null +++ b/include/termios.h @@ -0,0 +1,46 @@ +#ifndef _TERMIOS_H +#define _TERMIOS_H + +#define TTY_BUF_SIZE 1024 + +#define NCCS 17 +struct termios { + unsigned short c_iflag; + unsigned short c_oflag; + unsigned short c_cflag; + unsigned short c_lflag; + unsigned char c_line; + unsigned char c_cc[NCCS]; +}; + + +// iflag +#define ICRNL 0000400 + +// oflag +#define OPOST 0000001 +#define OLCUC 0000002 +#define ONLCR 0000004 +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 + + +// lflag +#define ISIG 0000001 +#define ICANON 0000002 +#define XCASE 0000004 +#define ECHO 0000010 +#define ECHOE 0000020 +#define ECHOK 0000040 +#define ECHONL 0000100 +#define NOFLSH 0000200 +#define TOSTOP 0000400 +#define ECHOCTL 0001000 +#define ECHOPRT 0002000 +#define ECHOKE 0004000 +#define FLUSHO 0010000 +#define PENDIN 0040000 +#define IEXTEN 0100000 + +#endif diff --git a/include/unistd.h b/include/unistd.h new file mode 100644 index 0000000000000000000000000000000000000000..060344121161ff06ee8155e260783722f0c560c5 --- /dev/null +++ b/include/unistd.h @@ -0,0 +1,133 @@ +#ifndef _UNISTD_H +#define _UNISTD_H + +#include + +#ifndef NULL +#define NULL ((void*)0) +#endif + +#ifdef __LIBRARY__ + +#define __NR_setup 0 /* used only by init, to get system going */ +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_open 5 +#define __NR_close 6 +#define __NR_waitpid 7 +#define __NR_creat 8 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_execve 11 +#define __NR_chdir 12 +#define __NR_time 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_chown 16 +#define __NR_break 17 +#define __NR_stat 18 +#define __NR_lseek 19 +#define __NR_getpid 20 +#define __NR_mount 21 +#define __NR_umount 22 +#define __NR_setuid 23 +#define __NR_getuid 24 +#define __NR_stime 25 +#define __NR_ptrace 26 +#define __NR_alarm 27 +#define __NR_fstat 28 +#define __NR_pause 29 +#define __NR_utime 30 +#define __NR_stty 31 +#define __NR_gtty 32 +#define __NR_access 33 +#define __NR_nice 34 +#define __NR_ftime 35 +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_rename 38 +#define __NR_mkdir 39 +#define __NR_rmdir 40 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_times 43 +#define __NR_prof 44 +#define __NR_brk 45 +#define __NR_setgid 46 +#define __NR_getgid 47 +#define __NR_signal 48 +#define __NR_geteuid 49 +#define __NR_getegid 50 +#define __NR_acct 51 +#define __NR_phys 52 +#define __NR_lock 53 +#define __NR_ioctl 54 +#define __NR_fcntl 55 +#define __NR_mpx 56 +#define __NR_setpgid 57 +#define __NR_ulimit 58 +#define __NR_uname 59 +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_ustat 62 +#define __NR_dup2 63 +#define __NR_getppid 64 +#define __NR_getpgrp 65 +#define __NR_setsid 66 +#define __NR_sigaction 67 +#define __NR_sgetmask 68 +#define __NR_ssetmask 69 +#define __NR_setreuid 70 +#define __NR_setregid 71 +#define __NR_sigsuspend 72 +#define __NR_sigpending 73 +#define __NR_sethostname 74 +#define __NR_setrlimit 75 +#define __NR_getrlimit 76 +#define __NR_getrusage 77 +#define __NR_gettimeofday 78 +#define __NR_settimeofday 79 +#define __NR_getgroups 80 +#define __NR_setgroups 81 +#define __NR_select 82 +#define __NR_symlink 83 +#define __NR_lstat 84 +#define __NR_readlink 85 +#define __NR_uselib 86 + +#define _syscall0(type, name) \ +type name() { \ + long __res; \ +__asm__ volatile("int $0x80\n\r"\ + : "=a"(__res) \ + : "a"(__NR_##name)); \ + if (__res >= 0) \ + return (type)__res; \ + errno = -__res; \ + return -1; \ +} + +#define _syscall3(type,name,atype,a,btype,b,ctype,c) \ +type name(atype a, btype b, ctype c) { \ + long __res; \ +__asm__ volatile("int $0x80\n\r"\ + : "=a"(__res) \ + : "a"(__NR_##name), "b"((long)a), "c"((long)b), "d"((long)c)); \ + if (__res >= 0) \ + return (type)__res; \ + errno = -__res; \ + return -1; \ +} + + + +#endif /* __LIBRARY__ */ + +extern int errno; + +int fork(); +int write(int fildes, const char * buf, off_t count); + +#endif diff --git a/kernel/Makefile b/kernel/Makefile index 7a092d41e9d9d25d54c8c6d8134d13911b5a63cf..528e366fd6cb0cc37de1ae51efb602fddd53f9c4 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -1,8 +1,9 @@ GCC := gcc -CCFLAG := -I../include -nostdinc -Wall -fomit-frame-pointer -fno-stack-protector -c -m32 +CCFLAG := -I../include -nostdinc -ffreestanding -Wall -fomit-frame-pointer -fno-stack-protector -c -m32 LDFLAG := -Ttext 0x0 -s --oformat binary -m elf_i386 INCDIR := ../include OBJS := head.o main.o sys_call.o asm.o sched.o printk.o vsprintf.o traps.o fork.o chr_drv/chr_drv.a ../mm/mm.o + ../lib/lib.a ../fs/fs.o system: $(OBJS) $(LD) $(LDFLAG) -M -e startup_32 -o $@ $^ > System.map @@ -40,10 +41,18 @@ chr_drv/chr_drv.a: chr_drv/*.c ../mm/mm.o : ../mm/*.c cd ../mm; make mm.o; cd ../kernel +../lib/lib.a : ../lib/*.c + cd ../lib; make lib.a; cd ../kernel + +../fs/fs.o : ../fs/*.c + cd ../fs; make fs.o; cd ../kernel + clean : rm *.o rm system rm System.map cd chr_drv; make clean; cd .. cd ../mm; make clean; cd ../kernel + cd ../lib; make clean; cd ../kernel + cd ../fs; make clean; cd ../kernel diff --git a/kernel/asm.S b/kernel/asm.S index 1a82981e8e5a85164571084da28a623719eeb259..c6e39b1e7db9c0ef6a40fb11037e6ed875d43c37 100644 --- a/kernel/asm.S +++ b/kernel/asm.S @@ -1,7 +1,7 @@ .code32 .globl divide_error, .globl invalid_TSS, segment_not_present, stack_segment -.globl general_protection, page_fault +.globl general_protection divide_error: pushl $do_divide_error @@ -88,7 +88,3 @@ general_protection: pushl $do_general_protection jmp error_code -page_fault: - pushl $do_page_fault - jmp error_code - diff --git a/kernel/chr_drv/Makefile b/kernel/chr_drv/Makefile index 56430e64557166f4bd422ee63bf123e3b2ab7380..727b55694e372349df13f83fe893cf700c6d3a7f 100644 --- a/kernel/chr_drv/Makefile +++ b/kernel/chr_drv/Makefile @@ -2,17 +2,23 @@ AR := ar LD := ld GCC := gcc CCFLAG := -m32 -I../../include -nostdinc -Wall -fomit-frame-pointer -fno-stack-protector -c -OBJS := tty_io.o console.o +OBJS := tty_io.o console.o keyboard.o kboard.o + +chr_drv.a : $(OBJS) + $(AR) rcs $@ $^ + sync tty_io.o : tty_io.c $(GCC) $(CCFLAG) -o $@ $< -console.o : console.c +kboard.o : kboard.c $(GCC) $(CCFLAG) -o $@ $< -chr_drv.a : $(OBJS) - $(AR) rcs $@ $^ - sync +keyboard.o : keyboard.S + $(GCC) -m32 -traditional -c -o $@ $< + +console.o : console.c + $(GCC) $(CCFLAG) -o $@ $< clean : rm *.o diff --git a/kernel/chr_drv/console.c b/kernel/chr_drv/console.c index 749aa726f0629086fce14fe2a2de26a6a35590cb..6ce868ceedc9d700e3ed820bf12ca58b1417fe07 100644 --- a/kernel/chr_drv/console.c +++ b/kernel/chr_drv/console.c @@ -1,3 +1,4 @@ +#include #include #include @@ -18,6 +19,8 @@ #define VIDEO_TYPE_EGAM 0x20 /* EGA/VGA in Monochrome Mode */ #define VIDEO_TYPE_EGAC 0x21 /* EGA/VGA in Color Mode */ +extern void keyboard_interrupt(void); + static unsigned char video_type; /* Type of display being used */ static unsigned long video_num_columns; /* Number of text columns */ static unsigned long video_num_lines; /* Number of test lines */ @@ -104,6 +107,7 @@ static void del() { } void con_init() { + register unsigned char a; char * display_desc = "????"; char * display_ptr; @@ -149,7 +153,7 @@ void con_init() { display_ptr = ((char *)video_mem_base) + video_size_row - 8; while (*display_desc) { *display_ptr++ = *display_desc++; - *display_ptr++; + display_ptr++; } origin = video_mem_base; @@ -159,14 +163,22 @@ void con_init() { gotoxy(ORIG_X, ORIG_Y); set_cursor(); + + set_trap_gate(0x21,&keyboard_interrupt); + outb_p(inb_p(0x21)&0xfd,0x21); + a=inb_p(0x61); + outb_p(a|0x80,0x61); + outb_p(a,0x61); } -void con_write(const char* buf, int nr) { - char* s = buf; - int i = 0; +void con_write(struct tty_struct* tty) { + int nr; + char c; + + nr = CHARS(tty->write_q); while(nr--) { - char c = *s++; + GETCH(tty->write_q, c); if (c > 31 && c < 127) { if (x >= video_num_columns) { x -= video_num_columns; diff --git a/kernel/chr_drv/kboard.c b/kernel/chr_drv/kboard.c new file mode 100644 index 0000000000000000000000000000000000000000..552204b2701330a42ff2f1ca056db7211bfda853 --- /dev/null +++ b/kernel/chr_drv/kboard.c @@ -0,0 +1,80 @@ +#include +#include +#include + +int cursor = 0x1e0; + +static char key_map[0x7f] = { + 0, 27, + '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', + 127, 9, + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', + 10, 0, + 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', + '`', 0, + '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', + 0, '*', 0, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + '-', 0, 0, 0, '+', + 0,0,0,0,0,0,0, + '>', + 0,0,0,0,0,0,0,0,0,0}; + +static char shift_map[0x7f] = { + 0,27, + '!', '@', '#', '$', '%', '^', '&', '*','(',')','_','+', + 127,9, + 'Q','W','E','R','T','Y','U','I','O','P','{','}', + 10,0, + 'A','S','D','F','G','H','J','K','L',':','\"', + '~',0, + '|','Z','X','C','V','B','N','M','<','>','?', + 0,'*',0,32, //36h-39h + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //3Ah-49h + '-',0,0,0,'+', //4A-4E + 0,0,0,0,0,0,0, //4F-55 + '>', + 0,0,0,0,0,0,0,0,0,0}; + +#define showh(tmp) \ + __asm__("movl cursor, %%edx\n\r" \ + "movb $0x0f, %%ah \n\r" \ + "movw %%ax, %%gs:(%%edx)\n\r" \ + "addl $0x02, cursor\n\r" \ + ::"a"(tmp):"edx", "memory"); + +char mode = 0; +char e0 = 0; + +void keyboard_handler(void) +{ + unsigned char a, scan_code; + + scan_code = inb_p(0x60); + a = inb_p(0x61); + outb_p(a | 0x80, 0x61); + outb(a & 0x7f, 0x61); + outb(0x20, 0x20); + + if (scan_code == 0xE0) + { + e0 = 1; + } + else if (scan_code == 0x1d) // left ctrl + { + mode = 3; + } + else if (scan_code == 0x2a) + { + mode = 5; + } + else + { + if (scan_code & 0x80) + { + showh(key_map[scan_code & 0x7f]); + } + } +} + + diff --git a/kernel/chr_drv/keyboard.S b/kernel/chr_drv/keyboard.S new file mode 100644 index 0000000000000000000000000000000000000000..caa9060a05c0395f4287b56cd072693e940b4e44 --- /dev/null +++ b/kernel/chr_drv/keyboard.S @@ -0,0 +1,30 @@ +.code32 +.text +.globl keyboard_interrupt + +.align 4 +keyboard_interrupt: + pushw %ds + pushw %es + pushw %fs + pushl %edx + pushl %ecx + pushl %ebx + pushl %eax + movl $0x10, %eax + movw %ax, %ds + movw %ax, %es + movl $0x17, %eax + movw %ax, %fs + pushl %eax + call keyboard_handler + popl %eax + popl %eax + popl %ebx + popl %ecx + popl %edx + popw %fs + popw %es + popw %ds + iret + diff --git a/kernel/chr_drv/tty_io.c b/kernel/chr_drv/tty_io.c index eeeb1c263180879a9ff7bf4184b661bc4bf1b0c1..b93f4780874e9d9fbdcfc9a65a165e08063b5df0 100644 --- a/kernel/chr_drv/tty_io.c +++ b/kernel/chr_drv/tty_io.c @@ -1,10 +1,73 @@ +#include #include +#include + +#define _O_FLAG(tty,f) ((tty)->termios.c_oflag & f) + +#define O_POST(tty) _O_FLAG((tty),OPOST) +#define O_NLCR(tty) _O_FLAG((tty),ONLCR) +#define O_CRNL(tty) _O_FLAG((tty),OCRNL) +#define O_NLRET(tty) _O_FLAG((tty),ONLRET) +#define O_LCUC(tty) _O_FLAG((tty),OLCUC) + +struct tty_struct tty_table[] = { + { + { + ICRNL, + OPOST | ONLCR, + 0, + ISIG | ICANON | ECHO | ECHOCTL | ECHOKE, + 0, + INIT_C_CC + }, + 0, + 0, + con_write, + {0, 0, 0, 0, ""}, + {0, 0, 0, 0, ""}, + {0, 0, 0, 0, ""}, + } +}; + void tty_init() { con_init(); } -void tty_write(unsigned channel, char* buf, int nr) { - con_write(buf, nr); +int tty_write(unsigned channel, char* buf, int nr) { + static int cr_flag = 0; + struct tty_struct * tty; + char c, *b=buf; + + if (channel > 2 || nr < 0) + return -1; + + tty = tty_table + channel; + while (nr > 0) { + c = get_fs_byte(b); + if (O_POST(tty)) { + if (c=='\r' && O_CRNL(tty)) + c = '\n'; + else if (c=='\n' && O_NLRET(tty)) + c = '\r'; + + if (c=='\n' && !cr_flag && O_NLCR(tty)) { + cr_flag = 1; + PUTCH(13,tty->write_q); + continue; + } + + if (O_LCUC(tty)) { + c = toupper(c); + } + } + + b++; nr--; + cr_flag = 0; + PUTCH(c,tty->write_q); + } + + tty->write(tty); + return (b-buf); } diff --git a/kernel/fork.c b/kernel/fork.c index 47dc817274f075e59fb82b3a4aa68482042e391b..82eeeb45dcac8375a9a7fb1664426191f46b5df6 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -3,51 +3,102 @@ #include #include -int find_empty_process() { - int i; - for (i = 1; i < NR_TASKS; i++) { - if (!task[i]) - return i; +long last_pid = 0; + +int copy_mem(int nr, struct task_struct* p) { + unsigned long old_data_base,new_data_base,data_limit; + unsigned long old_code_base,new_code_base,code_limit; + + code_limit = get_limit(0x0f); + data_limit = get_limit(0x17); + old_code_base = get_base(current->ldt[1]); + old_data_base = get_base(current->ldt[2]); + if (old_data_base != old_code_base) + printk("We don't support separate I&D"); + if (data_limit < code_limit) + printk("Bad data_limit"); + + new_data_base = new_code_base = nr * TASK_SIZE; + set_base(p->ldt[1],new_code_base); + set_base(p->ldt[2],new_data_base); + if (copy_page_tables(old_data_base,new_data_base,data_limit)) { + free_page_tables(new_data_base,data_limit); + return -ENOMEM; } - return -EAGAIN; + return 0; } -int create_second_process1() { - int nr; +int copy_process(int nr,long ebp,long edi,long esi,long gs,long none, + long ebx,long ecx,long edx, long orig_eax, + long fs,long es,long ds, + long eip,long cs,long eflags,long esp,long ss) { struct task_struct *p; - //char* ustack; p = (struct task_struct *) get_free_page(); if (!p) return -EAGAIN; - /* - ustack = (char*) get_free_page(); - if (!ustack) - return -EAGAIN; - */ + task[nr] = p; + *p = *current; - //*p = *current; + p->pid = last_pid; + p->p_pptr = current; - p->tss.eip = (long)test_b; - p->tss.ldt = _LDT(nr); + p->ldt[0] = current->ldt[0]; + p->ldt[1] = current->ldt[1]; + p->ldt[2] = current->ldt[2]; + + p->tss.back_link = 0; + p->tss.esp0 = PAGE_SIZE + (long)p - 8; p->tss.ss0 = 0x10; - p->tss.esp0 = PAGE_SIZE + (long)p; - p->tss.ss = 0x10; - p->tss.ds = 0x10; - p->tss.es = 0x10; - p->tss.fs = 0x10; - p->tss.gs = 0x10; - p->tss.cs = 0x08; - p->tss.esp = PAGE_SIZE + (long)p; - p->tss.eflags = 0x602; + p->tss.cr3 = current->tss.cr3; + p->tss.eip = eip; + p->tss.eflags = eflags; + p->tss.eax = 0; + p->tss.ecx = ecx; + p->tss.edx = edx; + p->tss.ebx = ebx; + p->tss.esp = esp; + p->tss.ebp = ebp; + p->tss.esi = esi; + p->tss.edi = edi; + p->tss.es = es & 0xffff; + p->tss.cs = cs & 0xffff; + p->tss.ss = ss & 0xffff; + p->tss.ds = ds & 0xffff; + p->tss.fs = fs & 0xffff; + p->tss.gs = gs & 0xffff; + p->tss.ldt = _LDT(nr); + p->tss.trace_bitmap = 0x80000000; + + if (copy_mem(nr, p)) { + task[nr] = NULL; + free_page((long)p); + return -EAGAIN; + } set_tss_desc(gdt+(nr<<1)+FIRST_TSS_ENTRY,&(p->tss)); set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY,&(p->ldt)); - task[nr] = p; + return last_pid; +} - return nr; +int find_empty_process() { + int i; +repeat: + if ((++last_pid)<0) last_pid=1; + + for(i=0 ; ipid == last_pid)) + goto repeat; + } + + for (i = 1; i < NR_TASKS; i++) { + if (!task[i]) + return i; + } + + return -EAGAIN; } diff --git a/kernel/main.c b/kernel/main.c index 7220d00577eb7695e8b0b3da04faf9485932f191..ff2c3381ffc2bbff6f811f7167a20c557ab4bb63 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -1,11 +1,24 @@ #define __LIBRARY__ +#include + +inline _syscall0(int, fork); + +int errno; + #include #include #include #include +#include + +static char printbuf[1024]; + +int printf(const char* fmt, ...); + +extern int vsprintf(char* buf, const char* fmt, va_list args); extern void mem_init(long start, long end); #define EXT_MEM_K (*(unsigned short *)0x90002) @@ -45,14 +58,34 @@ void main(void) tty_init(); - printk("%x, %x\n\r", task[0], task[1]); + printk("\nmemory start at 0x%x, end at 0x%x\n", main_memory_start, memory_end); + move_to_user_mode(); - test_a(); + if (!fork()) { + printf("In second process, user mode!\n"); + test_b(); + while(1) {} + } + + __asm__("movl $0x0, %edi\n\r" + "movw $0x18, %ax\n\t" + "movw %ax, %gs \n\t" + "movb $0x0c, %ah\n\r" + "movb $'A', %al\n\r" + "movw %ax, %gs:(%edi)\n\r"); - __asm__ __volatile__( - "int $0x80\n\r" - "loop:\n\r" - "jmp loop" - ::); + for(;;); } + +int printf(const char* fmt, ...) { + va_list args; + int i; + + va_start(args, fmt); + write(1, printbuf, i = vsprintf(printbuf, fmt, args)); + va_end(args); + + return i; +} + diff --git a/kernel/sched.c b/kernel/sched.c index 9a876b6061ab6b2b008215c5f41ab08e4bd92963..45c060dfb6aa87bd780de81bfbf7a35a8bf85e6b 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -31,35 +32,27 @@ struct short b; } stack_start = {&user_stack[PAGE_SIZE >> 2], 0x10}; +void schedule() { + if (current == task[0] && task[1]) { + switch_to(1); + } + else if (current == task[1]) { + switch_to(0); + } +} int clock = COUNTER; -static int cnt = 0; -static int isFirst = 1; void do_timer(long cpl) { - cnt++; - - if (cnt > 2) - return; - if (clock >0 && clock <= COUNTER) { clock--; } else if (clock == 0) { - clock = COUNTER; - if (isFirst) { - isFirst = 0; - switch_to(1); - } - else { - isFirst = 1; - switch_to(0); - } + schedule(); } else { clock = COUNTER; } - cnt--; } void sched_init() { @@ -79,8 +72,6 @@ void sched_init() { p++; } - create_second_process(); - __asm__("pushfl; andl $0xffffbfff, (%esp); popfl"); ltr(0); lldt(0); @@ -95,65 +86,12 @@ void sched_init() { set_system_gate(0x80, &system_call); } -int create_second_process() { - struct task_struct *p; - int i, nr; - - nr = find_empty_process(); - if (nr < 0) - return -EAGAIN; - - //p = (struct task_struct*) &(second_task.task); - p = (struct task_struct*) get_free_page(); - *p = *current; - - set_tss_desc(gdt+(nr<<1)+FIRST_TSS_ENTRY,&(p->tss)); - set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY,&(p->ldt)); - - p->ldt[0] = current->ldt[0]; - p->ldt[1] = current->ldt[1]; - p->ldt[2] = current->ldt[2]; - - p->tss = current->tss; - - p->tss.eip = (long)test_b; - p->tss.ldt = _LDT(nr); - p->tss.ss0 = 0x10; - p->tss.esp0 = PAGE_SIZE + (long)p - 8; - p->tss.ss = 0x10; - p->tss.ds = 0x10; - p->tss.es = 0x10; - p->tss.cs = 0x8; - p->tss.fs = 0x10; - p->tss.esp = PAGE_SIZE + (long)p - 8; - p->tss.eflags = 0x602; - - task[nr] = p; - return nr; -} - -void test_a(void) { -__asm__("movl $0, %edi\n\r" - "movl $0x17, %eax\n\t" - "movw %ax, %ds \n\t" - "movw %ax, %es \n\t" - "movw %ax, %fs \n\t" - "movw $0x18, %ax\n\t" - "movw %ax, %gs \n\t" - "movb $0x0c, %ah\n\r" - "movb $'A', %al\n\r" - "loopa:\n\r" - "movw %ax, %gs:(%edi)\n\r" - "jmp loopa"); -} - void test_b(void) { -__asm__("movl $0, %edi\n\r" +__asm__("movl $0x30, %edi\n\r" "movw $0x18, %ax\n\t" "movw %ax, %gs \n\t" "movb $0x0f, %ah\n\r" "movb $'B', %al\n\r" - "loopb:\n\r" - "movw %ax, %gs:(%edi)\n\r" - "jmp loopb"); + "movw %ax, %gs:(%edi)\n\r"); } + diff --git a/kernel/sys_call.S b/kernel/sys_call.S index a75406c7e14c02cabf34e35d63482418bb0a1589..7ea146f0e96e73bba2aad760a71947457b8c4d59 100644 --- a/kernel/sys_call.S +++ b/kernel/sys_call.S @@ -1,6 +1,6 @@ .code32 .text -.globl system_call, timer_interrupt +.globl system_call, timer_interrupt, sys_fork EAX = 0x00 EBX = 0x04 @@ -19,43 +19,40 @@ int_msg: .asciz "In kernel interrupt\n\r" system_call: + pushl %ds + pushl %es + pushl %fs pushl %eax - pushl %ecx pushl %edx - pushw %ds - pushw %es - pushw %fs - movl $0x10, %eax - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - /* call _printk */ - pushl $int_msg - call printk - popl %eax - popw %fs - popw %es - popw %ds - popl %edx - popl %ecx - popl %eax - iret + pushl %ecx + pushl %ebx + movl $0x10, %edx + movw %dx, %ds + movw %dx, %es + movl $0x17, %edx + movw %dx, %fs + + call sys_call_table(, %eax, 4) + pushl %eax + ret_from_sys_call: popl %eax popl %ebx popl %ecx popl %edx - popw %fs - popw %es - popw %ds + addl $4, %esp + popl %fs + popl %es + popl %ds iret .align 4 timer_interrupt: - pushw %ds - pushw %es - pushw %fs + pushl %ds + pushl %es + pushl %fs + pushl $-1 pushl %edx pushl %ecx pushl %ebx @@ -73,3 +70,18 @@ timer_interrupt: call do_timer addl $4, %esp jmp ret_from_sys_call + +.align 4 +sys_fork: + call find_empty_process + testl %eax, %eax + js 1f + pushl %gs + pushl %esi + pushl %edi + pushl %ebp + pushl %eax + call copy_process + addl $20, %esp +1: ret + diff --git a/kernel/traps.c b/kernel/traps.c index 86cbdb5c79c92e32b0450a63118884ce49e94220..f10cce22138dd7596ab6c3cfa24fd03635be5ae1 100644 --- a/kernel/traps.c +++ b/kernel/traps.c @@ -76,10 +76,6 @@ void do_general_protection(long esp, long error_code) { die("general protection", esp, error_code); } -void do_page_fault(long esp, long error_code) { - die("page fault", esp, error_code); -} - void trap_init() { set_trap_gate(0, ÷_error); set_trap_gate(10, &invalid_TSS); diff --git a/lib/Makefile b/lib/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..f25f2c46bc8b9ee44eeb33a208797b6c15f62dd8 --- /dev/null +++ b/lib/Makefile @@ -0,0 +1,20 @@ +AR := ar +LD := ld +GCC := gcc +CCFLAG := -m32 -I../include -nostdinc -Wall -fomit-frame-pointer -fno-stack-protector -c +OBJS := ctype.o write.o + +lib.a : $(OBJS) + $(AR) rcs $@ $^ + sync + +ctype.o : ctype.c + $(GCC) $(CCFLAG) -o $@ $< + +write.o : write.c + $(GCC) $(CCFLAG) -o $@ $< + +clean : + rm *.o + rm lib.a + diff --git a/lib/ctype.c b/lib/ctype.c new file mode 100644 index 0000000000000000000000000000000000000000..a9379e959bb1d77d1f58c4c6dfcd9a33ee9bfbe5 --- /dev/null +++ b/lib/ctype.c @@ -0,0 +1,30 @@ +#include + +char _ctmp; + +unsigned char _ctype[] = {0x00, + _C,_C,_C,_C,_C,_C,_C,_C, + _C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, + _C,_C,_C,_C,_C,_C,_C,_C, + _C,_C,_C,_C,_C,_C,_C,_C, + _S|_SP,_P,_P,_P,_P,_P,_P,_P, + _P,_P,_P,_P,_P,_P,_P,_P, + _D,_D,_D,_D,_D,_D,_D,_D, + _D,_D,_P,_P,_P,_P,_P,_P, + _P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, + _U,_U,_U,_U,_U,_U,_U,_U, + _U,_U,_U,_U,_U,_U,_U,_U, + _U,_U,_U,_P,_P,_P,_P,_P, + _P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, + _L,_L,_L,_L,_L,_L,_L,_L, + _L,_L,_L,_L,_L,_L,_L,_L, + _L,_L,_L,_P,_P,_P,_P,_C, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + diff --git a/lib/write.c b/lib/write.c new file mode 100644 index 0000000000000000000000000000000000000000..102f7518ca053c4a3d91421bc937e85562165e82 --- /dev/null +++ b/lib/write.c @@ -0,0 +1,5 @@ +#define __LIBRARY__ +#include + +_syscall3(int,write,int,fd,const char *,buf,off_t,count) + diff --git a/mm/Makefile b/mm/Makefile index e1cfe5bea32349119e85e5675190a27bb6a5848e..6c1850df2a430f7781a26de4a3b6d31e7057d5d7 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -3,7 +3,7 @@ LD := ld CCFLAG := -I../include -nostdinc -Wall -fomit-frame-pointer -fno-stack-protector -c -m32 LDFLAG := -Ttext 0x0 -s --oformat binary -m elf_i386 INCDIR := ../include -OBJS := swap.o memory.o +OBJS := swap.o memory.o page.o mm.o : $(OBJS) $(LD) -m elf_i386 -r -o $@ $^ @@ -14,6 +14,9 @@ memory.o : memory.c swap.o : swap.c $(GCC) $(CCFLAG) -o $@ $< +page.o : page.S + $(GCC) -m32 -traditional -c -o $@ $< + clean : rm *.o diff --git a/mm/memory.c b/mm/memory.c index 26aa66b6ed90350b2add33f83bd7f8edab17e986..f45963f90302d913cdff77aa80f858ef586038a8 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -4,6 +4,129 @@ unsigned long HIGH_MEMORY = 0; unsigned char mem_map [ PAGING_PAGES ] = {0,}; +#define copy_page(from,to) \ +__asm__("cld ; rep ; movsl"::"S" (from),"D" (to),"c" (1024):) + +void free_page(unsigned long addr) { + if (addr < LOW_MEM) return; + if (addr >= HIGH_MEMORY) + printk("trying to free nonexistent page"); + + addr -= LOW_MEM; + addr >>= 12; + if (mem_map[addr]--) return; + mem_map[addr]=0; + printk("trying to free free page"); +} + +int free_page_tables(unsigned long from,unsigned long size) { + unsigned long *pg_table; + unsigned long * dir, nr; + + if (from & 0x3fffff) + printk("free_page_tables called with wrong alignment"); + if (!from) + printk("Trying to free up swapper memory space"); + size = (size + 0x3fffff) >> 22; + dir = (unsigned long *) ((from>>20) & 0xffc); + + for ( ; size-->0 ; dir++) { + if (!(1 & *dir)) + continue; + pg_table = (unsigned long *) (0xfffff000 & *dir); + for (nr=0 ; nr<1024 ; nr++) { + if (*pg_table) { + if (1 & *pg_table) + free_page(0xfffff000 & *pg_table); + *pg_table = 0; + } + pg_table++; + } + free_page(0xfffff000 & *dir); + *dir = 0; + } + invalidate(); + return 0; +} + +int copy_page_tables(unsigned long from,unsigned long to,long size) { + unsigned long * from_page_table; + unsigned long * to_page_table; + unsigned long this_page; + unsigned long * from_dir, * to_dir; + unsigned long nr; + + if ((from&0x3fffff) || (to&0x3fffff)) { + printk("copy_page_tables called with wrong alignment"); + } + + /* Get high 10 bits. As PDE is 4 byts, so right shift 20.*/ + from_dir = (unsigned long *) ((from>>20) & 0xffc); + to_dir = (unsigned long *) ((to>>20) & 0xffc); + + size = ((unsigned) (size+0x3fffff)) >> 22; + for( ; size-->0 ; from_dir++,to_dir++) { + if (1 & *to_dir) + printk("copy_page_tables: already exist"); + if (!(1 & *from_dir)) + continue; + + from_page_table = (unsigned long *) (0xfffff000 & *from_dir); + if (!(to_page_table = (unsigned long *) get_free_page())) + return -1; + + *to_dir = ((unsigned long) to_page_table) | 7; + nr = (from==0)?0xA0:1024; + + for ( ; nr-- > 0 ; from_page_table++,to_page_table++) { + this_page = *from_page_table; + if (!this_page) + continue; + if (!(1 & this_page)) + continue; + + this_page &= ~2; + *to_page_table = this_page; + + if (this_page > LOW_MEM) { + *from_page_table = this_page; + this_page -= LOW_MEM; + this_page >>= 12; + mem_map[this_page]++; + } + } + } + invalidate(); + return 0; +} + +void un_wp_page(unsigned long * table_entry) { + unsigned long old_page,new_page; + old_page = 0xfffff000 & *table_entry; + + if (old_page >= LOW_MEM && mem_map[MAP_NR(old_page)]==1) { + *table_entry |= 2; + invalidate(); + return; + } + + new_page=get_free_page(); + if (old_page >= LOW_MEM) + mem_map[MAP_NR(old_page)]--; + copy_page(old_page,new_page); + *table_entry = new_page | 7; + invalidate(); +} + +void do_wp_page(unsigned long error_code, unsigned long address) { + if (address < TASK_SIZE) + printk("\n\rBAD! KERNEL MEMORY WP-ERR!\n\r"); + + un_wp_page((unsigned long *) + (((address>>10) & 0xffc) + (0xfffff000 & + *((unsigned long *) ((address>>20) &0xffc))))); +} + void mem_init(long start_mem, long end_mem) { int i; diff --git a/mm/page.S b/mm/page.S new file mode 100644 index 0000000000000000000000000000000000000000..6f8d7a6d3bb4a33ea39124014f051ecec955fead --- /dev/null +++ b/mm/page.S @@ -0,0 +1,30 @@ +.globl page_fault + +page_fault: + xchgl %eax, (%esp) + pushl %ecx + pushl %edx + pushl %ds + pushl %es + pushl %fs + movl $0x10, %edx + movw %dx, %ds + movw %dx, %es + movw %dx, %fs + movl %cr2, %edx + pushl %edx + pushl %eax + testl $1, %eax + jne 1f + jmp 2f +1: call do_wp_page +2: addl $8, %esp + popl %fs + popl %es + popl %ds + popl %edx + popl %ecx + popl %eax + iret + +