aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Benedict Torvalds <torvalds@klaava.Helsinki.FI>1992-04-21 23:15:10 +0000
committerNicolas Pitre <nico@cam.org>2007-08-19 14:19:03 -0400
commit30cd071cd0121a1f0a965ce3a533131d55e9a1b4 (patch)
tree781ba7a0989b4cba28b08cc03f2757221360482f
parentb5de4a78ce363e94ad92d82c6ef2d6909bdd00dd (diff)
downloadarchive-30cd071cd0121a1f0a965ce3a533131d55e9a1b4.tar.gz
pre-0.96 (was Re: gdb still isn't working)v0.96-pre
In article <1992Apr20.085143.23027@klaava.Helsinki.FI> torvalds@klaava.Helsinki.FI (Linus Benedict Torvalds) writes: > [ trace not working in gdb ] > >My personal version handles this correctly (as well as doing some other >things in a cleaner manner), but I'm not quite ready for a new release >yet. I could make YAAR (yet another alpha-release) or just mail >interested parties the fixes needed - mail me if you're interested, and >depending on the number of messages I get I'll make it a new release. Ok, the response seems to make a new pre-release appropriate: I have uploaded "pre-0.96.tar.Z" to tsx-11 and nic. Here is what the pre-release contains: - truncate/ftruncate/fchmod/fchown system calls note that there aren't any library functions for these, so they aren't very useful yet... [f]truncate needed a change in the logic of the internal truncate VFS call - anybody that has any nonstandard filesystem probably needs to look it up. - io-bitmap syscalls giving root-processes access to selected io ports from user space. There is a "ioperm()" system call that lets the process select which ports it wants to enable/disable (all ports disabled as default) as well as a (standard sysv?) ioctl interface that X uses. again, no library stubs, but it allows things like reading and setting the cmos clock without using /dev/port, as well as control over the VGA registers... - mmap for /dev/mem more things needed for X... - the signal-handling fixes needed for gdb These aren't yet complete: serial lines still send signals under interrupts that can result in problems (ie ptrace doesn't correctly get them), but that's pretty unlikely (and will be fixed in the final 0.96). Breakpoints should work etc.. - multiple shared libraries Up to 6 simultaneous shared libraries/process: the patches were originally by pmacdona, but they were heavily changed by me, and I think they work in a more natural manner now. One user-level change is that the libraries are now checked for read and execute permissions for safety-reasons. - cleaned up special files. read/write/ioctl no longer has special-case code: it is all handled with tables to functions. This will mean that the SCSI patches won't patch in quite cleanly into 0.96: you'll need to add the code that sets up the functions. Again: device drivers and vfs-filesystem hackers need to look into the changes, although they are pretty logical (earlier versions just didn't implement all the vfs-routines) Note that the vfs-code for select is still not used: select is hardcoded for the devices it supports right now. - ptrace() has a new interface as gdb for versions < 0.95c don't work on the new version, and gdb won't work very well at all on 0.95c[+], there was no reason not to break ptrace. Thus 0.96 has a new calling convention for ptrace, and the old ptrace library function no longer works. I'm including the new ptrace library function at the end of this post. - mount() takes 4 arguments, and checks that only the super-user can mount/umount things. Happily this shouldn't break any old binaries. - some general cleanups I've made the pre-release available only as pure source code: no diffs, no binary. The reason is that most people that needed this release want it for the gdb-fixes: and they should have no problem recompiling the kernel. Others just have to wait for the real 0.96. Changes that are NOT in this pre-release, but which I hope to have in the real 0.96: - more include-file cleanups - I'm still working on these - the wd8003 driver and hopefully some other parts of biro's config. - select() using the vfs-tables. And possibly bugfixes that people find in this pre-release... Linus ========== library ptrace.c (wants gcc=2.1) ========== #define __LIBRARY__ #include <time.h> #include <unistd.h> int ptrace(int request, int pid, int addr, int data) { long ret; long res; if (request > 0 && request < 4) (long *)data = &ret; __asm__ volatile ("int $0x80" :"=a" (res) :"0" (__NR_ptrace),"b" (request), "c" (pid), "d" (addr), "S" (data) : "si","bx","cx","dx"); if (res >= 0) { if (request > 0 && request < 4) { errno = 0; return (ret); } return (int) res; } errno = -res; return -1; }
-rw-r--r--Makefile24
-rw-r--r--fs/Makefile163
-rw-r--r--fs/block_dev.c1
-rw-r--r--fs/buffer.c3
-rw-r--r--fs/char_dev.c198
-rw-r--r--fs/exec.c65
-rw-r--r--fs/fcntl.c2
-rw-r--r--fs/inode.c2
-rw-r--r--fs/ioctl.c36
-rw-r--r--fs/minix/Makefile71
-rw-r--r--fs/minix/bitmap.c2
-rw-r--r--fs/minix/file_dev.c44
-rw-r--r--fs/minix/inode.c2
-rw-r--r--fs/minix/minix_op.c21
-rw-r--r--fs/minix/namei.c8
-rw-r--r--fs/minix/truncate.c174
-rw-r--r--fs/namei.c6
-rw-r--r--fs/open.c127
-rw-r--r--fs/pipe.c69
-rw-r--r--fs/read_write.c43
-rw-r--r--fs/select.c17
-rw-r--r--fs/super.c22
-rw-r--r--include/asm/system.h2
-rw-r--r--include/checkpoint.h0
-rw-r--r--include/errno.h1
-rw-r--r--include/linux/config_rel.h2
-rw-r--r--include/linux/config_ver.h2
-rw-r--r--include/linux/ctype.h (renamed from include/ctype.h)0
-rw-r--r--include/linux/fs.h25
-rw-r--r--include/linux/kernel.h1
-rw-r--r--include/linux/lp.h5
-rw-r--r--include/linux/minix_fs.h24
-rw-r--r--include/linux/sched.h81
-rw-r--r--include/linux/string.h (renamed from include/string.h)0
-rw-r--r--include/linux/sys.h23
-rw-r--r--include/linux/tty.h18
-rw-r--r--include/sys/kd.h179
-rw-r--r--include/sys/mman.h18
-rw-r--r--include/sys/stat.h2
-rw-r--r--include/sys/types.h2
-rw-r--r--include/sys/vfs.h20
-rw-r--r--include/sys/vt.h32
-rw-r--r--include/unistd.h228
-rw-r--r--init/main.c11
-rw-r--r--kernel/Makefile108
-rw-r--r--kernel/asm.s182
-rw-r--r--kernel/blk_drv/Makefile55
-rw-r--r--kernel/blk_drv/floppy.c11
-rw-r--r--kernel/blk_drv/hd.c44
-rw-r--r--kernel/blk_drv/ll_rw_blk.c2
-rw-r--r--kernel/blk_drv/ramdisk.c13
-rw-r--r--kernel/chr_drv/Makefile100
-rw-r--r--kernel/chr_drv/console.c22
-rw-r--r--kernel/chr_drv/keyboard.S63
-rw-r--r--kernel/chr_drv/lp.c125
-rw-r--r--kernel/chr_drv/mem.c238
-rw-r--r--kernel/chr_drv/pty.c3
-rw-r--r--kernel/chr_drv/serial.c3
-rw-r--r--kernel/chr_drv/tty_io.c61
-rw-r--r--kernel/chr_drv/tty_ioctl.c12
-rw-r--r--kernel/chr_drv/vt.c170
-rw-r--r--kernel/chr_drv/vt_kern.h8
-rw-r--r--kernel/exit.c6
-rw-r--r--kernel/fork.c29
-rw-r--r--kernel/ioport.c94
-rw-r--r--kernel/math/Makefile79
-rw-r--r--kernel/ptrace.c10
-rw-r--r--kernel/sched.c9
-rw-r--r--kernel/sys.c20
-rw-r--r--kernel/sys_call.S369
-rw-r--r--kernel/sys_call.s320
-rw-r--r--kernel/traps.c2
-rw-r--r--kernel/vsprintf.c2
-rw-r--r--lib/Makefile57
-rw-r--r--lib/ctype.c2
-rw-r--r--lib/string.c2
-rw-r--r--mm/Makefile25
-rw-r--r--mm/memory.c184
-rw-r--r--mm/mmap.c196
-rw-r--r--mm/swap.c21
80 files changed, 2863 insertions, 1560 deletions
diff --git a/Makefile b/Makefile
index 59d5f66..dc83ace 100644
--- a/Makefile
+++ b/Makefile
@@ -8,8 +8,8 @@ MATH_EMULATION = -DKERNEL_MATH_EMULATION
# uncomment the correct keyboard:
#
-# KEYBOARD = -DKBD_FINNISH
-KEYBOARD = -DKBD_US
+KEYBOARD = -DKBD_FINNISH
+# KEYBOARD = -DKBD_US
# KEYBOARD = -DKBD_GR
# KEYBOARD = -DKBD_FR
# KEYBOARD = -DKBD_UK
@@ -32,7 +32,7 @@ CFLAGS =-Wall -O6 -fomit-frame-pointer $(GCC_OPT)
# default of FLOPPY is used by 'build'.
#
-# ROOT_DEV = /dev/hdb1
+ROOT_DEV = /dev/hdb1
#
# if you want the ram-disk device, define this to be the
@@ -86,7 +86,7 @@ disk: Image
dd bs=8192 if=Image of=/dev/PS0
tools/build: tools/build.c
- $(CC) $(CFLAGS) \
+ $(CC) -static $(CFLAGS) \
-o tools/build tools/build.c
boot/head.o: boot/head.s
@@ -159,15 +159,15 @@ dep:
(cd fs; make dep)
(cd kernel; make dep)
(cd mm; make dep)
+ (cd lib; make dep)
dummy:
### Dependencies:
-init/main.o : init/main.c include/unistd.h include/sys/stat.h \
- include/sys/types.h include/sys/time.h include/time.h include/sys/times.h \
- include/sys/utsname.h include/sys/param.h include/sys/resource.h \
- include/utime.h include/linux/tty.h include/termios.h include/linux/sched.h \
- include/linux/head.h include/linux/fs.h include/sys/dirent.h \
- include/limits.h include/linux/mm.h include/linux/kernel.h include/signal.h \
- include/asm/system.h include/asm/io.h include/stddef.h include/stdarg.h \
- include/fcntl.h include/string.h
+init/main.o : init/main.c include/unistd.h include/sys/stat.h include/sys/types.h \
+ include/sys/time.h include/time.h include/sys/times.h include/sys/utsname.h \
+ include/sys/param.h include/sys/resource.h include/utime.h include/linux/sched.h \
+ include/linux/head.h include/linux/fs.h include/sys/dirent.h include/limits.h \
+ include/linux/mm.h include/linux/kernel.h include/signal.h include/linux/tty.h \
+ include/termios.h include/linux/string.h include/asm/system.h include/asm/io.h \
+ include/stddef.h include/stdarg.h include/fcntl.h
diff --git a/fs/Makefile b/fs/Makefile
index 312f2f6..602e09f 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -23,8 +23,8 @@ CPP =cpp -nostdinc -I../include
$(AS) -o $*.o $<
OBJS= open.o read_write.o inode.o file_table.o buffer.o super.o \
- block_dev.o char_dev.o stat.o exec.o pipe.o namei.o \
- fcntl.o ioctl.o select.o
+ block_dev.o stat.o exec.o pipe.o namei.o fcntl.o ioctl.o \
+ select.o
fs.o: $(OBJS)
$(LD) -r -o fs.o $(OBJS)
@@ -41,97 +41,74 @@ dep:
cd minix; make dep
### Dependencies:
-block_dev.o : block_dev.c ../include/errno.h ../include/linux/sched.h \
- ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h \
- ../include/sys/dirent.h ../include/limits.h ../include/linux/mm.h \
- ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h \
- ../include/sys/time.h ../include/time.h ../include/sys/resource.h \
- ../include/asm/segment.h ../include/asm/system.h
-buffer.o : buffer.c ../include/stdarg.h ../include/linux/config.h \
- ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \
- ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h \
- ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h \
- ../include/sys/param.h ../include/sys/time.h ../include/time.h \
- ../include/sys/resource.h ../include/asm/system.h ../include/asm/io.h
-char_dev.o : char_dev.c ../include/errno.h ../include/sys/types.h \
- ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \
- ../include/sys/dirent.h ../include/limits.h ../include/linux/mm.h \
- ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h \
- ../include/sys/time.h ../include/time.h ../include/sys/resource.h \
- ../include/asm/segment.h ../include/asm/io.h
-exec.o : exec.c ../include/signal.h ../include/sys/types.h \
- ../include/errno.h ../include/string.h ../include/sys/stat.h \
- ../include/a.out.h ../include/linux/fs.h ../include/sys/dirent.h \
- ../include/limits.h ../include/linux/sched.h ../include/linux/head.h \
- ../include/linux/mm.h ../include/linux/kernel.h ../include/sys/param.h \
- ../include/sys/time.h ../include/time.h ../include/sys/resource.h \
+block_dev.o : block_dev.c ../include/errno.h ../include/linux/sched.h ../include/linux/head.h \
+ ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h \
+ ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h \
+ ../include/sys/time.h ../include/time.h ../include/sys/resource.h ../include/asm/segment.h \
+ ../include/asm/system.h
+buffer.o : buffer.c ../include/stdarg.h ../include/linux/config.h ../include/linux/config_rel.h \
+ ../include/linux/config_ver.h ../include/linux/sched.h ../include/linux/head.h \
+ ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h \
+ ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h \
+ ../include/sys/time.h ../include/time.h ../include/sys/resource.h ../include/asm/system.h \
+ ../include/asm/io.h
+exec.o : exec.c ../include/signal.h ../include/sys/types.h ../include/errno.h \
+ ../include/linux/string.h ../include/sys/stat.h ../include/a.out.h ../include/linux/fs.h \
+ ../include/sys/dirent.h ../include/limits.h ../include/linux/sched.h ../include/linux/head.h \
+ ../include/linux/mm.h ../include/linux/kernel.h ../include/sys/param.h ../include/sys/time.h \
+ ../include/time.h ../include/sys/resource.h ../include/asm/segment.h
+fcntl.o : fcntl.c ../include/linux/string.h ../include/errno.h ../include/linux/sched.h \
+ ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h \
+ ../include/limits.h ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h \
+ ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h \
+ ../include/asm/segment.h ../include/fcntl.h ../include/sys/stat.h
+file_table.o : file_table.c ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h \
+ ../include/limits.h
+inode.o : inode.c ../include/linux/string.h ../include/sys/stat.h ../include/sys/types.h \
+ ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h ../include/sys/dirent.h \
+ ../include/limits.h ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h \
+ ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h \
+ ../include/asm/system.h
+ioctl.o : ioctl.c ../include/linux/string.h ../include/errno.h ../include/sys/stat.h \
+ ../include/sys/types.h ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \
+ ../include/sys/dirent.h ../include/limits.h ../include/linux/mm.h ../include/linux/kernel.h \
+ ../include/signal.h ../include/sys/param.h ../include/sys/time.h ../include/time.h \
+ ../include/sys/resource.h
+namei.o : namei.c ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \
+ ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h ../include/linux/mm.h \
+ ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h ../include/sys/time.h \
+ ../include/time.h ../include/sys/resource.h ../include/asm/segment.h ../include/linux/string.h \
+ ../include/fcntl.h ../include/errno.h ../include/const.h ../include/sys/stat.h
+open.o : open.c ../include/errno.h ../include/fcntl.h ../include/sys/types.h \
+ ../include/utime.h ../include/sys/stat.h ../include/sys/vfs.h ../include/linux/string.h \
+ ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h ../include/sys/dirent.h \
+ ../include/limits.h ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h \
+ ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h \
../include/asm/segment.h
-fcntl.o : fcntl.c ../include/string.h ../include/errno.h \
- ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \
- ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h \
- ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h \
- ../include/sys/param.h ../include/sys/time.h ../include/time.h \
- ../include/sys/resource.h ../include/asm/segment.h ../include/fcntl.h \
- ../include/sys/stat.h
-file_table.o : file_table.c ../include/linux/fs.h ../include/sys/types.h \
- ../include/sys/dirent.h ../include/limits.h
-inode.o : inode.c ../include/string.h ../include/sys/stat.h \
- ../include/sys/types.h ../include/linux/sched.h ../include/linux/head.h \
- ../include/linux/fs.h ../include/sys/dirent.h ../include/limits.h \
- ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h \
- ../include/sys/param.h ../include/sys/time.h ../include/time.h \
- ../include/sys/resource.h ../include/asm/system.h
-ioctl.o : ioctl.c ../include/string.h ../include/errno.h \
- ../include/sys/stat.h ../include/sys/types.h ../include/linux/sched.h \
- ../include/linux/head.h ../include/linux/fs.h ../include/sys/dirent.h \
- ../include/limits.h ../include/linux/mm.h ../include/linux/kernel.h \
- ../include/signal.h ../include/sys/param.h ../include/sys/time.h \
+pipe.o : pipe.c ../include/signal.h ../include/sys/types.h ../include/errno.h \
+ ../include/termios.h ../include/fcntl.h ../include/asm/segment.h ../include/linux/sched.h \
+ ../include/linux/head.h ../include/linux/fs.h ../include/sys/dirent.h ../include/limits.h \
+ ../include/linux/mm.h ../include/linux/kernel.h ../include/sys/param.h ../include/sys/time.h \
../include/time.h ../include/sys/resource.h
-namei.o : namei.c ../include/linux/sched.h ../include/linux/head.h \
- ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h \
- ../include/limits.h ../include/linux/mm.h ../include/linux/kernel.h \
- ../include/signal.h ../include/sys/param.h ../include/sys/time.h \
- ../include/time.h ../include/sys/resource.h ../include/asm/segment.h \
- ../include/string.h ../include/fcntl.h ../include/errno.h \
- ../include/const.h ../include/sys/stat.h
-open.o : open.c ../include/string.h ../include/errno.h ../include/fcntl.h \
- ../include/sys/types.h ../include/utime.h ../include/sys/stat.h \
- ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \
- ../include/sys/dirent.h ../include/limits.h ../include/linux/mm.h \
- ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h \
- ../include/sys/time.h ../include/time.h ../include/sys/resource.h \
- ../include/asm/segment.h
-pipe.o : pipe.c ../include/signal.h ../include/sys/types.h \
- ../include/errno.h ../include/termios.h ../include/fcntl.h \
- ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \
- ../include/sys/dirent.h ../include/limits.h ../include/linux/mm.h \
- ../include/linux/kernel.h ../include/sys/param.h ../include/sys/time.h \
- ../include/time.h ../include/sys/resource.h ../include/asm/segment.h
-read_write.o : read_write.c ../include/errno.h ../include/sys/types.h \
- ../include/sys/stat.h ../include/sys/dirent.h ../include/limits.h \
- ../include/linux/kernel.h ../include/linux/sched.h ../include/linux/head.h \
- ../include/linux/fs.h ../include/linux/mm.h ../include/signal.h \
- ../include/sys/param.h ../include/sys/time.h ../include/time.h \
- ../include/sys/resource.h ../include/linux/minix_fs.h \
+read_write.o : read_write.c ../include/errno.h ../include/sys/types.h ../include/sys/stat.h \
+ ../include/sys/dirent.h ../include/limits.h ../include/linux/kernel.h ../include/linux/sched.h \
+ ../include/linux/head.h ../include/linux/fs.h ../include/linux/mm.h ../include/signal.h \
+ ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h \
+ ../include/linux/minix_fs.h ../include/asm/segment.h
+select.o : select.c ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h \
+ ../include/limits.h ../include/linux/kernel.h ../include/linux/tty.h ../include/termios.h \
+ ../include/linux/sched.h ../include/linux/head.h ../include/linux/mm.h ../include/signal.h \
+ ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h \
+ ../include/linux/string.h ../include/asm/segment.h ../include/asm/system.h ../include/sys/stat.h \
+ ../include/const.h ../include/errno.h
+stat.o : stat.c ../include/errno.h ../include/sys/stat.h ../include/sys/types.h \
+ ../include/linux/fs.h ../include/sys/dirent.h ../include/limits.h ../include/linux/sched.h \
+ ../include/linux/head.h ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h \
+ ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h \
../include/asm/segment.h
-select.o : select.c ../include/linux/fs.h ../include/sys/types.h \
- ../include/sys/dirent.h ../include/limits.h ../include/linux/kernel.h \
- ../include/linux/tty.h ../include/termios.h ../include/linux/sched.h \
- ../include/linux/head.h ../include/linux/mm.h ../include/signal.h \
- ../include/sys/param.h ../include/sys/time.h ../include/time.h \
- ../include/sys/resource.h ../include/asm/segment.h ../include/asm/system.h \
- ../include/sys/stat.h ../include/string.h ../include/const.h \
- ../include/errno.h
-stat.o : stat.c ../include/errno.h ../include/sys/stat.h \
- ../include/sys/types.h ../include/linux/fs.h ../include/sys/dirent.h \
- ../include/limits.h ../include/linux/sched.h ../include/linux/head.h \
- ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h \
- ../include/sys/param.h ../include/sys/time.h ../include/time.h \
- ../include/sys/resource.h ../include/asm/segment.h
-super.o : super.c ../include/linux/config.h ../include/linux/sched.h \
- ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h \
- ../include/sys/dirent.h ../include/limits.h ../include/linux/mm.h \
- ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h \
- ../include/sys/time.h ../include/time.h ../include/sys/resource.h \
- ../include/linux/minix_fs.h ../include/asm/system.h ../include/errno.h \
- ../include/sys/stat.h
+super.o : super.c ../include/linux/config.h ../include/linux/config_rel.h ../include/linux/config_ver.h \
+ ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h \
+ ../include/sys/dirent.h ../include/limits.h ../include/linux/mm.h ../include/linux/kernel.h \
+ ../include/signal.h ../include/sys/param.h ../include/sys/time.h ../include/time.h \
+ ../include/sys/resource.h ../include/linux/minix_fs.h ../include/asm/system.h \
+ ../include/asm/segment.h ../include/errno.h ../include/sys/stat.h
diff --git a/fs/block_dev.c b/fs/block_dev.c
index cca44d3..c102c94 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -50,6 +50,7 @@ int block_write(struct inode * inode, struct file * filp, char * buf, int count)
memcpy_fromfs(p,buf,chars);
p += chars;
buf += chars;
+ bh->b_uptodate = 1;
bh->b_dirt = 1;
brelse(bh);
}
diff --git a/fs/buffer.c b/fs/buffer.c
index 54fa805..4b80848 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -200,7 +200,8 @@ static inline void insert_into_queues(struct buffer_head * bh)
return;
bh->b_next = hash(bh->b_dev,bh->b_blocknr);
hash(bh->b_dev,bh->b_blocknr) = bh;
- bh->b_next->b_prev = bh;
+ if (bh->b_next)
+ bh->b_next->b_prev = bh;
}
static struct buffer_head * find_buffer(int dev, int block)
diff --git a/fs/char_dev.c b/fs/char_dev.c
deleted file mode 100644
index 081b18e..0000000
--- a/fs/char_dev.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * linux/fs/char_dev.c
- *
- * (C) 1991 Linus Torvalds
- */
-
-#include <errno.h>
-#include <sys/types.h>
-
-#include <linux/sched.h>
-#include <linux/kernel.h>
-
-#include <checkpoint.h>
-#include <asm/segment.h>
-#include <asm/io.h>
-
-extern int tty_read(unsigned minor,char * buf,int count,unsigned short flags);
-extern int tty_write(unsigned minor,char * buf,int count);
-extern int lp_write(unsigned minor,char *buf, int count);
-
-typedef (*crw_ptr)(int,unsigned,char *,int,off_t *,unsigned short);
-
-static int rw_ttyx(int rw,unsigned minor,char * buf,int count,off_t * pos, unsigned short flags)
-{
- return ((rw==READ)?tty_read(minor,buf,count,flags):
- tty_write(minor,buf,count));
-}
-
-static int rw_lp(int rw,unsigned minor,char * buf,int count,off_t * pos, unsigned short flags)
-{
- return ((rw==READ)?-EINVAL:lp_write(minor,buf,count));
-}
-
-static int rw_tty(int rw,unsigned minor,char * buf,int count, off_t * pos, unsigned short flags)
-{
- if (current->tty<0)
- return -EPERM;
- return rw_ttyx(rw,current->tty,buf,count,pos,flags);
-}
-
-static int rw_ram(int rw,char * buf, int count, off_t *pos)
-{
- return -EIO;
-}
-
-static int rw_mem(int rw,char * buf, int count, off_t * pos)
-{
- char *p;
- unsigned long pde, pte, tmp;
- int i = count;
-
- if (count <= 0)
- return(0);
- /*
- * return EOF on nonexistant pages or pages swapped out to disk
- */
- pde = (unsigned long) pg_dir + (*pos >> 20 & 0xffc);
- if (((pte = *((unsigned long *) pde)) & 1) == 0)
- return 0; /* page table not present */
- pte &= 0xfffff000;
- pte += *pos >> 10 & 0xffc;
- if (((tmp = *((unsigned long *) pte)) & 1) == 0)
- return 0;
- if (rw == WRITE && (tmp & 2) == 0)
- un_wp_page((unsigned long *) pte);
- p = (char *) ((tmp & 0xfffff000) + (*pos & 0xfff));
- while (1) {
- if (rw == WRITE)
- *p++ = get_fs_byte(buf++);
- else
- put_fs_byte(*p++, buf++);
-
- if (--i == 0)
- break;
-
- if (count && ((unsigned long) p & 0xfff) == 0) {
- if (((pte += 4) & 0xfff) == 0) {
- if (((pde += 4) & 0xfff) == 0)
- break;
- if (((pte = *((unsigned long *) pde)) & 1) == 0)
- break;
- pte &= 0xfffff000;
- }
- if (((tmp = *((unsigned long *) pte)) & 1) == 0)
- break;
-
- if (rw == WRITE && (tmp & 2) == 0)
- un_wp_page((unsigned long *) pte);
- p = (char *) (tmp & 0xfffff000);
- }
- }
- return(count - i);
-}
-
-static int rw_kmem(int rw,char * buf, int count, off_t * pos)
-{
- char *p=(char *) *pos;
-
- if ((unsigned long) *pos > HIGH_MEMORY)
- return 0;
- if ((unsigned long) *pos + count > HIGH_MEMORY)
- count = HIGH_MEMORY - *pos;
-
- switch (rw) {
- case READ:
- while ((count -= 4) >= 0)
- put_fs_long(*((unsigned long *) p)++,
- ((unsigned long *) buf)++);
- count += 4;
- while (--count >= 0)
- put_fs_byte(*p++, buf++);
- break;
- case WRITE:
- while (--count >= 0)
- *p++ = get_fs_byte(buf++);
- break;
- default:
- return -EINVAL;
- }
- p -= *pos;
- *pos += (int) p;
- return (int) p;
-}
-
-static int rw_port(int rw,char * buf, int count, off_t * pos)
-{
- int i=*pos;
-
- while (count-->0 && i<65536) {
- if (rw==READ)
- put_fs_byte(inb(i),buf++);
- else
- outb(get_fs_byte(buf++),i);
- i++;
- }
- i -= *pos;
- *pos += i;
- return i;
-}
-
-static int rw_memory(int rw, unsigned minor, char * buf, int count,
- off_t * pos, unsigned short flags)
-{
- switch(minor) {
- case 0:
- return rw_ram(rw,buf,count,pos);
- case 1:
- return rw_mem(rw,buf,count,pos);
- case 2:
- return rw_kmem(rw,buf,count,pos);
- case 3:
- return (rw==READ)?0:count; /* rw_null */
- case 4:
- return rw_port(rw,buf,count,pos);
- default:
- return -EIO;
- }
-}
-
-#define NRDEVS ((sizeof (crw_table))/(sizeof (crw_ptr)))
-
-static crw_ptr crw_table[]={
- NULL, /* nodev */
- rw_memory, /* /dev/mem etc */
- NULL, /* /dev/fd */
- NULL, /* /dev/hd */
- rw_ttyx, /* /dev/ttyx */
- rw_tty, /* /dev/tty */
- rw_lp, /* /dev/lp */
- NULL}; /* unnamed pipes */
-
-int char_read(struct inode * inode, struct file * filp, char * buf, int count)
-{
- unsigned int major,minor;
- crw_ptr call_addr;
-
- major = MAJOR(inode->i_rdev);
- minor = MINOR(inode->i_rdev);
- if (major >= NRDEVS)
- return -ENODEV;
- if (!(call_addr = crw_table[major]))
- return -ENODEV;
- return call_addr(READ,minor,buf,count,&filp->f_pos,filp->f_flags);
-}
-
-int char_write(struct inode * inode, struct file * filp, char * buf, int count)
-{
- unsigned int major,minor;
- crw_ptr call_addr;
-
- major = MAJOR(inode->i_rdev);
- minor = MINOR(inode->i_rdev);
- if (major >= NRDEVS)
- return -ENODEV;
- if (!(call_addr=crw_table[major]))
- return -ENODEV;
- return call_addr(WRITE,minor,buf,count,&filp->f_pos,filp->f_flags);
-}
diff --git a/fs/exec.c b/fs/exec.c
index f27b51f..cb7b2ba 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -19,7 +19,7 @@
#include <signal.h>
#include <errno.h>
-#include <string.h>
+#include <linux/string.h>
#include <sys/stat.h>
#include <a.out.h>
@@ -39,26 +39,57 @@ extern int sys_close(int fd);
*/
#define MAX_ARG_PAGES 32
+/*
+ * Note that a shared library must be both readable and executable due to
+ * security reasons.
+ *
+ * Also note that we take the address to load from from the file itself.
+ */
int sys_uselib(const char * library)
{
+#define libnum (current->numlibraries)
struct inode * inode;
- unsigned long base;
+ struct buffer_head * bh;
+ struct exec ex;
if (get_limit(0x17) != TASK_SIZE)
return -EINVAL;
- if (library) {
- if (!(inode=namei(library))) /* get library inode */
- return -ENOENT;
- } else
+ if ((libnum >= MAX_SHARED_LIBS) || (libnum < 0))
+ return -EINVAL;
+ if (library)
+ inode = namei(library);
+ else
inode = NULL;
-/* we should check filetypes (headers etc), but we don't */
- iput(current->library);
- current->library = NULL;
- base = get_base(current->ldt[2]);
- base += LIBRARY_OFFSET;
- free_page_tables(base,LIBRARY_SIZE);
- current->library = inode;
+ if (!inode)
+ return -ENOENT;
+ if (!S_ISREG(inode->i_mode) || !permission(inode,MAY_READ|MAY_EXEC)) {
+ iput(inode);
+ return -EACCES;
+ }
+ if (!(bh = bread(inode->i_dev,inode->i_data[0]))) {
+ iput(inode);
+ return -EACCES;
+ }
+ ex = *(struct exec *) bh->b_data;
+ brelse(bh);
+ if (N_MAGIC(ex) != ZMAGIC || ex.a_trsize || ex.a_drsize ||
+ ex.a_text+ex.a_data+ex.a_bss>0x3000000 ||
+ inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) {
+ iput(inode);
+ return -ENOEXEC;
+ }
+ current->libraries[libnum].library = inode;
+ current->libraries[libnum].start = ex.a_entry;
+ current->libraries[libnum].length = (ex.a_data+ex.a_text+0xfff) & 0xfffff000;
+#if 0
+ printk("Loaded library %d at %08x, length %08x\n",
+ libnum,
+ current->libraries[libnum].start,
+ current->libraries[libnum].length);
+#endif
+ libnum++;
return 0;
+#undef libnum
}
/*
@@ -348,7 +379,6 @@ restart_interp:
}
}
/* OK, This is the point of no return */
-/* note that current->library stays unchanged by an exec */
for (i=0; (ch = get_fs_byte(filename++)) != '\0';)
if (ch == '/')
i = 0;
@@ -357,9 +387,14 @@ restart_interp:
current->comm[i++] = ch;
if (i < 8)
current->comm[i] = '\0';
-
if (current->executable)
iput(current->executable);
+ i = current->numlibraries;
+ while (i-- > 0) {
+ iput(current->libraries[i].library);
+ current->libraries[i].library = NULL;
+ }
+ current->numlibraries = 0;
current->executable = inode;
current->signal = 0;
for (i=0 ; i<32 ; i++) {
diff --git a/fs/fcntl.c b/fs/fcntl.c
index ab7fe1f..9658483 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -4,7 +4,7 @@
* (C) 1991 Linus Torvalds
*/
-#include <string.h>
+#include <linux/string.h>
#include <errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
diff --git a/fs/inode.c b/fs/inode.c
index c1634d8..385f2f9 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -4,7 +4,7 @@
* (C) 1991 Linus Torvalds
*/
-#include <string.h>
+#include <linux/string.h>
#include <sys/stat.h>
#include <linux/sched.h>
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 284a0dc..7b28116 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -4,47 +4,19 @@
* (C) 1991 Linus Torvalds
*/
-#include <string.h>
+#include <linux/string.h>
#include <errno.h>
#include <sys/stat.h>
#include <linux/sched.h>
-extern int hd_ioctl(int dev, int cmd, int arg);
-extern int tty_ioctl(int dev, int cmd, int arg);
-extern int pipe_ioctl(struct inode *pino, int cmd, int arg);
-
-typedef int (*ioctl_ptr)(int dev,int cmd,int arg);
-
-#define NRDEVS ((sizeof (ioctl_table))/(sizeof (ioctl_ptr)))
-
-static ioctl_ptr ioctl_table[]={
- NULL, /* nodev */
- NULL, /* /dev/mem */
- NULL, /* /dev/fd */
- hd_ioctl, /* /dev/hd */
- tty_ioctl, /* /dev/ttyx */
- tty_ioctl, /* /dev/tty */
- NULL, /* /dev/lp */
- NULL}; /* named pipes */
-
-
int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
struct file * filp;
- int dev,mode;
if (fd >= NR_OPEN || !(filp = current->filp[fd]))
return -EBADF;
- if (filp->f_inode->i_pipe)
- return (filp->f_mode&1)?pipe_ioctl(filp->f_inode,cmd,arg):-EBADF;
- mode=filp->f_inode->i_mode;
- if (!S_ISCHR(mode) && !S_ISBLK(mode))
- return -EINVAL;
- dev = filp->f_inode->i_rdev;
- if (MAJOR(dev) >= NRDEVS)
- return -ENODEV;
- if (!ioctl_table[MAJOR(dev)])
- return -ENOTTY;
- return ioctl_table[MAJOR(dev)](dev,cmd,arg);
+ if (filp->f_op && filp->f_op->ioctl)
+ return filp->f_op->ioctl(filp->f_inode, filp, cmd,arg);
+ return -EINVAL;
}
diff --git a/fs/minix/Makefile b/fs/minix/Makefile
index fd1a331..81aebc7 100644
--- a/fs/minix/Makefile
+++ b/fs/minix/Makefile
@@ -37,46 +37,33 @@ dep:
cp tmp_make Makefile
### Dependencies:
-bitmap.o : bitmap.c ../../include/string.h ../../include/linux/sched.h \
- ../../include/linux/head.h ../../include/linux/fs.h \
+bitmap.o : bitmap.c ../../include/linux/string.h ../../include/linux/sched.h \
+ ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/types.h \
+ ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \
+ ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
+ ../../include/sys/resource.h ../../include/linux/minix_fs.h
+file_dev.o : file_dev.c ../../include/errno.h ../../include/fcntl.h ../../include/sys/types.h \
+ ../../include/sys/dirent.h ../../include/limits.h ../../include/sys/stat.h ../../include/linux/sched.h \
+ ../../include/linux/head.h ../../include/linux/fs.h ../../include/linux/mm.h \
+ ../../include/linux/kernel.h ../../include/signal.h ../../include/sys/param.h \
+ ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h ../../include/linux/minix_fs.h \
+ ../../include/asm/segment.h
+inode.o : inode.c ../../include/linux/string.h ../../include/sys/stat.h ../../include/sys/types.h \
+ ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \
+ ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \
+ ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
+ ../../include/sys/resource.h ../../include/linux/minix_fs.h ../../include/asm/system.h
+minix_op.o : minix_op.c ../../include/linux/fs.h ../../include/sys/types.h ../../include/sys/dirent.h \
+ ../../include/limits.h ../../include/linux/minix_fs.h
+namei.o : namei.c ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \
../../include/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \
- ../../include/linux/mm.h ../../include/linux/kernel.h \
- ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h \
- ../../include/time.h ../../include/sys/resource.h \
- ../../include/linux/minix_fs.h
-file_dev.o : file_dev.c ../../include/errno.h ../../include/fcntl.h \
- ../../include/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \
- ../../include/sys/stat.h ../../include/linux/sched.h \
- ../../include/linux/head.h ../../include/linux/fs.h \
- ../../include/linux/mm.h ../../include/linux/kernel.h \
- ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h \
- ../../include/time.h ../../include/sys/resource.h \
- ../../include/linux/minix_fs.h ../../include/asm/segment.h
-inode.o : inode.c ../../include/string.h ../../include/sys/stat.h \
- ../../include/sys/types.h ../../include/linux/sched.h \
- ../../include/linux/head.h ../../include/linux/fs.h \
- ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h \
- ../../include/linux/kernel.h ../../include/signal.h \
- ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
- ../../include/sys/resource.h ../../include/linux/minix_fs.h \
- ../../include/asm/system.h
-minix_op.o : minix_op.c ../../include/linux/fs.h ../../include/sys/types.h \
- ../../include/sys/dirent.h ../../include/limits.h \
- ../../include/linux/minix_fs.h
-namei.o : namei.c ../../include/linux/sched.h ../../include/linux/head.h \
- ../../include/linux/fs.h ../../include/sys/types.h \
- ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h \
- ../../include/linux/kernel.h ../../include/signal.h \
- ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
- ../../include/sys/resource.h ../../include/linux/minix_fs.h \
- ../../include/asm/segment.h ../../include/string.h ../../include/fcntl.h \
- ../../include/errno.h ../../include/const.h ../../include/sys/stat.h
-truncate.o : truncate.c ../../include/linux/sched.h \
- ../../include/linux/head.h ../../include/linux/fs.h \
- ../../include/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \
- ../../include/linux/mm.h ../../include/linux/kernel.h \
- ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h \
- ../../include/time.h ../../include/sys/resource.h \
- ../../include/linux/minix_fs.h ../../include/linux/tty.h \
- ../../include/termios.h ../../include/errno.h ../../include/fcntl.h \
- ../../include/sys/stat.h
+ ../../include/linux/mm.h ../../include/linux/kernel.h ../../include/signal.h \
+ ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h \
+ ../../include/linux/minix_fs.h ../../include/asm/segment.h ../../include/linux/string.h \
+ ../../include/fcntl.h ../../include/errno.h ../../include/const.h ../../include/sys/stat.h
+truncate.o : truncate.c ../../include/linux/sched.h ../../include/linux/head.h \
+ ../../include/linux/fs.h ../../include/sys/types.h ../../include/sys/dirent.h \
+ ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \
+ ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
+ ../../include/sys/resource.h ../../include/linux/minix_fs.h ../../include/linux/tty.h \
+ ../../include/termios.h ../../include/errno.h ../../include/fcntl.h ../../include/sys/stat.h
diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c
index 645db74..6a3ead3 100644
--- a/fs/minix/bitmap.c
+++ b/fs/minix/bitmap.c
@@ -5,7 +5,7 @@
*/
/* bitmap.c contains the code that handles the inode and block bitmaps */
-#include <string.h>
+#include <linux/string.h>
#include <linux/sched.h>
#include <linux/minix_fs.h>
diff --git a/fs/minix/file_dev.c b/fs/minix/file_dev.c
index 91995d9..2ae0705 100644
--- a/fs/minix/file_dev.c
+++ b/fs/minix/file_dev.c
@@ -17,16 +17,16 @@
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
-int minix_readdir(struct inode * inode, struct file * filp, struct dirent * dirent)
+int minix_readdir(struct inode * inode, struct file * filp, struct dirent * dirent, int count)
{
unsigned int block,offset,i;
char c;
struct buffer_head * bh;
struct minix_dir_entry * de;
- if (!S_ISDIR(inode->i_mode))
+ if (!inode || !S_ISDIR(inode->i_mode))
return -EBADF;
- if (filp->f_pos & 15)
+ if (filp->f_pos & (sizeof (struct minix_dir_entry) - 1))
return -EBADF;
while (filp->f_pos < inode->i_size) {
offset = filp->f_pos & 1023;
@@ -37,10 +37,10 @@ int minix_readdir(struct inode * inode, struct file * filp, struct dirent * dire
}
de = (struct minix_dir_entry *) (offset + bh->b_data);
while (offset < 1024 && filp->f_pos < inode->i_size) {
- offset += 16;
- filp->f_pos += 16;
+ offset += sizeof (struct minix_dir_entry);
+ filp->f_pos += sizeof (struct minix_dir_entry);
if (de->inode) {
- for (i = 0; i < 14; i++)
+ for (i = 0; i < MINIX_NAME_LEN; i++)
if (c = de->name[i])
put_fs_byte(c,i+dirent->d_name);
else
@@ -65,6 +65,14 @@ int minix_file_read(struct inode * inode, struct file * filp, char * buf, int co
int read,left,chars,nr;
struct buffer_head * bh;
+ if (!inode) {
+ printk("minix_file_read: inode = NULL\n");
+ return -EINVAL;
+ }
+ if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
+ printk("minix_file_read: mode = %07o\n",inode->i_mode);
+ return -EINVAL;
+ }
if (filp->f_pos > inode->i_size)
left = 0;
else
@@ -103,6 +111,14 @@ int minix_file_write(struct inode * inode, struct file * filp, char * buf, int c
struct buffer_head * bh;
char * p;
+ if (!inode) {
+ printk("minix_file_write: inode = NULL\n");
+ return -EINVAL;
+ }
+ if (!S_ISREG(inode->i_mode)) {
+ printk("minix_file_write: mode = %07o\n",inode->i_mode);
+ return -EINVAL;
+ }
/*
* ok, append may not work when many processes are writing at the same time
* but so what. That way leads to madness anyway.
@@ -118,16 +134,19 @@ int minix_file_write(struct inode * inode, struct file * filp, char * buf, int c
written = -ENOSPC;
break;
}
- if (!(bh=bread(inode->i_dev,block))) {
+ c = BLOCK_SIZE - (pos % BLOCK_SIZE);
+ if (c > count-written)
+ c = count-written;
+ if (c == BLOCK_SIZE)
+ bh = getblk(inode->i_dev, block);
+ else
+ bh = bread(inode->i_dev,block);
+ if (!bh) {
if (!written)
written = -EIO;
break;
}
- c = pos % BLOCK_SIZE;
- p = c + bh->b_data;
- c = BLOCK_SIZE-c;
- if (c > count-written)
- c = count-written;
+ p = (pos % BLOCK_SIZE) + bh->b_data;
pos += c;
if (pos > inode->i_size) {
inode->i_size = pos;
@@ -136,6 +155,7 @@ int minix_file_write(struct inode * inode, struct file * filp, char * buf, int c
written += c;
memcpy_fromfs(p,buf,c);
buf += c;
+ bh->b_uptodate = 1;
bh->b_dirt = 1;
brelse(bh);
}
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index 75ec7a2..c635e6e 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -4,7 +4,7 @@
* (C) 1991 Linus Torvalds
*/
-#include <string.h>
+#include <linux/string.h>
#include <sys/stat.h>
#include <linux/sched.h>
diff --git a/fs/minix/minix_op.c b/fs/minix/minix_op.c
index 7fd5559..a588f09 100644
--- a/fs/minix/minix_op.c
+++ b/fs/minix/minix_op.c
@@ -9,6 +9,7 @@
void minix_put_inode(struct inode *inode)
{
+ inode->i_size = 0;
minix_truncate(inode);
minix_free_inode(inode);
}
@@ -41,9 +42,21 @@ struct inode_operations minix_inode_operations = {
* the minix filesystem.
*/
struct file_operations minix_file_operations = {
- NULL, /* lseek */
- NULL, /* read */
- NULL, /* write */
- minix_readdir
+ NULL, /* lseek - default */
+ minix_file_read, /* read */
+ minix_file_write, /* write */
+ NULL, /* readdir - bad */
+ NULL, /* close - default */
+ NULL, /* select - default */
+ NULL /* ioctl - default */
};
+struct file_operations minix_dir_operations = {
+ NULL, /* lseek - default */
+ minix_file_read, /* read */
+ NULL, /* write - bad */
+ minix_readdir, /* readdir */
+ NULL, /* close - default */
+ NULL, /* select - default */
+ NULL /* ioctl - default */
+};
diff --git a/fs/minix/namei.c b/fs/minix/namei.c
index ba891cb..912b883 100644
--- a/fs/minix/namei.c
+++ b/fs/minix/namei.c
@@ -9,7 +9,7 @@
#include <linux/kernel.h>
#include <asm/segment.h>
-#include <string.h>
+#include <linux/string.h>
#include <fcntl.h>
#include <errno.h>
#include <const.h>
@@ -323,7 +323,7 @@ int minix_mkdir(struct inode * dir, const char * name, int len, int mode)
iput(dir);
return -ENOSPC;
}
- inode->i_size = 32;
+ inode->i_size = 2 * sizeof (struct minix_dir_entry);
inode->i_dirt = 1;
inode->i_mtime = inode->i_atime = CURRENT_TIME;
if (!(inode->i_data[0] = minix_new_block(inode->i_dev))) {
@@ -337,7 +337,7 @@ int minix_mkdir(struct inode * dir, const char * name, int len, int mode)
iput(dir);
inode->i_nlink--;
iput(inode);
- return -ERROR;
+ return -EIO;
}
de = (struct minix_dir_entry *) dir_block->b_data;
de->inode=inode->i_ino;
@@ -529,7 +529,7 @@ int minix_symlink(struct inode * dir, const char * name, int len, const char * s
iput(dir);
inode->i_nlink--;
iput(inode);
- return -ERROR;
+ return -EIO;
}
i = 0;
while (i < 1023 && (c=get_fs_byte(symname++)))
diff --git a/fs/minix/truncate.c b/fs/minix/truncate.c
index ab72736..7df5268 100644
--- a/fs/minix/truncate.c
+++ b/fs/minix/truncate.c
@@ -12,93 +12,132 @@
#include <fcntl.h>
#include <sys/stat.h>
-static int minix_free_ind(int dev,int block)
+/*
+ * Truncate has the most races in the whole filesystem: coding it is
+ * a pain in the a**. Especially as I don't do any locking...
+ *
+ * The code may look a bit weird, but that's just because I've tried to
+ * handle things like file-size changes in a somewhat graceful manner.
+ * Anyway, truncating a file at the same time somebody else writes to it
+ * is likely to result in pretty weird behaviour...
+ *
+ * The new code handles normal truncates (size = 0) as well as the more
+ * general case (size = XXX). I hope.
+ */
+
+static int trunc_direct(struct inode * inode)
{
- struct buffer_head * bh;
- unsigned short * p;
int i;
- int block_busy;
+ int result = 0;
+#define DIRECT_BLOCK ((inode->i_size + 1023) >> 10)
- if (!block)
- return 1;
- block_busy = 0;
- if (bh=bread(dev,block)) {
- p = (unsigned short *) bh->b_data;
- for (i=0;i<512;i++,p++)
- if (*p)
- if (minix_free_block(dev,*p)) {
- *p = 0;
- bh->b_dirt = 1;
- } else
- block_busy = 1;
- brelse(bh);
+repeat:
+ for (i = DIRECT_BLOCK ; i < 7 ; i++) {
+ if (i < DIRECT_BLOCK)
+ goto repeat;
+ if (!inode->i_data[i])
+ continue;
+ result = 1;
+ if (minix_free_block(inode->i_dev,inode->i_data[i]))
+ inode->i_data[i] = 0;
}
- if (block_busy)
- return 0;
- else
- return minix_free_block(dev,block);
+ return result;
}
-static int minix_free_dind(int dev,int block)
+static int trunc_indirect(struct inode * inode, int offset, unsigned short * p)
{
- struct buffer_head * bh;
- unsigned short * p;
int i;
- int block_busy;
+ struct buffer_head * bh = NULL;
+ unsigned short * ind;
+ int result = 0;
+#define INDIRECT_BLOCK (DIRECT_BLOCK-offset)
- if (!block)
- return 1;
- block_busy = 0;
- if (bh=bread(dev,block)) {
- p = (unsigned short *) bh->b_data;
- for (i=0;i<512;i++,p++)
- if (*p)
- if (minix_free_ind(dev,*p)) {
- *p = 0;
- bh->b_dirt = 1;
- } else
- block_busy = 1;
- brelse(bh);
- }
- if (block_busy)
+ if (*p)
+ bh = bread(inode->i_dev,*p);
+ if (!bh)
return 0;
- else
- return minix_free_block(dev,block);
+repeat:
+ for (i = INDIRECT_BLOCK ; i < 512 ; i++) {
+ if (i < 0)
+ i = 0;
+ if (i < INDIRECT_BLOCK)
+ goto repeat;
+ ind = i+(unsigned short *) bh->b_data;
+ if (!*ind)
+ continue;
+ result = 1;
+ if (minix_free_block(inode->i_dev,*ind))
+ *ind = 0;
+ }
+ ind = (unsigned short *) bh->b_data;
+ for (i = 0; i < 512; i++)
+ if (*(ind++))
+ break;
+ brelse(bh);
+ if (i >= 512) {
+ result = 1;
+ if (minix_free_block(inode->i_dev,*p))
+ *p = 0;
+ }
+ return result;
}
+
+static int trunc_dindirect(struct inode * inode)
+{
+ int i;
+ struct buffer_head * bh = NULL;
+ unsigned short * dind;
+ int result = 0;
+#define DINDIRECT_BLOCK ((DIRECT_BLOCK-(512+7))>>9)
+ if (inode->i_data[8])
+ bh = bread(inode->i_dev,inode->i_data[8]);
+ if (!bh)
+ return 0;
+repeat:
+ for (i = DINDIRECT_BLOCK ; i < 512 ; i ++) {
+ if (i < 0)
+ i = 0;
+ if (i < DINDIRECT_BLOCK)
+ goto repeat;
+ dind = i+(unsigned short *) bh->b_data;
+ if (!*dind)
+ continue;
+ result |= trunc_indirect(inode,7+512+(i<<9),dind);
+ }
+ dind = (unsigned short *) bh->b_data;
+ for (i = 0; i < 512; i++)
+ if (*(dind++))
+ break;
+ brelse(bh);
+ if (i >= 512) {
+ result = 1;
+ if (minix_free_block(inode->i_dev,inode->i_data[8]))
+ inode->i_data[8] = 0;
+ }
+ return result;
+}
+
void minix_truncate(struct inode * inode)
{
- int i;
- int block_busy;
+ int flag;
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
S_ISLNK(inode->i_mode)))
return;
-repeat:
- block_busy = 0;
- for (i=0;i<7;i++)
- if (inode->i_data[i]) {
- if (minix_free_block(inode->i_dev,inode->i_data[i]))
- inode->i_data[i]=0;
- else
- block_busy = 1;
- }
- if (minix_free_ind(inode->i_dev,inode->i_data[7]))
- inode->i_data[7] = 0;
- else
- block_busy = 1;
- if (minix_free_dind(inode->i_dev,inode->i_data[8]))
- inode->i_data[8] = 0;
- else
- block_busy = 1;
- inode->i_dirt = 1;
- if (block_busy) {
+ if (inode->i_data[7] & 0xffff0000)
+ printk("BAD! minix inode has 16 high bits set\n");
+ while (1) {
+ flag = trunc_direct(inode);
+ flag |= trunc_indirect(inode,7,(unsigned short *)&inode->i_data[7]);
+ flag |= trunc_dindirect(inode);
+ if (!flag)
+ break;
current->counter = 0;
schedule();
- goto repeat;
}
- inode->i_size = 0;
inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+ inode->i_dirt = 1;
}
/*
@@ -151,6 +190,9 @@ int minix_open(struct inode * inode, struct file * filp)
return -EAGAIN;
} else if (S_ISBLK(inode->i_mode))
check_disk_change(inode->i_rdev);
- filp->f_op = &minix_file_operations;
+ else if (S_ISREG(inode->i_mode))
+ filp->f_op = &minix_file_operations;
+ else if (S_ISDIR(inode->i_mode))
+ filp->f_op = &minix_dir_operations;
return 0;
}
diff --git a/fs/namei.c b/fs/namei.c
index 6833d62..73c1621 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -12,7 +12,7 @@
#include <linux/kernel.h>
#include <asm/segment.h>
-#include <string.h>
+#include <linux/string.h>
#include <fcntl.h>
#include <errno.h>
#include <const.h>
@@ -248,8 +248,10 @@ int open_namei(const char * pathname, int flag, int mode,
}
inode->i_atime = CURRENT_TIME;
if (flag & O_TRUNC)
- if (inode->i_op && inode->i_op->truncate)
+ if (inode->i_op && inode->i_op->truncate) {
+ inode->i_size = 0;
inode->i_op->truncate(inode);
+ }
*res_inode = inode;
return 0;
}
diff --git a/fs/open.c b/fs/open.c
index fe0fb5b..e2cdce7 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -4,23 +4,83 @@
* (C) 1991 Linus Torvalds
*/
-#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <utime.h>
+
#include <sys/stat.h>
+#include <sys/vfs.h>
+#include <linux/string.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <asm/segment.h>
+struct file_operations * chrdev_fops[MAX_CHRDEV] = {
+ NULL,
+};
+
+struct file_operations * blkdev_fops[MAX_BLKDEV] = {
+ NULL,
+};
+
int sys_ustat(int dev, struct ustat * ubuf)
{
return -ENOSYS;
}
+int sys_statfs(const char * path, struct statfs * buf)
+{
+ printk("statfs not implemented\n");
+ return -ENOSYS;
+}
+
+int sys_fstatfs(unsigned int fd, struct statfs * buf)
+{
+ printk("fstatfs not implemented\n");
+ return -ENOSYS;
+}
+
+int sys_truncate(const char * path, unsigned int length)
+{
+ struct inode * inode;
+
+ if (!(inode = namei(path)))
+ return -ENOENT;
+ if (!permission(inode,MAY_WRITE)) {
+ iput(inode);
+ return -EPERM;
+ }
+ inode->i_size = length;
+ if (inode->i_op && inode->i_op->truncate)
+ inode->i_op->truncate(inode);
+ inode->i_atime = inode->i_mtime = CURRENT_TIME;
+ inode->i_dirt = 1;
+ iput(inode);
+ return 0;
+}
+
+int sys_ftruncate(unsigned int fd, unsigned int length)
+{
+ struct inode * inode;
+ struct file * file;
+
+ if (fd >= NR_OPEN || !(file = current->filp[fd]))
+ return -EBADF;
+ if (!(inode = file->f_inode))
+ return -ENOENT;
+ if (!(file->f_flags & 2))
+ return -EPERM;
+ inode->i_size = length;
+ if (inode->i_op && inode->i_op->truncate)
+ inode->i_op->truncate(inode);
+ inode->i_atime = inode->i_mtime = CURRENT_TIME;
+ inode->i_dirt = 1;
+ return 0;
+}
+
int sys_utime(char * filename, struct utimbuf * times)
{
struct inode * inode;
@@ -107,11 +167,27 @@ int sys_chroot(const char * filename)
return (0);
}
-int sys_chmod(const char * filename,int mode)
+int sys_fchmod(unsigned int fd, mode_t mode)
{
struct inode * inode;
+ struct file * file;
- if (!(inode=namei(filename)))
+ if (fd >= NR_OPEN || !(file = current->filp[fd]))
+ return -EBADF;
+ if (!(inode = file->f_inode))
+ return -ENOENT;
+ if ((current->euid != inode->i_uid) && !suser())
+ return -EACCES;
+ inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777);
+ inode->i_dirt = 1;
+ return 0;
+}
+
+int sys_chmod(const char * filename, mode_t mode)
+{
+ struct inode * inode;
+
+ if (!(inode = namei(filename)))
return -ENOENT;
if ((current->euid != inode->i_uid) && !suser()) {
iput(inode);
@@ -123,19 +199,36 @@ int sys_chmod(const char * filename,int mode)
return 0;
}
-int sys_chown(const char * filename,int uid,int gid)
+int sys_fchown(unsigned int fd, uid_t user, gid_t group)
{
struct inode * inode;
+ struct file * file;
- if (!(inode=namei(filename)))
+ if (fd >= NR_OPEN || !(file = current->filp[fd]))
+ return -EBADF;
+ if (!(inode = file->f_inode))
+ return -ENOENT;
+ if (!suser())
+ return -EACCES;
+ inode->i_uid = user;
+ inode->i_gid = group;
+ inode->i_dirt=1;
+ return 0;
+}
+
+int sys_chown(const char * filename, uid_t user, gid_t group)
+{
+ struct inode * inode;
+
+ if (!(inode = namei(filename)))
return -ENOENT;
if (!suser()) {
iput(inode);
return -EACCES;
}
- inode->i_uid=uid;
- inode->i_gid=gid;
- inode->i_dirt=1;
+ inode->i_uid = user;
+ inode->i_gid = group;
+ inode->i_dirt = 1;
iput(inode);
return 0;
}
@@ -157,13 +250,23 @@ int sys_open(const char * filename,int flag,int mode)
if (!f->f_count) break;
if (i>=NR_FILE)
return -EINVAL;
- (current->filp[fd]=f)->f_count++;
- if ((i=open_namei(filename,flag,mode,&inode))<0) {
+ (current->filp[fd] = f)->f_count++;
+ if ((i = open_namei(filename,flag,mode,&inode))<0) {
current->filp[fd]=NULL;
f->f_count=0;
return i;
}
f->f_op = NULL;
+ if (inode)
+ if (S_ISCHR(inode->i_mode)) {
+ i = MAJOR(inode->i_rdev);
+ if (i < MAX_CHRDEV)
+ f->f_op = chrdev_fops[i];
+ } else if (S_ISBLK(inode->i_mode)) {
+ i = MAJOR(inode->i_rdev);
+ if (i < MAX_CHRDEV)
+ f->f_op = blkdev_fops[i];
+ }
f->f_mode = "\001\002\003\000"[flag & O_ACCMODE];
f->f_flags = flag;
f->f_count = 1;
@@ -198,6 +301,8 @@ int sys_close(unsigned int fd)
panic("Close: file count is 0");
if (--filp->f_count)
return (0);
+ if (filp->f_op && filp->f_op->close)
+ return filp->f_op->close(filp->f_inode,filp);
iput(filp->f_inode);
- return (0);
+ return 0;
}
diff --git a/fs/pipe.c b/fs/pipe.c
index 5f773d9..0aef899 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -9,11 +9,12 @@
#include <termios.h>
#include <fcntl.h>
-#include <linux/sched.h>
#include <asm/segment.h>
+
+#include <linux/sched.h>
#include <linux/kernel.h>
-int pipe_read(struct inode * inode, struct file * filp, char * buf, int count)
+static int pipe_read(struct inode * inode, struct file * filp, char * buf, int count)
{
int chars, size, read = 0;
@@ -44,7 +45,7 @@ int pipe_read(struct inode * inode, struct file * filp, char * buf, int count)
return read?read:-EAGAIN;
}
-int pipe_write(struct inode * inode, struct file * filp, char * buf, int count)
+static int pipe_write(struct inode * inode, struct file * filp, char * buf, int count)
{
int chars, size, written = 0;
@@ -76,6 +77,54 @@ int pipe_write(struct inode * inode, struct file * filp, char * buf, int count)
return written;
}
+static int pipe_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
+{
+ return -ESPIPE;
+}
+
+static int pipe_readdir(struct inode * inode, struct file * file, struct dirent * de, int count)
+{
+ return -ENOTDIR;
+}
+
+static int bad_pipe_rw(struct inode * inode, struct file * filp, char * buf, int count)
+{
+ return -EBADF;
+}
+
+static int pipe_ioctl(struct inode *pino, struct file * filp,
+ unsigned int cmd, unsigned int arg)
+{
+ switch (cmd) {
+ case FIONREAD:
+ verify_area((void *) arg,4);
+ put_fs_long(PIPE_SIZE(*pino),(unsigned long *) arg);
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+static struct file_operations read_pipe_fops = {
+ pipe_lseek,
+ pipe_read,
+ bad_pipe_rw,
+ pipe_readdir,
+ NULL, /* pipe_close */
+ NULL, /* pipe_select */
+ pipe_ioctl
+};
+
+static struct file_operations write_pipe_fops = {
+ pipe_lseek,
+ bad_pipe_rw,
+ pipe_write,
+ pipe_readdir,
+ NULL, /* pipe_close */
+ NULL, /* pipe_select */
+ pipe_ioctl
+};
+
int sys_pipe(unsigned long * fildes)
{
struct inode * inode;
@@ -111,21 +160,11 @@ int sys_pipe(unsigned long * fildes)
}
f[0]->f_inode = f[1]->f_inode = inode;
f[0]->f_pos = f[1]->f_pos = 0;
+ f[0]->f_op = &read_pipe_fops;
f[0]->f_mode = 1; /* read */
+ f[1]->f_op = &write_pipe_fops;
f[1]->f_mode = 2; /* write */
put_fs_long(fd[0],0+fildes);
put_fs_long(fd[1],1+fildes);
return 0;
}
-
-int pipe_ioctl(struct inode *pino, int cmd, int arg)
-{
- switch (cmd) {
- case FIONREAD:
- verify_area((void *) arg,4);
- put_fs_long(PIPE_SIZE(*pino),(unsigned long *) arg);
- return 0;
- default:
- return -EINVAL;
- }
-}
diff --git a/fs/read_write.c b/fs/read_write.c
index 1a9b20a..19cbcda 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -28,43 +28,40 @@ int sys_readdir(unsigned int fd, struct dirent * dirent, unsigned int count)
return -EBADF;
if (file->f_op && file->f_op->readdir) {
verify_area(dirent, sizeof (*dirent));
- return file->f_op->readdir(inode,file,dirent);
+ return file->f_op->readdir(inode,file,dirent,count);
}
- return -EBADF;
+ return -ENOTDIR;
}
int sys_lseek(unsigned int fd, off_t offset, unsigned int origin)
{
struct file * file;
- int tmp, mem_dev;
+ int tmp;
if (fd >= NR_OPEN || !(file=current->filp[fd]) || !(file->f_inode))
return -EBADF;
if (origin > 2)
return -EINVAL;
- if (file->f_inode->i_pipe)
- return -ESPIPE;
if (file->f_op && file->f_op->lseek)
return file->f_op->lseek(file->f_inode,file,offset,origin);
- mem_dev = S_ISCHR(file->f_inode->i_mode);
/* this is the default handler if no lseek handler is present */
switch (origin) {
case 0:
- if (offset<0 && !mem_dev) return -EINVAL;
- file->f_pos=offset;
+ tmp = offset;
break;
case 1:
- if (file->f_pos+offset<0 && !mem_dev) return -EINVAL;
- file->f_pos += offset;
+ tmp = file->f_pos + offset;
break;
case 2:
- if ((tmp=file->f_inode->i_size+offset)<0 && !mem_dev)
+ if (!file->f_inode)
return -EINVAL;
- file->f_pos = tmp;
+ tmp = file->f_inode->i_size + offset;
+ break;
}
- if (mem_dev && file->f_pos < 0)
- return 0;
+ if (tmp < 0)
+ return -EINVAL;
+ file->f_pos = tmp;
return file->f_pos;
}
@@ -82,15 +79,6 @@ int sys_read(unsigned int fd,char * buf,unsigned int count)
verify_area(buf,count);
if (file->f_op && file->f_op->read)
return file->f_op->read(inode,file,buf,count);
-/* these are the default read-functions */
- if (inode->i_pipe)
- return pipe_read(inode,file,buf,count);
- if (S_ISCHR(inode->i_mode))
- return char_read(inode,file,buf,count);
- if (S_ISBLK(inode->i_mode))
- return block_read(inode,file,buf,count);
- if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode))
- return minix_file_read(inode,file,buf,count);
printk("(Read)inode->i_mode=%06o\n\r",inode->i_mode);
return -EINVAL;
}
@@ -108,15 +96,6 @@ int sys_write(unsigned int fd,char * buf,unsigned int count)
return 0;
if (file->f_op && file->f_op->write)
return file->f_op->write(inode,file,buf,count);
-/* these are the default read-functions */
- if (inode->i_pipe)
- return pipe_write(inode,file,buf,count);
- if (S_ISCHR(inode->i_mode))
- return char_write(inode,file,buf,count);
- if (S_ISBLK(inode->i_mode))
- return block_write(inode,file,buf,count);
- if (S_ISREG(inode->i_mode))
- return minix_file_write(inode,file,buf,count);
printk("(Write)inode->i_mode=%06o\n\r",inode->i_mode);
return -EINVAL;
}
diff --git a/fs/select.c b/fs/select.c
index e5d1439..98e74c4 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -9,16 +9,17 @@
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/sched.h>
+#include <linux/string.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <sys/stat.h>
#include <sys/types.h>
-#include <string.h>
+#include <sys/time.h>
+
#include <const.h>
#include <errno.h>
-#include <sys/time.h>
#include <signal.h>
/*
@@ -34,18 +35,6 @@
* task.
*/
-typedef struct {
- struct task_struct * old_task;
- struct task_struct ** wait_address;
-} wait_entry;
-
-typedef struct select_table_struct {
- int nr, woken;
- struct task_struct * current;
- struct select_table_struct * next_table;
- wait_entry entry[NR_OPEN*3];
-} select_table;
-
static select_table * sel_tables = NULL;
static void add_wait(struct task_struct ** wait_address, select_table * p)
diff --git a/fs/super.c b/fs/super.c
index b4c95e0..78f8b6c 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -12,6 +12,7 @@
#include <linux/minix_fs.h>
#include <linux/kernel.h>
#include <asm/system.h>
+#include <asm/segment.h>
#include <errno.h>
#include <sys/stat.h>
@@ -146,7 +147,9 @@ int sys_umount(char * dev_name)
struct super_block * sb;
int dev;
- if (!(inode=namei(dev_name)))
+ if (!suser())
+ return -EPERM;
+ if (!(inode = namei(dev_name)))
return -ENOENT;
dev = inode->i_rdev;
if (!S_ISBLK(inode->i_mode)) {
@@ -176,13 +179,17 @@ int sys_umount(char * dev_name)
return 0;
}
-int sys_mount(char * dev_name, char * dir_name, int rw_flag)
+int sys_mount(char * dev_name, char * dir_name, char * type, int rw_flag)
{
struct inode * dev_i, * dir_i;
struct super_block * sb;
int dev;
+ char tmp[100],*t;
+ int i;
- if (!(dev_i=namei(dev_name)))
+ if (!suser())
+ return -EPERM;
+ if (!(dev_i = namei(dev_name)))
return -ENOENT;
dev = dev_i->i_rdev;
if (!S_ISBLK(dev_i->i_mode)) {
@@ -204,7 +211,14 @@ int sys_mount(char * dev_name, char * dir_name, int rw_flag)
iput(dir_i);
return -EPERM;
}
- if (!(sb=read_super(dev,"minix",NULL))) {
+ if (type) {
+ i = 0;
+ while (i < 100 && (tmp[i] = get_fs_byte(type++)))
+ i++;
+ t = tmp;
+ } else
+ t = "minix";
+ if (!(sb = read_super(dev,t,NULL))) {
iput(dir_i);
return -EBUSY;
}
diff --git a/include/asm/system.h b/include/asm/system.h
index 6f5f670..6fbcf1b 100644
--- a/include/asm/system.h
+++ b/include/asm/system.h
@@ -50,7 +50,7 @@ __asm__ ("movw %%dx,%%ax\n\t" \
((limit) & 0x0ffff); }
#define _set_tssldt_desc(n,addr,type) \
-__asm__ ("movw $104,%1\n\t" \
+__asm__ ("movw $232,%1\n\t" \
"movw %%ax,%2\n\t" \
"rorl $16,%%eax\n\t" \
"movb %%al,%3\n\t" \
diff --git a/include/checkpoint.h b/include/checkpoint.h
deleted file mode 100644
index e69de29..0000000
--- a/include/checkpoint.h
+++ /dev/null
diff --git a/include/errno.h b/include/errno.h
index a38b78f..fdb1b14 100644
--- a/include/errno.h
+++ b/include/errno.h
@@ -16,7 +16,6 @@
extern int errno;
-#define ERROR 99
#define EPERM 1
#define ENOENT 2
#define ESRCH 3
diff --git a/include/linux/config_rel.h b/include/linux/config_rel.h
index 0e26529..a602c1f 100644
--- a/include/linux/config_rel.h
+++ b/include/linux/config_rel.h
@@ -1 +1 @@
-#define UTS_RELEASE "0.95c-18"
+#define UTS_RELEASE "0.95c-54"
diff --git a/include/linux/config_ver.h b/include/linux/config_ver.h
index 1024624..34e98a9 100644
--- a/include/linux/config_ver.h
+++ b/include/linux/config_ver.h
@@ -1 +1 @@
-#define UTS_VERSION "04/09/92"
+#define UTS_VERSION "04/22/92"
diff --git a/include/ctype.h b/include/linux/ctype.h
index 7acf55d..7acf55d 100644
--- a/include/ctype.h
+++ b/include/linux/ctype.h
diff --git a/include/linux/fs.h b/include/linux/fs.h
index d75dd80..7e067bd 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -46,6 +46,9 @@ void buffer_init(long buffer_end);
#define NR_BUFFERS nr_buffers
#define BLOCK_SIZE 1024
#define BLOCK_SIZE_BITS 10
+#define MAX_CHRDEV 16
+#define MAX_BLKDEV 16
+
#ifndef NULL
#define NULL ((void *) 0)
#endif
@@ -115,6 +118,18 @@ struct file {
off_t f_pos;
};
+typedef struct {
+ struct task_struct * old_task;
+ struct task_struct ** wait_address;
+} wait_entry;
+
+typedef struct select_table_struct {
+ int nr, woken;
+ struct task_struct * current;
+ struct select_table_struct * next_table;
+ wait_entry entry[NR_OPEN*3];
+} select_table;
+
struct super_block {
unsigned short s_ninodes;
unsigned short s_nzones;
@@ -143,7 +158,10 @@ struct file_operations {
int (*lseek) (struct inode *, struct file *, off_t, int);
int (*read) (struct inode *, struct file *, char *, int);
int (*write) (struct inode *, struct file *, char *, int);
- int (*readdir) (struct inode *, struct file *, struct dirent *);
+ int (*readdir) (struct inode *, struct file *, struct dirent *, int count);
+ int (*close) (struct inode *, struct file *);
+ int (*select) (struct inode *, struct file *, int, select_table *);
+ int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned int);
};
struct inode_operations {
@@ -177,6 +195,9 @@ struct file_system_type {
char *name;
};
+extern struct file_operations * chrdev_fops[MAX_CHRDEV];
+extern struct file_operations * blkdev_fops[MAX_BLKDEV];
+
extern struct file_system_type *get_fs_type(char *name);
extern struct inode inode_table[NR_INODE];
@@ -222,11 +243,9 @@ extern void mount_root(void);
extern void lock_super(struct super_block * sb);
extern void free_super(struct super_block * sb);
-extern int pipe_read(struct inode *, struct file *, char *, int);
extern int char_read(struct inode *, struct file *, char *, int);
extern int block_read(struct inode *, struct file *, char *, int);
-extern int pipe_write(struct inode *, struct file *, char *, int);
extern int char_write(struct inode *, struct file *, char *, int);
extern int block_write(struct inode *, struct file *, char *, int);
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index eab299b..2451af9 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -7,7 +7,6 @@ volatile void do_exit(long error_code);
int printf(const char * fmt, ...);
int printk(const char * fmt, ...);
void console_print(const char * str);
-int tty_write(unsigned ch,char * buf,int count);
void * malloc(unsigned int size);
void free_s(void * obj, int size);
diff --git a/include/linux/lp.h b/include/linux/lp.h
index 69049a7..6e565da 100644
--- a/include/linux/lp.h
+++ b/include/linux/lp.h
@@ -107,8 +107,3 @@ struct lp_struct lp_table[] = {
*/
extern void lp_init(void);
-
-extern int lp_reset(int minor);
-extern int lp_char(char lpchar, int minor);
-extern int lp_write(unsigned minor, char *buf, int count);
-
diff --git a/include/linux/minix_fs.h b/include/linux/minix_fs.h
index 189f438..c427cb1 100644
--- a/include/linux/minix_fs.h
+++ b/include/linux/minix_fs.h
@@ -65,23 +65,25 @@ extern void minix_free_inode(struct inode * inode);
extern int minix_new_block(int dev);
extern int minix_free_block(int dev, int block);
-extern int minix_create_block(struct inode * inode, int block);
-extern int minix_bmap(struct inode * inode,int block);
+extern int minix_create_block(struct inode *, int);
+extern int minix_bmap(struct inode *,int);
-extern void minix_truncate(struct inode * inode);
-extern void minix_put_super(struct super_block *sb);
-extern struct super_block *minix_read_super(struct super_block *s,void *data);
-extern void minix_read_inode(struct inode * inode);
-extern void minix_write_inode(struct inode * inode);
+extern void minix_truncate(struct inode *);
+extern void minix_put_super(struct super_block *);
+extern struct super_block *minix_read_super(struct super_block *,void *);
+extern void minix_read_inode(struct inode *);
+extern void minix_write_inode(struct inode *);
-extern int minix_lseek(struct inode * inode, struct file * filp, off_t offset, int origin);
-extern int minix_read(struct inode * inode, struct file * filp, char * buf, int count);
-extern int minix_write(struct inode * inode, struct file * filp, char * buf, int count);
-extern int minix_readdir(struct inode * inode, struct file * filp, struct dirent * dirent);
+extern int minix_lseek(struct inode *, struct file *, off_t, int);
+extern int minix_read(struct inode *, struct file *, char *, int);
+extern int minix_write(struct inode *, struct file *, char *, int);
+extern int minix_readdir(struct inode *, struct file *, struct dirent *, int);
extern int minix_file_read(struct inode *, struct file *, char *, int);
extern int minix_file_write(struct inode *, struct file *, char *, int);
extern struct inode_operations minix_inode_operations;
+
extern struct file_operations minix_file_operations;
+extern struct file_operations minix_dir_operations;
#endif
diff --git a/include/linux/sched.h b/include/linux/sched.h
index e1fac82..9d744cb 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -7,6 +7,11 @@
#define TASK_SIZE 0x04000000
#define LIBRARY_SIZE 0x00400000
+/*
+ * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
+ */
+#define IO_BITMAP_SIZE 32
+
#if (TASK_SIZE & 0x3fffff)
#error "TASK_SIZE must be multiple of 4M"
#endif
@@ -53,6 +58,8 @@
#define NULL ((void *) 0)
#endif
+#define MAX_SHARED_LIBS 6
+
extern int copy_page_tables(unsigned long from, unsigned long to, long size);
extern int free_page_tables(unsigned long from, unsigned long size);
@@ -60,7 +67,6 @@ extern void sched_init(void);
extern void schedule(void);
extern void trap_init(void);
extern void panic(const char * str);
-extern int tty_write(unsigned minor,char * buf,int count);
typedef int (*fn_ptr)();
@@ -76,29 +82,30 @@ struct i387_struct {
};
struct tss_struct {
- long back_link; /* 16 high bits zero */
- long esp0;
- long ss0; /* 16 high bits zero */
- long esp1;
- long ss1; /* 16 high bits zero */
- long esp2;
- long ss2; /* 16 high bits zero */
- long cr3;
- long eip;
- long eflags;
- long eax,ecx,edx,ebx;
- long esp;
- long ebp;
- long esi;
- long edi;
- long es; /* 16 high bits zero */
- long cs; /* 16 high bits zero */
- long ss; /* 16 high bits zero */
- long ds; /* 16 high bits zero */
- long fs; /* 16 high bits zero */
- long gs; /* 16 high bits zero */
- long ldt; /* 16 high bits zero */
- long trace_bitmap; /* bits: trace 0, bitmap 16-31 */
+ unsigned long back_link; /* 16 high bits zero */
+ unsigned long esp0;
+ unsigned long ss0; /* 16 high bits zero */
+ unsigned long esp1;
+ unsigned long ss1; /* 16 high bits zero */
+ unsigned long esp2;
+ unsigned long ss2; /* 16 high bits zero */
+ unsigned long cr3;
+ unsigned long eip;
+ unsigned long eflags;
+ unsigned long eax,ecx,edx,ebx;
+ unsigned long esp;
+ unsigned long ebp;
+ unsigned long esi;
+ unsigned long edi;
+ unsigned long es; /* 16 high bits zero */
+ unsigned long cs; /* 16 high bits zero */
+ unsigned long ss; /* 16 high bits zero */
+ unsigned long ds; /* 16 high bits zero */
+ unsigned long fs; /* 16 high bits zero */
+ unsigned long gs; /* 16 high bits zero */
+ unsigned long ldt; /* 16 high bits zero */
+ unsigned long trace_bitmap; /* bits: trace 0, bitmap 16-31 */
+ unsigned long io_bitmap[IO_BITMAP_SIZE];
struct i387_struct i387;
};
@@ -143,9 +150,14 @@ struct task_struct {
struct inode * pwd;
struct inode * root;
struct inode * executable;
- struct inode * library;
- unsigned long close_on_exec;
+ struct {
+ struct inode * library;
+ unsigned long start;
+ unsigned long length;
+ } libraries[MAX_SHARED_LIBS];
+ int numlibraries;
struct file * filp[NR_OPEN];
+ unsigned long close_on_exec;
/* ldt for this task 0 - zero 1 - cs 2 - ds&ss */
struct desc_struct ldt[3];
/* tss for this task */
@@ -183,17 +195,18 @@ struct task_struct {
/* math */ 0, \
/* rss */ 2, \
/* comm */ "swapper", \
-/* fs info */ 0,-1,0022,NULL,NULL,NULL,NULL,0, \
-/* filp */ {NULL,}, \
- { \
- {0,0}, \
-/* ldt */ {0x9f,0xc0fa00}, \
- {0x9f,0xc0f200}, \
- }, \
+/* fs info */ 0,-1,0022,NULL,NULL,NULL, \
+/* libraries */ { { NULL, 0, 0}, }, 0, \
+/* filp */ {NULL,}, 0, \
+ { \
+ {0,0}, \
+/* ldt */ {0x9f,0xc0fa00}, \
+ {0x9f,0xc0f200} \
+ }, \
/*tss*/ {0,PAGE_SIZE+(long)&init_task,0x10,0,0,0,0,(long)&pg_dir,\
0,0,0,0,0,0,0,0, \
0,0,0x17,0x17,0x17,0x17,0x17,0x17, \
- _LDT(0),0x80000000, \
+ _LDT(0),0x80000000,{0xffffffff}, \
{} \
}, \
}
diff --git a/include/string.h b/include/linux/string.h
index 7da1793..7da1793 100644
--- a/include/string.h
+++ b/include/linux/string.h
diff --git a/include/linux/sys.h b/include/linux/sys.h
index e721865..df8264c 100644
--- a/include/linux/sys.h
+++ b/include/linux/sys.h
@@ -92,6 +92,18 @@ extern int sys_uselib();
extern int sys_swapon();
extern int sys_reboot();
extern int sys_readdir();
+extern int sys_mmap();
+extern int sys_munmap();
+extern int sys_truncate();
+extern int sys_ftruncate();
+extern int sys_fchmod();
+extern int sys_fchown();
+extern int sys_getpriority();
+extern int sys_setpriority();
+extern int sys_profil();
+extern int sys_statfs();
+extern int sys_fstatfs();
+extern int sys_ioperm();
fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read,
sys_write, sys_open, sys_close, sys_waitpid, sys_creat, sys_link,
@@ -105,10 +117,13 @@ 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, sys_swapon, sys_reboot, sys_readdir };
+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,
+sys_swapon, sys_reboot, sys_readdir, sys_mmap, sys_munmap,
+sys_truncate, sys_ftruncate, sys_fchmod, sys_fchown, sys_getpriority,
+sys_setpriority, sys_profil, sys_statfs, sys_fstatfs, sys_ioperm };
/* So we don't have to do any more manual updating.... */
int NR_syscalls = sizeof(sys_call_table)/sizeof(fn_ptr);
diff --git a/include/linux/tty.h b/include/linux/tty.h
index d185dd6..22f0f0e 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -119,17 +119,17 @@ extern unsigned long video_num_lines;
*/
#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
-void rs_init(void);
-void con_init(void);
-void tty_init(void);
+extern void rs_init(void);
+extern void lp_init(void);
+extern void con_init(void);
+extern void tty_init(void);
-int tty_read(unsigned c, char * buf, int n, unsigned short flags);
-int tty_write(unsigned c, char * buf, int n);
+extern int tty_ioctl(struct inode *, struct file *, unsigned int, unsigned int);
-void con_write(struct tty_struct * tty);
-void rs_write(struct tty_struct * tty);
-void mpty_write(struct tty_struct * tty);
-void spty_write(struct tty_struct * tty);
+extern void rs_write(struct tty_struct * tty);
+extern void con_write(struct tty_struct * tty);
+extern void mpty_write(struct tty_struct * tty);
+extern void spty_write(struct tty_struct * tty);
extern void serial_open(unsigned int line);
diff --git a/include/sys/kd.h b/include/sys/kd.h
new file mode 100644
index 0000000..9335ebf
--- /dev/null
+++ b/include/sys/kd.h
@@ -0,0 +1,179 @@
+#ifndef _KD_H
+#define _KD_H
+
+/* 0x4B is 'K', to avoid collision with termios and vt */
+
+#define SWAPMONO 0x4B00 /* use mca as output device */
+#define SWAPCGA 0x4B01 /* use cga as output device */
+#define SWAPEGA 0x4B02 /* use ega as output device */
+#define SWAPVGA 0x4B03 /* use vga as output device */
+#define CONS_CURRENT 0x4B04 /* return current output device */
+#define MONO 0x01
+#define CGA 0x02
+#define EGA 0x03
+
+#define SW_B40x25 0x4B05 /* 40x25 mono text (cga/ega) */
+#define SW_C40x25 0x4B06 /* 40x24 color text (cga/ega) */
+#define SW_B80x25 0x4B07 /* 80x25 mono text (cga/ega) */
+#define SW_C80x25 0x4B08 /* 80x25 color text (cga/ega) */
+#define SW_BG320 0x4B09 /* 320x200 mono graphics (cga/ega) */
+#define SW_CG320 0x4B0A /* 320x200 color graphics (cga/ega) */
+#define SW_BG640 0x4B0B /* 640x200 mono graphics (cga/ega) */
+#define SW_CG320_D 0x4B0C /* 320x200 graphics (ega mode d) */
+#define SW_CG640_E 0x4B0D /* 640x200 graphics (ega mode e) */
+#define SW_EGAMONOAPA 0x4B0E /* 640x350 graphics (ega mode f) */
+#define SW_ENH_MONOAPA2 0x4B0F /* 640x350 graphics extd mem (ega mode f*) */
+#define SW_CG640x350 0x4B10 /* 640x350 graphics (ega mode 10) */
+#define SW_ENH_CG640 0x4B11 /* 640x350 graphics extd mem (ega mode 10*) */
+#define SW_EGAMONO80x25 0x4B12 /* 80x25 mono text (ega mode 7) */
+#define SW_ENHB40x25 0x4B13 /* enhanced 40x25 mono text (ega) */
+#define SW_ENHC40x25 0x4B14 /* enhanced 40x25 color text (ega) */
+#define SW_ENHB80x25 0x4B15 /* enhanced 80x25 mono text (ega) */
+#define SW_ENHC80x25 0x4B16 /* enhanced 80x25 color text (ega) */
+#define SW_ENHB80x43 0x4B17 /* enhanced 80x43 mono text (ega) */
+#define SW_ENHC80x43 0x4B18 /* enhanced 80x43 color text (ega) */
+#define SW_MCAMODE 0x4B19 /* reinit mca */
+#define SW_ATT640 0x4B1A /* 640x400 16color */
+/* should add more vga modes, etc */
+
+#define CONS_GET 0x4B1B /* get current display mode */
+#define M_B40x25 0 /* 40x25 mono (cga/ega) */
+#define M_C40x25 1 /* 40x25 color (cga/ega) */
+#define M_B80x25 2 /* 80x25 mono (cga/ega) */
+#define M_C80x25 3 /* 80x25 color (cga/ega) */
+#define M_BG320 4 /* 320x200 mono (cga/ega) */
+#define M_CG320 5 /* 320x200 color (cga/ega) */
+#define M_BG640 6 /* 640x200 mono (cga/ega) */
+#define M_EGAMONO80x25 7 /* 80x25 mono (ega) */
+#define M_CG320_D 13 /* ega mode d */
+#define M_CG640_E 14 /* ega mode e */
+#define M_EFAMONOAPA 15 /* ega mode f */
+#define M_CG640x350 16 /* ega mode 10 */
+#define M_ENHMONOAPA2 17 /* ega mode f with ext mem */
+#define M_ENH_CG640 18 /* ega mode 10* */
+#define M_ENH_B40x25 19 /* ega enh 40x25 mono */
+#define M_ENH_C40x25 20 /* ega enh 40x25 color */
+#define M_ENH_B80x25 21 /* ega enh 80x25 mono */
+#define M_ENH_C80x25 22 /* ega enh 80x25 color */
+#define M_ENH_B80x43 0x70 /* ega enh 80x43 mono */
+#define M_ENH_C80x43 0x71 /* ega enh 80x43 color */
+#define M_MCA_MODE 0xff /* monochrome adapter mode */
+#define MCA_GET 0x4B1C /* get mca display mode */
+#define CGA_GET 0x4B1D /* get cga display mode */
+#define EGA_GET 0x4B1E /* get ega display mode */
+
+#define MAPCONS 0x4B1F /* map current video mem into address space */
+#define MAPMONO 0x4B20 /* map mca video mem into address space */
+#define MAPCGA 0x4B21 /* map cga video mem into address space */
+#define MAPEGA 0x4B22 /* map ega video mem into address space */
+#define MAPVGA 0x4B23 /* map vga video mem into address space */
+
+struct port_io_struc {
+ char dir; /* direction in vs out */
+ unsigned short port;
+ char data;
+};
+#define IN_ON_PORT 0x00
+#define OUT_ON_PORT 0x01
+struct port_io_arg {
+ struct port_io_struc args[4];
+};
+#define MCAIO 0x4B24 /* i/o to mca video board */
+#define CGAIO 0x4B25 /* i/o to cga video board */
+#define EGAIO 0x4B26 /* i/o to ega video board */
+#define VGAIO 0x4B27 /* i/o to vga video board */
+
+#define GIO_FONT8x8 0x4B28 /* gets current 8x8 font used */
+#define PIO_FONT8x8 0x4B29 /* use supplied 8x8 font */
+#define GIO_FONT8x14 0x4B2A /* gets current 8x14 font used */
+#define PIO_FONT8x14 0x4B2B /* use supplied 8x14 font */
+#define GIO_FONT8x16 0x4B2C /* gets current 8x16 font used */
+#define PIO_FONT8x16 0x4B2D /* use supplied 8x16 font */
+
+#define MKDIOADDR 32 /* io bitmap size from <linux/sched.h> */
+struct kd_disparam {
+ long type; /* type of display */
+ char *addr; /* display mem address */
+ ushort ioaddr[MKDIOADDR]; /* valid i/o addresses */
+};
+#define KDDISPTYPE 0x4B2E /* gets display info */
+#define KD_MONO 0x01
+#define KD_HERCULES 0x02
+#define KD_CGA 0x03
+#define KD_EGA 0x04
+
+#define KIOCSOUND 0x4B2F /* start sound generation (0 for off) */
+#define KDMKTONE 0x4B30 /* generate tone */
+
+#define KDGETLED 0x4B31 /* return current led flags */
+#define KDSETLED 0x4B32 /* set current led flags */
+#define LED_SCR 0x01 /* scroll lock */
+#define LED_CAP 0x04 /* caps lock */
+#define LED_NUM 0x02 /* num lock */
+
+#define KDGKBTYPE 0x4B33 /* get keyboard type */
+#define KB_84 0x01
+#define KB_101 0x02
+#define KB_OTHER 0x03
+
+#define KDADDIO 0x4B34 /* add i/o port as valid */
+#define KDDELIO 0x4B35 /* del i/o port as valid */
+#define KDENABIO 0x4B36 /* enable i/o to video board */
+#define KDDISABIO 0x4B37 /* disable i/o to video board */
+
+struct kd_quemode {
+ int qsize; /* desired # elem in queue */
+ int signo; /* signal to send when queue not empty */
+ char *qaddr; /* user virt addr of queue */
+};
+#define KDQUEMODE 0x4B38 /* enable/disable special queue mode */
+
+#define KDSBORDER 0x4B39 /* set screen boarder in ega text mode */
+
+#define KDSETMODE 0x4B3A /* set text/grahics mode */
+#define KD_TEXT 0x00
+#define KD_GRAPHICS 0x01
+#define KD_TEXT0 0x02 /* ? */
+#define KD_TEXT1 0x03 /* ? */
+#define KDGETMODE 0x4B3B /* get current mode */
+
+struct kd_memloc {
+ char *vaddr; /* virt addr to map to */
+ char *physaddr; /* phys addr to map from */
+ long length; /* number of bytes */
+ long ioflg; /* enable i/o if set */
+};
+#define KDMAPDISP 0x4B3C /* map display into address space */
+#define KDUNMAPDISP 0x4B3D /* unmap display from address space */
+
+#define KDVDCTYPE 0x4B3E /* return vdc controller/display info */
+
+#define KIOCINFO 0x4B3F /* tell what the device is */
+
+typedef char scrnmap_t;
+#define E_TABSZ 256
+#define GIO_SCRNMAP 0x4B40 /* get screen mapping from kernel */
+#define PIO_SCRNMAP 0x4B41 /* put screen mapping table in kernel */
+
+#define GIO_ATTR 0x4B42 /* get screen attributes */
+#define GIO_COLOR 0x4B43 /* return nonzero if display is color */
+
+#define K_RAW 0x00
+#define K_XLATE 0x01
+#define KDGKBMODE 0x4B44 /* gets current keyboard mode */
+#define KDSKBMODE 0x4B45 /* sets current keyboard mode */
+
+struct kbentry {
+ u_char kb_table;
+ u_char kb_index;
+ u_char kb_value;
+};
+#define K_NORMTAB 0x00
+#define K_SHIFTTAB 0x01
+#define K_ALTTAB 0x02
+#define K_ALTSHIFTTAB 0x03
+#define K_SRQTAB 0x04
+#define KDGKBENT 0x4B46 /* gets one entry in translation table */
+#define KDSKBENT 0x4B47 /* sets one entry in translation table */
+
+#endif /* _KD_H */
diff --git a/include/sys/mman.h b/include/sys/mman.h
new file mode 100644
index 0000000..0a26c1b
--- /dev/null
+++ b/include/sys/mman.h
@@ -0,0 +1,18 @@
+#ifndef _MMAN_H
+#define _MMAN_H
+
+#define PROT_READ 0x1 /* page can be read */
+#define PROT_WRITE 0x2 /* page can be written */
+#define PROT_EXEC 0x4 /* page can be executed */
+#define PROT_NONE 0x0 /* page can not be accessed */
+
+#define MAP_SHARED 1 /* Share changes */
+#define MAP_PRIVATE 2 /* Changes are private */
+#define MAP_TYPE 0xf /* Mask for type of mapping */
+#define MAP_FIXED 0x10 /* Interpret addr exactly */
+
+extern caddr_t mmap(caddr_t addr, size_t len, int prot, int flags, int fd,
+ off_t off);
+extern int munmap(caddr_t addr, size_t len);
+
+#endif /* _MMAN_H */
diff --git a/include/sys/stat.h b/include/sys/stat.h
index e917e9c..b709165 100644
--- a/include/sys/stat.h
+++ b/include/sys/stat.h
@@ -18,6 +18,7 @@ struct stat {
};
#define S_IFMT 00170000
+#define S_IFSOCK 0140000
#define S_IFLNK 0120000
#define S_IFREG 0100000
#define S_IFBLK 0060000
@@ -34,6 +35,7 @@ struct stat {
#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
#define S_IRWXU 00700
#define S_IRUSR 00400
diff --git a/include/sys/types.h b/include/sys/types.h
index 5e220fa..8529532 100644
--- a/include/sys/types.h
+++ b/include/sys/types.h
@@ -31,6 +31,8 @@ typedef unsigned short nlink_t;
typedef int daddr_t;
typedef long off_t;
typedef unsigned char u_char;
+typedef unsigned short u_short;
+typedef unsigned long u_long;
typedef unsigned short ushort;
typedef char *caddr_t;
diff --git a/include/sys/vfs.h b/include/sys/vfs.h
new file mode 100644
index 0000000..c7e113e
--- /dev/null
+++ b/include/sys/vfs.h
@@ -0,0 +1,20 @@
+#ifndef _SYS_VFS_H_
+#define _SYS_VFS_H_
+
+typedef struct {
+ long val[2];
+} fsid_t;
+
+struct statfs {
+ long f_type;
+ long f_bsize;
+ long f_blocks;
+ long f_bfree;
+ long f_bavail;
+ long f_files;
+ long f_ffree;
+ fsid_t f_fsid;
+ long f_spare[7];
+};
+
+#endif
diff --git a/include/sys/vt.h b/include/sys/vt.h
new file mode 100644
index 0000000..092ae0d
--- /dev/null
+++ b/include/sys/vt.h
@@ -0,0 +1,32 @@
+#ifndef _VT_H
+#define _VT_H
+
+/* 0x56 is 'V', to avoid collision with termios and kd */
+
+#define VT_OPENQRY 0x5600 /* find available vt */
+
+struct vt_mode {
+ char mode; /* vt mode */
+ char waitv; /* if set, hang on writes if not active */
+ short relsig; /* signal to raise on release req */
+ short acqsig; /* signal to raise on acquisition */
+ short frsig; /* unused (set to 0) */
+};
+#define VT_GETMODE 0x5601 /* get mode of active vt */
+#define VT_SETMODE 0x5602 /* set mode of active vt */
+#define VT_AUTO 0x00 /* auto vt switching */
+#define VT_PROCESS 0x01 /* process controls switching */
+
+struct vt_stat {
+ ushort v_active; /* active vt */
+ ushort v_signal; /* signal to send */
+ ushort v_state; /* vt bitmask */
+};
+#define VT_GETSTATE 0x5603 /* get global vt state info */
+#define VT_SENDSIG 0x5604 /* signal to send to bitmask of vts */
+
+#define VT_RELDISP 0x5605 /* release display */
+
+#define VT_ACTIVATE 0x5606 /* make vt active */
+
+#endif /* _VT_H */
diff --git a/include/unistd.h b/include/unistd.h
index f297df9..6631444 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -65,96 +65,112 @@
#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 __NR_swapon 87
-#define __NR_reboot 88
-#define __NR_readdir 89
+#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 __NR_swapon 87
+#define __NR_reboot 88
+#define __NR_readdir 89
+#define __NR_mmap 90
+#define __NR_munmap 91
+/*
+ * Not all of these are implemented yet, but these are the
+ * numbers they will use.
+ */
+#define __NR_truncate 92
+#define __NR_ftruncate 93
+#define __NR_fchmod 94
+#define __NR_fchown 95
+#define __NR_getpriority 96
+#define __NR_setpriority 97
+#define __NR_profil 98
+#define __NR_statfs 99
+#define __NR_fstatfs 100
+#define __NR_ioperm 101
/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
#define _syscall0(type,name) \
@@ -212,6 +228,36 @@ errno=-__res; \
return -1; \
}
+#define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \
+type name (atype a, btype b, ctype c, dtype d) \
+{ \
+long __res; \
+__asm__ volatile ("movl %2,%%ebx\n\t" \
+ "int $0x80" \
+ : "=a" (__res) \
+ : "0" (__NR_##name),"b" ((long)(a)),"c" ((long)(b)), \
+ "d" ((long)(c)),"S" ((long)(d))); \
+if (__res>=0) \
+ return (type) __res; \
+errno=-__res; \
+return -1; \
+}
+
+#define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
+type name (atype a,btype b,ctype c,dtype d,etype e) \
+{ \
+long __res; \
+__asm__ volatile ("movl %2,%%ebx\n\t" \
+ "int $0x80" \
+ : "=a" (__res) \
+ : "0" (__NR_##name),"b" ((long)(a)),"c" ((long)(b)), \
+ "d" ((long)(c)),"S" ((long)(d)),"D" ((long)(e))); \
+if (__res>=0) \
+ return (type) __res; \
+errno=-__res; \
+return -1; \
+}
+
#endif /* __LIBRARY__ */
/* XXX - illegal. */
@@ -255,7 +301,7 @@ int kill(pid_t pid, int signal);
int link(const char * filename1, const char * filename2);
off_t lseek(int fildes, off_t offset, int origin);
int mknod(const char * filename, mode_t mode, dev_t dev); /* XXX - shorts */
-int mount(const char * specialfile, const char * dir, int rwflag);
+int mount(const char * specialfile, const char * dir, const char * type, int rwflag);
int nice(int val);
int open(const char * filename, int flag, ...);
int pause(void);
diff --git a/init/main.c b/init/main.c
index d53e00f..378ca99 100644
--- a/init/main.c
+++ b/init/main.c
@@ -25,9 +25,11 @@ static inline _syscall0(int,pause)
static inline _syscall1(int,setup,void *,BIOS)
static inline _syscall0(int,sync)
-#include <linux/tty.h>
#include <linux/sched.h>
+#include <linux/tty.h>
#include <linux/head.h>
+#include <linux/string.h>
+
#include <asm/system.h>
#include <asm/io.h>
@@ -37,10 +39,6 @@ static inline _syscall0(int,sync)
#include <fcntl.h>
#include <sys/types.h>
-#include <linux/fs.h>
-
-#include <string.h>
-
static char printbuf[1024];
extern char *strcpy();
@@ -156,9 +154,8 @@ void start_kernel(void)
#endif
mem_init(main_memory_start,memory_end);
trap_init();
- blk_dev_init();
chr_dev_init();
- tty_init();
+ blk_dev_init();
time_init();
sched_init();
buffer_init(buffer_memory_end);
diff --git a/kernel/Makefile b/kernel/Makefile
index a822e41..0ebd895 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -15,6 +15,8 @@ CC =gcc -nostdinc -I../include
CPP =cpp -nostdinc -I../include
+.S.s:
+ $(CPP) -traditional $< -o $*.s
.c.s:
$(CC) $(CFLAGS) \
-S -o $*.s $<
@@ -26,17 +28,21 @@ CPP =cpp -nostdinc -I../include
OBJS = sched.o sys_call.o traps.o asm.o fork.o \
panic.o printk.o vsprintf.o sys.o exit.o \
- signal.o mktime.o ptrace.o
+ signal.o mktime.o ptrace.o ioport.o
kernel.o: $(OBJS)
$(LD) -r -o kernel.o $(OBJS)
sync
+sys_call.s: sys_call.S
+
+sys_call.o: sys_call.s
+
sched.o: sched.c
$(CC) $(CFLAGS) -fno-omit-frame-pointer -c $<
clean:
- rm -f core *.o *.a tmp_make keyboard.s
+ rm -f core *.o *.a tmp_make sys_call.s
for i in *.c;do rm -f `basename $$i .c`.s;done
(cd chr_drv; make clean)
(cd blk_drv; make clean)
@@ -49,61 +55,55 @@ dep:
cp tmp_make Makefile
(cd chr_drv; make dep)
(cd blk_drv; make dep)
+ (cd math; make dep)
### Dependencies:
-exit.s exit.o : exit.c ../include/errno.h ../include/signal.h \
- ../include/sys/types.h ../include/sys/wait.h ../include/linux/sched.h \
- ../include/linux/head.h ../include/linux/fs.h ../include/sys/dirent.h \
- ../include/limits.h ../include/linux/mm.h ../include/linux/kernel.h \
- ../include/sys/param.h ../include/sys/time.h ../include/time.h \
- ../include/sys/resource.h ../include/linux/tty.h ../include/termios.h \
- ../include/asm/segment.h
-fork.s fork.o : fork.c ../include/errno.h ../include/linux/sched.h \
- ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h \
- ../include/sys/dirent.h ../include/limits.h ../include/linux/mm.h \
- ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h \
- ../include/sys/time.h ../include/time.h ../include/sys/resource.h \
+exit.s exit.o : exit.c ../include/errno.h ../include/signal.h ../include/sys/types.h \
+ ../include/sys/wait.h ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \
+ ../include/sys/dirent.h ../include/limits.h ../include/linux/mm.h ../include/linux/kernel.h \
+ ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h \
+ ../include/linux/tty.h ../include/termios.h ../include/asm/segment.h
+fork.s fork.o : fork.c ../include/errno.h ../include/stddef.h ../include/linux/sched.h \
+ ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h \
+ ../include/limits.h ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h \
+ ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h \
../include/asm/segment.h ../include/asm/system.h
+ioport.s ioport.o : ioport.c ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \
+ ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h ../include/linux/mm.h \
+ ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h ../include/sys/time.h \
+ ../include/time.h ../include/sys/resource.h ../include/errno.h
mktime.s mktime.o : mktime.c ../include/time.h
-panic.s panic.o : panic.c ../include/linux/kernel.h ../include/linux/sched.h \
- ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h \
- ../include/sys/dirent.h ../include/limits.h ../include/linux/mm.h \
- ../include/signal.h ../include/sys/param.h ../include/sys/time.h \
+panic.s panic.o : panic.c ../include/linux/kernel.h ../include/linux/sched.h ../include/linux/head.h \
+ ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h \
+ ../include/linux/mm.h ../include/signal.h ../include/sys/param.h ../include/sys/time.h \
../include/time.h ../include/sys/resource.h
-printk.s printk.o : printk.c ../include/stdarg.h ../include/stddef.h \
- ../include/linux/kernel.h
-ptrace.s ptrace.o : ptrace.c ../include/linux/head.h ../include/linux/kernel.h \
- ../include/linux/sched.h ../include/linux/fs.h ../include/sys/types.h \
- ../include/sys/dirent.h ../include/limits.h ../include/linux/mm.h \
- ../include/signal.h ../include/sys/param.h ../include/sys/time.h \
- ../include/time.h ../include/sys/resource.h ../include/errno.h \
- ../include/asm/segment.h ../include/asm/system.h ../include/sys/ptrace.h
-sched.s sched.o : sched.c ../include/linux/sched.h ../include/linux/head.h \
- ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h \
- ../include/limits.h ../include/linux/mm.h ../include/linux/kernel.h \
- ../include/signal.h ../include/sys/param.h ../include/sys/time.h \
- ../include/time.h ../include/sys/resource.h ../include/linux/timer.h \
- ../include/linux/sys.h ../include/linux/fdreg.h ../include/asm/system.h \
- ../include/asm/io.h ../include/asm/segment.h ../include/errno.h
-signal.s signal.o : signal.c ../include/linux/sched.h ../include/linux/head.h \
- ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h \
- ../include/limits.h ../include/linux/mm.h ../include/linux/kernel.h \
- ../include/signal.h ../include/sys/param.h ../include/sys/time.h \
- ../include/time.h ../include/sys/resource.h ../include/asm/segment.h \
- ../include/sys/wait.h ../include/errno.h
-sys.s sys.o : sys.c ../include/errno.h ../include/linux/sched.h \
- ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h \
- ../include/sys/dirent.h ../include/limits.h ../include/linux/mm.h \
- ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h \
- ../include/sys/time.h ../include/time.h ../include/sys/resource.h \
- ../include/linux/tty.h ../include/termios.h ../include/linux/config.h \
- ../include/asm/segment.h ../include/sys/times.h ../include/sys/utsname.h \
- ../include/string.h
-traps.s traps.o : traps.c ../include/string.h ../include/linux/head.h \
- ../include/linux/sched.h ../include/linux/fs.h ../include/sys/types.h \
- ../include/sys/dirent.h ../include/limits.h ../include/linux/mm.h \
- ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h \
- ../include/sys/time.h ../include/time.h ../include/sys/resource.h \
- ../include/asm/system.h ../include/asm/segment.h ../include/asm/io.h \
+printk.s printk.o : printk.c ../include/stdarg.h ../include/stddef.h ../include/linux/kernel.h
+ptrace.s ptrace.o : ptrace.c ../include/linux/head.h ../include/linux/kernel.h ../include/linux/sched.h \
+ ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h \
+ ../include/linux/mm.h ../include/signal.h ../include/sys/param.h ../include/sys/time.h \
+ ../include/time.h ../include/sys/resource.h ../include/errno.h ../include/asm/segment.h \
+ ../include/asm/system.h ../include/sys/ptrace.h
+sched.s sched.o : sched.c ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \
+ ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h ../include/linux/mm.h \
+ ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h ../include/sys/time.h \
+ ../include/time.h ../include/sys/resource.h ../include/linux/timer.h ../include/linux/sys.h \
+ ../include/linux/fdreg.h ../include/asm/system.h ../include/asm/io.h ../include/asm/segment.h \
+ ../include/errno.h
+signal.s signal.o : signal.c ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \
+ ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h ../include/linux/mm.h \
+ ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h ../include/sys/time.h \
+ ../include/time.h ../include/sys/resource.h ../include/asm/segment.h ../include/sys/wait.h \
../include/errno.h
-vsprintf.s vsprintf.o : vsprintf.c ../include/stdarg.h ../include/string.h
+sys.s sys.o : sys.c ../include/errno.h ../include/linux/sched.h ../include/linux/head.h \
+ ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h \
+ ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h \
+ ../include/sys/time.h ../include/time.h ../include/sys/resource.h ../include/linux/tty.h \
+ ../include/termios.h ../include/linux/config.h ../include/linux/config_rel.h \
+ ../include/linux/config_ver.h ../include/asm/segment.h ../include/sys/times.h \
+ ../include/sys/utsname.h ../include/linux/string.h
+traps.s traps.o : traps.c ../include/linux/string.h ../include/linux/head.h ../include/linux/sched.h \
+ ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h \
+ ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h \
+ ../include/sys/time.h ../include/time.h ../include/sys/resource.h ../include/asm/system.h \
+ ../include/asm/segment.h ../include/asm/io.h ../include/errno.h
+vsprintf.s vsprintf.o : vsprintf.c ../include/stdarg.h ../include/linux/string.h
diff --git a/kernel/asm.s b/kernel/asm.s
index 299e4a9..f565060 100644
--- a/kernel/asm.s
+++ b/kernel/asm.s
@@ -5,138 +5,80 @@
*/
/*
- * asm.s contains the low-level code for most hardware faults.
- * page_exception is handled by the mm, so that isn't here. This
- * file also handles (hopefully) fpu-exceptions due to TS-bit, as
- * the fpu must be properly saved/resored. This hasn't been tested.
+ * asm.s contains the low-level code for interrupts that cannot
+ * result in an task-switch. These are things like the hd- and
+ * floppy-interrupt etc. With these interrupts, we don't have to
+ * care about the stack layout etc.
*/
-.globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op
-.globl _double_fault,_coprocessor_segment_overrun
-.globl _invalid_TSS,_segment_not_present,_stack_segment
-.globl _general_protection,_coprocessor_error,_irq13,_reserved
-.globl _alignment_check
-.globl _page_fault
+.globl _hd_interrupt,_floppy_interrupt,_parallel_interrupt
-_divide_error:
- pushl $0 # no error code
- pushl $_do_divide_error
-error_code:
- push %fs
- push %es
- push %ds
+_hd_interrupt:
+ cld
pushl %eax
- pushl %ebp
- pushl %edi
- pushl %esi
- pushl %edx
pushl %ecx
- pushl %ebx
- cld
- movl $-1, %eax
- xchgl %eax, 0x2c(%esp) # orig_eax (get the error code. )
- xorl %ebx,%ebx # zero ebx
- mov %gs,%bx # get the lower order bits of gs
- xchgl %ebx, 0x28(%esp) # get the address and save gs.
- pushl %eax # push the error code
- lea 52(%esp),%edx
pushl %edx
- movl $0x10,%edx
- mov %dx,%ds
- mov %dx,%es
- mov %dx,%fs
- call *%ebx
- addl $8,%esp
- popl %ebx
- popl %ecx
+ push %ds
+ push %es
+ push %fs
+ movl $0x10,%eax
+ mov %ax,%ds
+ mov %ax,%es
+ movl $0x17,%eax
+ mov %ax,%fs
+ movb $0x20,%al
+ outb %al,$0xA0 # EOI to interrupt controller #1
+ jmp 1f # give port chance to breathe
+1: jmp 1f
+1: outb %al,$0x20
+ andl $0xfffeffff,_timer_active
+ xorl %edx,%edx
+ xchgl _do_hd,%edx
+ testl %edx,%edx
+ jne 1f
+ movl $_unexpected_hd_interrupt,%edx
+1: call *%edx # "interesting" way of handling intr.
+ pop %fs
+ pop %es
+ pop %ds
popl %edx
- popl %esi
- popl %edi
- popl %ebp
+ popl %ecx
popl %eax
- pop %ds
- pop %es
- pop %fs
- pop %gs
- addl $4,%esp
iret
-_debug:
- pushl $0
- pushl $_do_int3 # _do_debug
- jmp error_code
-
-_nmi:
- pushl $0
- pushl $_do_nmi
- jmp error_code
-
-_int3:
- pushl $0
- pushl $_do_int3
- jmp error_code
-
-_overflow:
- pushl $0
- pushl $_do_overflow
- jmp error_code
-
-_bounds:
- pushl $0
- pushl $_do_bounds
- jmp error_code
-
-_invalid_op:
- pushl $0
- pushl $_do_invalid_op
- jmp error_code
-
-_coprocessor_segment_overrun:
- pushl $0
- pushl $_do_coprocessor_segment_overrun
- jmp error_code
-
-_reserved:
- pushl $0
- pushl $_do_reserved
- jmp error_code
+_floppy_interrupt:
+ cld
+ pushl %eax
+ pushl %ecx
+ pushl %edx
+ push %ds
+ push %es
+ push %fs
+ movl $0x10,%eax
+ mov %ax,%ds
+ mov %ax,%es
+ movl $0x17,%eax
+ mov %ax,%fs
+ movb $0x20,%al
+ outb %al,$0x20 # EOI to interrupt controller #1
+ xorl %eax,%eax
+ xchgl _do_floppy,%eax
+ testl %eax,%eax
+ jne 1f
+ movl $_unexpected_floppy_interrupt,%eax
+1: call *%eax # "interesting" way of handling intr.
+ pop %fs
+ pop %es
+ pop %ds
+ popl %edx
+ popl %ecx
+ popl %eax
+ iret
-_irq13:
+_parallel_interrupt:
+ cld
pushl %eax
- xorb %al,%al
- outb %al,$0xF0
movb $0x20,%al
outb %al,$0x20
- jmp 1f
-1: jmp 1f
-1: outb %al,$0xA0
popl %eax
- jmp _coprocessor_error
-
-_double_fault:
- pushl $_do_double_fault
- jmp error_code
-
-_invalid_TSS:
- pushl $_do_invalid_TSS
- jmp error_code
-
-_segment_not_present:
- pushl $_do_segment_not_present
- jmp error_code
-
-_stack_segment:
- pushl $_do_stack_segment
- jmp error_code
-
-_general_protection:
- pushl $_do_general_protection
- jmp error_code
-
-_alignment_check:
- pushl $_do_alignment_check
- jmp error_code
-
-_page_fault:
- pushl $_do_page_fault
- jmp error_code
+ iret
diff --git a/kernel/blk_drv/Makefile b/kernel/blk_drv/Makefile
index 516ab48..3aaf961 100644
--- a/kernel/blk_drv/Makefile
+++ b/kernel/blk_drv/Makefile
@@ -42,36 +42,29 @@ dep:
cp tmp_make Makefile
### Dependencies:
-floppy.s floppy.o : floppy.c ../../include/linux/sched.h ../../include/linux/head.h \
- ../../include/linux/fs.h ../../include/sys/types.h \
- ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h \
- ../../include/linux/kernel.h ../../include/signal.h \
- ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
- ../../include/sys/resource.h ../../include/linux/fdreg.h \
- ../../include/asm/system.h ../../include/asm/io.h \
+floppy.s floppy.o : floppy.c ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \
+ ../../include/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \
+ ../../include/linux/mm.h ../../include/linux/kernel.h ../../include/signal.h \
+ ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h \
+ ../../include/linux/fdreg.h ../../include/asm/system.h ../../include/asm/io.h \
../../include/asm/segment.h blk.h
-hd.s hd.o : hd.c ../../include/errno.h ../../include/linux/config.h \
- ../../include/linux/sched.h ../../include/linux/head.h \
- ../../include/linux/fs.h ../../include/sys/types.h \
- ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h \
- ../../include/linux/kernel.h ../../include/signal.h \
- ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
- ../../include/sys/resource.h ../../include/linux/timer.h \
- ../../include/linux/hdreg.h ../../include/asm/system.h \
- ../../include/asm/io.h ../../include/asm/segment.h blk.h
+hd.s hd.o : hd.c ../../include/errno.h ../../include/linux/config.h ../../include/linux/config_rel.h \
+ ../../include/linux/config_ver.h ../../include/linux/sched.h ../../include/linux/head.h \
+ ../../include/linux/fs.h ../../include/sys/types.h ../../include/sys/dirent.h \
+ ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \
+ ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
+ ../../include/sys/resource.h ../../include/linux/timer.h ../../include/linux/hdreg.h \
+ ../../include/asm/system.h ../../include/asm/io.h ../../include/asm/segment.h \
+ blk.h
ll_rw_blk.s ll_rw_blk.o : ll_rw_blk.c ../../include/errno.h ../../include/linux/sched.h \
- ../../include/linux/head.h ../../include/linux/fs.h \
- ../../include/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \
- ../../include/linux/mm.h ../../include/linux/kernel.h \
- ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h \
- ../../include/time.h ../../include/sys/resource.h \
- ../../include/asm/system.h blk.h
-ramdisk.s ramdisk.o : ramdisk.c ../../include/string.h ../../include/linux/config.h \
- ../../include/linux/sched.h ../../include/linux/head.h \
- ../../include/linux/fs.h ../../include/sys/types.h \
- ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h \
- ../../include/linux/kernel.h ../../include/signal.h \
- ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
- ../../include/sys/resource.h ../../include/linux/minix_fs.h \
- ../../include/asm/system.h ../../include/asm/segment.h \
- ../../include/asm/memory.h blk.h
+ ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/types.h \
+ ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \
+ ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
+ ../../include/sys/resource.h ../../include/asm/system.h blk.h
+ramdisk.s ramdisk.o : ramdisk.c ../../include/linux/string.h ../../include/linux/config.h \
+ ../../include/linux/config_rel.h ../../include/linux/config_ver.h ../../include/linux/sched.h \
+ ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/types.h \
+ ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \
+ ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
+ ../../include/sys/resource.h ../../include/linux/minix_fs.h ../../include/asm/system.h \
+ ../../include/asm/segment.h ../../include/asm/memory.h blk.h
diff --git a/kernel/blk_drv/floppy.c b/kernel/blk_drv/floppy.c
index 82c3583..acda4c9 100644
--- a/kernel/blk_drv/floppy.c
+++ b/kernel/blk_drv/floppy.c
@@ -552,11 +552,22 @@ static int floppy_sizes[] ={
1440,1440,1440,1440
};
+static struct file_operations floppy_fops = {
+ NULL, /* lseek - default */
+ block_read, /* read - general block-dev read */
+ block_write, /* write - general block-dev write */
+ NULL, /* readdir - bad */
+ NULL, /* close - default */
+ NULL, /* select */
+ NULL /* ioctl */
+};
+
void floppy_init(void)
{
outb(current_DOR,FD_DOR);
blk_size[MAJOR_NR] = floppy_sizes;
blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
+ blkdev_fops[MAJOR_NR] = &floppy_fops;
set_intr_gate(0x26,&floppy_interrupt);
outb(inb_p(0x21)&~0x40,0x21);
}
diff --git a/kernel/blk_drv/hd.c b/kernel/blk_drv/hd.c
index 1ca50c9..756ebde 100644
--- a/kernel/blk_drv/hd.c
+++ b/kernel/blk_drv/hd.c
@@ -125,7 +125,7 @@ static void extended_partition(unsigned int dev)
current_minor, hd[current_minor].start_sect,
hd[current_minor].nr_sects,
hd[current_minor].start_sect +
- hd[current_minor].nr_sects);
+ hd[current_minor].nr_sects - 1);
current_minor++;
p++;
/*
@@ -171,7 +171,7 @@ static void check_partition(unsigned int dev)
hd[minor].start_sect = first_sector + p->start_sect;
printk(" part %d start %d size %d end %d \n\r", i,
hd[minor].start_sect, hd[minor].nr_sects,
- hd[minor].start_sect + hd[minor].nr_sects);
+ hd[minor].start_sect + hd[minor].nr_sects - 1);
if ((current_minor & 0x3f) >= 60)
continue;
if (p->sys_ind == EXTENDED_PARTITION) {
@@ -196,7 +196,7 @@ static void check_partition(unsigned int dev)
hd[current_minor].start_sect,
hd[current_minor].nr_sects,
hd[current_minor].start_sect +
- hd[current_minor].nr_sects);
+ hd[current_minor].nr_sects - 1);
}
}
} else
@@ -519,25 +519,17 @@ static void do_hd_request(void)
panic("unknown hd-command");
}
-void hd_init(void)
-{
- blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
- set_intr_gate(0x2E,&hd_interrupt);
- outb_p(inb_p(0x21)&0xfb,0x21);
- outb(inb_p(0xA1)&0xbf,0xA1);
- timer_table[HD_TIMER].fn = hd_times_out;
-}
-
-int hd_ioctl(int dev, int cmd, int arg)
+static int hd_ioctl(struct inode * inode, struct file * file,
+ unsigned int cmd, unsigned int arg)
{
struct hd_geometry *loc = (void *) arg;
+ int dev;
- if (!loc)
+ if (!loc || !inode)
return -EINVAL;
- dev = MINOR(dev) >> 6;
+ dev = MINOR(inode->i_rdev) >> 6;
if (dev >= NR_HD)
return -EINVAL;
-
switch (cmd) {
case HDIO_REQ:
put_fs_byte(hd_info[dev].head,
@@ -551,3 +543,23 @@ int hd_ioctl(int dev, int cmd, int arg)
return -EINVAL;
}
}
+
+static struct file_operations hd_fops = {
+ NULL, /* lseek - default */
+ block_read, /* read - general block-dev read */
+ block_write, /* write - general block-dev write */
+ NULL, /* readdir - bad */
+ NULL, /* close - default */
+ NULL, /* select */
+ hd_ioctl /* ioctl */
+};
+
+void hd_init(void)
+{
+ blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
+ blkdev_fops[MAJOR_NR] = &hd_fops;
+ set_intr_gate(0x2E,&hd_interrupt);
+ outb_p(inb_p(0x21)&0xfb,0x21);
+ outb(inb_p(0xA1)&0xbf,0xA1);
+ timer_table[HD_TIMER].fn = hd_times_out;
+}
diff --git a/kernel/blk_drv/ll_rw_blk.c b/kernel/blk_drv/ll_rw_blk.c
index 7b17306..475863c 100644
--- a/kernel/blk_drv/ll_rw_blk.c
+++ b/kernel/blk_drv/ll_rw_blk.c
@@ -135,7 +135,7 @@ repeat:
if (rw == READ)
req = request+NR_REQUEST;
else
- req = request+((NR_REQUEST*2)/3);
+ req = request+(NR_REQUEST/2);
/* find an empty request */
cli();
while (--req >= request)
diff --git a/kernel/blk_drv/ramdisk.c b/kernel/blk_drv/ramdisk.c
index a7d86fb..c507631 100644
--- a/kernel/blk_drv/ramdisk.c
+++ b/kernel/blk_drv/ramdisk.c
@@ -4,7 +4,7 @@
* Written by Theodore Ts'o, 12/2/91
*/
-#include <string.h>
+#include <linux/string.h>
#include <linux/config.h>
#include <linux/sched.h>
@@ -47,6 +47,16 @@ void do_rd_request(void)
goto repeat;
}
+static struct file_operations rd_fops = {
+ NULL, /* lseek - default */
+ block_read, /* read - general block-dev read */
+ block_write, /* write - general block-dev write */
+ NULL, /* readdir - bad */
+ NULL, /* close - default */
+ NULL, /* select */
+ NULL /* ioctl */
+};
+
/*
* Returns amount of memory which needs to be reserved.
*/
@@ -56,6 +66,7 @@ long rd_init(long mem_start, int length)
char *cp;
blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
+ blkdev_fops[MAJOR_NR] = &rd_fops;
rd_start = (char *) mem_start;
rd_length = length;
cp = rd_start;
diff --git a/kernel/chr_drv/Makefile b/kernel/chr_drv/Makefile
index 0246fc7..8049f2f 100644
--- a/kernel/chr_drv/Makefile
+++ b/kernel/chr_drv/Makefile
@@ -26,7 +26,7 @@ CPP =cpp -nostdinc -I../../include
-c -o $*.o $<
OBJS = tty_io.o console.o keyboard.o serial.o rs_io.o \
- tty_ioctl.o pty.o lp.o
+ tty_ioctl.o pty.o lp.o vt.o mem.o
chr_drv.a: $(OBJS)
$(AR) rcs chr_drv.a $(OBJS)
@@ -46,58 +46,56 @@ dep:
cp tmp_make Makefile
### Dependencies:
-console.s console.o : console.c ../../include/linux/sched.h \
- ../../include/linux/head.h ../../include/linux/fs.h \
+console.s console.o : console.c ../../include/linux/sched.h ../../include/linux/head.h \
+ ../../include/linux/fs.h ../../include/sys/types.h ../../include/sys/dirent.h \
+ ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \
+ ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
+ ../../include/sys/resource.h ../../include/linux/timer.h ../../include/linux/tty.h \
+ ../../include/termios.h ../../include/linux/config.h ../../include/linux/config_rel.h \
+ ../../include/linux/config_ver.h ../../include/asm/io.h ../../include/asm/system.h \
+ ../../include/asm/segment.h ../../include/linux/string.h ../../include/errno.h \
+ ../../include/sys/kd.h vt_kern.h
+lp.s lp.o : lp.c ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \
../../include/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \
- ../../include/linux/mm.h ../../include/linux/kernel.h \
- ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h \
- ../../include/time.h ../../include/sys/resource.h \
- ../../include/linux/timer.h ../../include/linux/tty.h \
- ../../include/termios.h ../../include/linux/config.h \
- ../../include/linux/config_rel.h ../../include/linux/config_ver.h \
- ../../include/asm/io.h ../../include/asm/system.h \
- ../../include/asm/segment.h ../../include/string.h ../../include/errno.h
-lp.s lp.o : lp.c ../../include/linux/lp.h ../../include/errno.h \
- ../../include/linux/kernel.h ../../include/linux/sched.h \
- ../../include/linux/head.h ../../include/linux/fs.h \
+ ../../include/linux/mm.h ../../include/linux/kernel.h ../../include/signal.h \
+ ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h \
+ ../../include/linux/lp.h ../../include/errno.h ../../include/asm/io.h ../../include/asm/segment.h
+mem.s mem.o : mem.c ../../include/errno.h ../../include/sys/types.h ../../include/linux/sched.h \
+ ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/dirent.h \
+ ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \
+ ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
+ ../../include/sys/resource.h ../../include/linux/tty.h ../../include/termios.h \
+ ../../include/asm/segment.h ../../include/asm/io.h
+pty.s pty.o : pty.c ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \
../../include/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \
- ../../include/linux/mm.h ../../include/signal.h ../../include/sys/param.h \
- ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h \
- ../../include/asm/io.h ../../include/asm/segment.h \
- ../../include/checkpoint.h
-pty.s pty.o : pty.c ../../include/linux/tty.h ../../include/termios.h \
- ../../include/sys/types.h ../../include/linux/sched.h \
- ../../include/linux/head.h ../../include/linux/fs.h \
- ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h \
- ../../include/linux/kernel.h ../../include/signal.h \
- ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
- ../../include/sys/resource.h ../../include/asm/system.h \
+ ../../include/linux/mm.h ../../include/linux/kernel.h ../../include/signal.h \
+ ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h \
+ ../../include/linux/tty.h ../../include/termios.h ../../include/asm/system.h \
../../include/asm/io.h
-serial.s serial.o : serial.c ../../include/linux/tty.h ../../include/termios.h \
- ../../include/sys/types.h ../../include/linux/sched.h \
- ../../include/linux/head.h ../../include/linux/fs.h \
- ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h \
- ../../include/linux/kernel.h ../../include/signal.h \
- ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
- ../../include/sys/resource.h ../../include/linux/timer.h \
+serial.s serial.o : serial.c ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \
+ ../../include/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \
+ ../../include/linux/mm.h ../../include/linux/kernel.h ../../include/signal.h \
+ ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h \
+ ../../include/linux/timer.h ../../include/linux/tty.h ../../include/termios.h \
../../include/asm/system.h ../../include/asm/io.h
-tty_io.s tty_io.o : tty_io.c ../../include/ctype.h ../../include/errno.h \
- ../../include/signal.h ../../include/sys/types.h ../../include/unistd.h \
- ../../include/sys/stat.h ../../include/sys/time.h ../../include/time.h \
- ../../include/sys/times.h ../../include/sys/utsname.h \
- ../../include/sys/param.h ../../include/sys/resource.h \
- ../../include/utime.h ../../include/fcntl.h ../../include/linux/sched.h \
- ../../include/linux/head.h ../../include/linux/fs.h \
- ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h \
- ../../include/linux/kernel.h ../../include/linux/tty.h \
- ../../include/termios.h ../../include/asm/segment.h \
- ../../include/asm/system.h
-tty_ioctl.s tty_ioctl.o : tty_ioctl.c ../../include/errno.h ../../include/termios.h \
- ../../include/sys/types.h ../../include/linux/sched.h \
- ../../include/linux/head.h ../../include/linux/fs.h \
- ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h \
- ../../include/linux/kernel.h ../../include/signal.h \
- ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
- ../../include/sys/resource.h ../../include/linux/tty.h \
- ../../include/asm/io.h ../../include/asm/segment.h \
+tty_io.s tty_io.o : tty_io.c ../../include/linux/ctype.h ../../include/errno.h ../../include/signal.h \
+ ../../include/sys/types.h ../../include/unistd.h ../../include/sys/stat.h ../../include/sys/time.h \
+ ../../include/time.h ../../include/sys/times.h ../../include/sys/utsname.h ../../include/sys/param.h \
+ ../../include/sys/resource.h ../../include/utime.h ../../include/fcntl.h ../../include/linux/sched.h \
+ ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/dirent.h \
+ ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \
+ ../../include/linux/tty.h ../../include/termios.h ../../include/asm/segment.h \
../../include/asm/system.h
+tty_ioctl.s tty_ioctl.o : tty_ioctl.c ../../include/errno.h ../../include/termios.h ../../include/sys/types.h \
+ ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \
+ ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \
+ ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
+ ../../include/sys/resource.h ../../include/linux/tty.h ../../include/asm/io.h \
+ ../../include/asm/segment.h ../../include/asm/system.h
+vt.s vt.o : vt.c ../../include/errno.h ../../include/sys/types.h ../../include/sys/kd.h \
+ ../../include/sys/vt.h ../../include/asm/io.h ../../include/asm/segment.h ../../include/linux/sched.h \
+ ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/dirent.h \
+ ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \
+ ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
+ ../../include/sys/resource.h ../../include/linux/tty.h ../../include/termios.h \
+ vt_kern.h
diff --git a/kernel/chr_drv/console.c b/kernel/chr_drv/console.c
index 2d62be3..01421e5 100644
--- a/kernel/chr_drv/console.c
+++ b/kernel/chr_drv/console.c
@@ -40,9 +40,12 @@
#include <asm/system.h>
#include <asm/segment.h>
-#include <string.h>
+#include <linux/string.h>
#include <errno.h>
+#include <sys/kd.h>
+#include "vt_kern.h"
+
#define DEF_TERMIOS \
(struct termios) { \
ICRNL, \
@@ -79,11 +82,14 @@ static void unblank_screen(void);
int NR_CONSOLES = 0;
+extern void vt_init(void);
extern void keyboard_interrupt(void);
extern void set_leds(void);
extern unsigned char kapplic;
extern unsigned char kleds;
extern unsigned char kmode;
+extern unsigned char kraw;
+extern unsigned char ke0;
unsigned long video_num_columns; /* Number of text columns */
unsigned long video_num_lines; /* Number of test lines */
@@ -120,6 +126,8 @@ static struct {
unsigned char vc_kbdapplic;
unsigned char vc_kbdleds;
unsigned char vc_kbdmode;
+ unsigned char vc_kbdraw;
+ unsigned char vc_kbde0;
char * vc_translate;
} vc_cons [MAX_CONSOLES];
@@ -153,6 +161,8 @@ static int console_blanked = 0;
#define iscolor (vc_cons[currcons].vc_iscolor)
#define kbdapplic (vc_cons[currcons].vc_kbdapplic)
#define kbdmode (vc_cons[currcons].vc_kbdmode)
+#define kbdraw (vc_cons[currcons].vc_kbdraw)
+#define kbde0 (vc_cons[currcons].vc_kbde0)
#define kbdleds (vc_cons[currcons].vc_kbdleds)
int blankinterval = 5*60*HZ;
@@ -970,6 +980,8 @@ void con_init(void)
translate = NORM_TRANS;
kbdleds = 2;
kbdmode = 0;
+ kbdraw = 0;
+ kbde0 = 0;
kbdapplic = 0;
vc_cons[0].vc_bold_attr = -1;
@@ -1000,16 +1012,22 @@ void con_init(void)
a=inb_p(0x61);
outb_p(a|0x80,0x61);
outb_p(a,0x61);
+
+ vt_init();
}
void kbdsave(int new_console)
{
int currcons = fg_console;
kbdmode = kmode;
+ kbdraw = kraw;
+ kbde0 = ke0;
kbdleds = kleds;
kbdapplic = kapplic;
currcons = new_console;
kmode = (kmode & 0x3F) | (kbdmode & 0xC0);
+ kraw = kbdraw;
+ ke0 = kbde0;
kleds = kbdleds;
kapplic = kbdapplic;
set_leds();
@@ -1120,6 +1138,8 @@ void console_print(const char * b)
if (currcons<0 || currcons>=NR_CONSOLES)
currcons = 0;
+ if (vt_info[currcons].mode == KD_GRAPHICS)
+ return; /* no output in graphics mode */
while (c = *(b++)) {
if (c == 10) {
cr(currcons);
diff --git a/kernel/chr_drv/keyboard.S b/kernel/chr_drv/keyboard.S
index fa5e2b5..099cfc9 100644
--- a/kernel/chr_drv/keyboard.S
+++ b/kernel/chr_drv/keyboard.S
@@ -5,6 +5,15 @@
*/
/*
+ * NOTE! This file no longer contains the low-level keyboard interrupt:
+ * that is now in kernel/sys_call.S. The reason is that the low-level
+ * interrupt must keep track of stack frames for signals etc.
+ *
+ * Thus it should be very easy to rewrite this in C - I just haven't
+ * bothered.
+ */
+
+/*
* Thanks to Alfred Leung for US keyboard patches
* Wolfgang Thiel for German keyboard patches
* Marc Corsini for the French keyboard
@@ -22,11 +31,14 @@
.text
.globl _hard_reset_now
-.globl _keyboard_interrupt
+.globl _do_keyboard_interrupt
+.globl _do_keyboard
.globl _kapplic
.globl _kmode
.globl _kleds
.globl _set_leds
+.globl _kraw
+.globl _ke0
/*
* these are for the keyboard read functions
@@ -41,24 +53,15 @@ buf = 16
_kapplic: .byte 0
_kmode: .byte 0 /* caps, alt, ctrl and shift mode */
_kleds: .byte 2 /* num-lock, caps, scroll-lock mode (nom-lock on) */
-e0: .byte 0
+_ke0: .byte 0
+_kraw: .byte 0
/*
- * con_int is the real interrupt routine that reads the
+ * do_keyboard is the real interrupt routine that reads the
* keyboard scan-code and converts it into the appropriate
* ascii character(s).
*/
-_keyboard_interrupt:
- cld
- pushl %eax
- pushl %ebx
- pushl %ecx
- pushl %edx
- push %ds
- push %es
- movl $0x10,%eax
- mov %ax,%ds
- mov %ax,%es
+_do_keyboard:
xorl %eax,%eax /* %eax is scan code */
inb $0x60,%al
pushl %eax
@@ -77,7 +80,14 @@ _keyboard_interrupt:
1: jmp 1f
1: movb $0x20,%al
outb %al,$0x20
+ cmpb $0,_kraw
+ je 1f
+ xorl %ebx,%ebx /* if raw kbd, just put scancode */
popl %eax
+ sti
+ call put_queue
+ jmp postkey
+1: popl %eax
movl $1,%ebx
cmpb $0xE0,%al
je end_intr
@@ -86,17 +96,12 @@ _keyboard_interrupt:
je end_intr
sti
call key_table(,%eax,4)
+postkey:
call _do_keyboard_interrupt
movl $0,%ebx
end_intr:
- movb %bl,e0
- pop %es
- pop %ds
- popl %edx
- popl %ecx
- popl %ebx
- popl %eax
- iret
+ movb %bl,_ke0
+ ret
/*
* This routine fills the buffer with max 8 bytes, taken from
@@ -129,7 +134,7 @@ put_queue:
ctrl: movb $0x04,%al
jmp 1f
alt: movb $0x10,%al
-1: cmpb $0,e0
+1: cmpb $0,_ke0
je 2f
addb %al,%al
2: orb %al,_kmode
@@ -137,7 +142,7 @@ alt: movb $0x10,%al
unctrl: movb $0x04,%al
jmp 1f
unalt: movb $0x10,%al
-1: cmpb $0,e0
+1: cmpb $0,_ke0
je 2f
addb %al,%al
2: notb %al
@@ -215,7 +220,7 @@ cursor:
je cur2
testb $0x30,_kmode
jne _ctrl_alt_del
-cur2: cmpb $0x01,e0 /* e0 forces cursor movement */
+cur2: cmpb $0x01,_ke0 /* _ke0 forces cursor movement */
je cur
testb $0x03,_kmode /* shift forces cursor */
jne cur
@@ -349,7 +354,7 @@ shift_map:
alt_map:
.byte 0,0
- .ascii "\0@\0$\0\0{[]}\\\0"
+ .ascii "\0@\243$\0\0{[]}\\\0"
.byte 0,0
.byte 0,0,0,0,0,0,0,0,0,0,0
.byte '~,13,0
@@ -433,7 +438,7 @@ key_map:
shift_map:
.byte 0,27
- .ascii "!\"#$%^&*()_+"
+ .ascii "!\"\243$%^&*()_+"
.byte 127,9
.ascii "QWERTYUIOP{}"
.byte 13,0
@@ -654,7 +659,7 @@ none: ret
* the scan code for slash means that the numeric keypad
* slash was pushed.
*/
-slash: cmpb $1,e0
+slash: cmpb $1,_ke0
jne do_self
cmpb $1,_kapplic
jne notmapplic
@@ -676,7 +681,7 @@ notsapplic:
xorl %ebx,%ebx
jmp put_queue
-enter: cmpb $1,e0
+enter: cmpb $1,_ke0
jne do_self
cmpb $1,_kapplic
jne do_self
diff --git a/kernel/chr_drv/lp.c b/kernel/chr_drv/lp.c
index 0f6e88f..53d4c9b 100644
--- a/kernel/chr_drv/lp.c
+++ b/kernel/chr_drv/lp.c
@@ -3,12 +3,16 @@
james_r_wiegand Exp james_r_wiegand $
*/
+/*
+ * Edited by Linus - cleaner interface etc. Still not using interrupts, so
+ * it eats more resources than necessary, but it was easy to code this way...
+ */
+
+#include <linux/sched.h>
#define __LP_C__
#include <linux/lp.h>
-#include <checkpoint.h>
-
-int lp_reset(int minor)
+static int lp_reset(int minor)
{
int testvalue;
@@ -20,31 +24,7 @@ int lp_reset(int minor)
return LP_S(minor);
}
-void lp_init(void)
-{
- int offset = 0;
- unsigned int testvalue = 0;
- int count = 0;
-
- /* take on all known port values */
- for (offset = 0; offset < LP_NO; offset++) {
- /* write to port & read back to check */
- outb( LP_DUMMY, LP_B(offset));
- for (testvalue = 0 ; testvalue < LP_DELAY ; testvalue++)
- ;
- testvalue = inb(LP_B(offset));
- if (testvalue != 255) {
- LP_F(offset) |= LP_EXIST;
- lp_reset(offset);
- printk("lp_init: lp%d exists (%d)\n", offset, testvalue);
- count++;
- }
- }
- if (count == 0)
- printk("lp_init: no lp devices found\n");
-}
-
-int lp_char(char lpchar, int minor)
+static int lp_char(char lpchar, int minor)
{
int retval = 0;
unsigned long count = 0;
@@ -67,61 +47,92 @@ int lp_char(char lpchar, int minor)
return LP_S(minor);
}
-int lp_write(unsigned minor, char *buf, int count)
+static int lp_write(struct inode * inode, struct file * file, char * buf, int count)
{
int retval;
- int loop;
- int tcount;
+ unsigned int minor = MINOR(inode->i_rdev);
char c, *temp = buf;
- if (minor > LP_NO - 1)
+ if (minor >= LP_NO)
return -ENODEV;
if ((LP_F(minor) & LP_EXIST) == 0)
return -ENODEV;
-
-/* if we aren't the "owner task", check if the old owner has died... */
- if (LP_T(minor) != current->pid && (LP_F(minor) & LP_BUSY)) {
- for(tcount = 0; tcount < NR_TASKS; tcount++) {
- if (!task[tcount])
- continue;
- if (task[tcount]->state == TASK_ZOMBIE)
- continue;
- if (task[tcount]->pid == LP_T(minor)) {
- tcount = -1;
- break;
- }
- }
- if (tcount == -1)
- return -EBUSY;
- }
-
LP_T(minor) = current->pid;
LP_F(minor) |= LP_BUSY;
LP_R(minor) = count;
temp = buf;
-
- for (loop = 0 ; loop < count ; loop++, temp++) {
- c = get_fs_byte(temp);
+ while (count > 0) {
+ c = get_fs_byte(temp++);
retval = lp_char(c, minor);
- LP_R(minor)--;
+ count--;
if (retval & LP_POUTPA) {
LP_F(minor) |= LP_NOPA;
- return loop?loop:-ENOSPC;
+ return temp-buf?temp-buf:-ENOSPC;
} else
LP_F(minor) &= ~LP_NOPA;
if (!(retval & LP_PSELECD)) {
LP_F(minor) &= ~LP_SELEC;
- return loop?loop:-EFAULT;
+ return temp-buf?temp-buf:-EFAULT;
} else
LP_F(minor) &= ~LP_SELEC;
/* not offline or out of paper. on fire? */
if (!(retval & LP_PERRORP)) {
LP_F(minor) |= LP_ERR;
- return loop?loop:-EIO;
+ return temp-buf?temp-buf:-EIO;
} else
LP_F(minor) &= ~LP_SELEC;
}
- return count;
+ return temp-buf;
+}
+
+static int lp_read(struct inode * inode, struct file * file, char * buf, int count)
+{
+ return -EINVAL;
+}
+
+static int lp_lseek(struct inode * inode, struct file * file, off_t offset, int origin)
+{
+ return -EINVAL;
+}
+
+static int lp_readdir(struct inode * inode, struct file * file, struct dirent * de, int count)
+{
+ return -ENOTDIR;
+}
+
+static struct file_operations lp_fops = {
+ lp_lseek,
+ lp_read,
+ lp_write,
+ lp_readdir,
+ NULL, /* lp_close */
+ NULL, /* lp_select */
+ NULL /* lp_ioctl */
+};
+
+void lp_init(void)
+{
+ int offset = 0;
+ unsigned int testvalue = 0;
+ int count = 0;
+
+ chrdev_fops[6] = &lp_fops;
+ /* take on all known port values */
+ for (offset = 0; offset < LP_NO; offset++) {
+ /* write to port & read back to check */
+ outb( LP_DUMMY, LP_B(offset));
+ for (testvalue = 0 ; testvalue < LP_DELAY ; testvalue++)
+ ;
+ testvalue = inb(LP_B(offset));
+ if (testvalue != 255) {
+ LP_F(offset) |= LP_EXIST;
+ lp_reset(offset);
+ printk("lp_init: lp%d exists (%d)\n", offset, testvalue);
+ count++;
+ }
+ }
+ if (count == 0)
+ printk("lp_init: no lp devices found\n");
}
diff --git a/kernel/chr_drv/mem.c b/kernel/chr_drv/mem.c
new file mode 100644
index 0000000..db3138f
--- /dev/null
+++ b/kernel/chr_drv/mem.c
@@ -0,0 +1,238 @@
+/*
+ * linux/kernel/chr_drv/mem.c
+ *
+ * (C) 1991 Linus Torvalds
+ */
+
+#include <errno.h>
+#include <sys/types.h>
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+
+static int read_ram(struct inode * inode, struct file * file,char * buf, int count)
+{
+ return -EIO;
+}
+
+static int write_ram(struct inode * inode, struct file * file,char * buf, int count)
+{
+ return -EIO;
+}
+
+static int read_mem(struct inode * inode, struct file * file,char * buf, int count)
+{
+ unsigned long addr;
+ char *tmp;
+ unsigned long pde, pte, page;
+ int i;
+
+ if (count < 0)
+ return -EINVAL;
+ addr = file->f_pos;
+ tmp = buf;
+ while (count > 0) {
+ pde = (unsigned long) pg_dir + (addr >> 20 & 0xffc);
+ if (!((pte = *((unsigned long *) pde)) & 1))
+ break;
+ pte &= 0xfffff000;
+ pte += (addr >> 10) & 0xffc;
+ if (((page = *((unsigned long *) pte)) & 1) == 0)
+ break;
+/*
+ if ((page & 2) == 0)
+ un_wp_page((unsigned long *) pte);
+*/
+ page &= 0xfffff000;
+ page += addr & 0xfff;
+ i = 4096-(addr & 0xfff);
+ if (i > count)
+ i = count;
+ memcpy_tofs(tmp,(void *) page,i);
+ addr += i;
+ tmp += i;
+ count -= i;
+ }
+ file->f_pos = addr;
+ return tmp-buf;
+}
+
+static int write_mem(struct inode * inode, struct file * file,char * buf, int count)
+{
+ unsigned long addr;
+ char *tmp;
+ unsigned long pde, pte, page;
+ int i;
+
+ if (count < 0)
+ return -EINVAL;
+ addr = file->f_pos;
+ tmp = buf;
+ while (count > 0) {
+ pde = (unsigned long) pg_dir + (addr >> 20 & 0xffc);
+ if (!((pte = *((unsigned long *) pde)) & 1))
+ break;
+ pte &= 0xfffff000;
+ pte += (addr >> 10) & 0xffc;
+ if (((page = *((unsigned long *) pte)) & 1) == 0)
+ break;
+ if ((page & 2) == 0)
+ un_wp_page((unsigned long *) pte);
+ page &= 0xfffff000;
+ page += addr & 0xfff;
+ i = 4096-(addr & 0xfff);
+ if (i > count)
+ i = count;
+ memcpy_fromfs((void *) page,tmp,i);
+ addr += i;
+ tmp += i;
+ count -= i;
+ }
+ file->f_pos = addr;
+ return tmp-buf;
+}
+
+static int read_kmem(struct inode * inode, struct file * file,char * buf, int count)
+{
+ unsigned long p = file->f_pos;
+
+ if (count < 0)
+ return -EINVAL;
+ if (p >= HIGH_MEMORY)
+ return 0;
+ if (count > HIGH_MEMORY - p)
+ count = HIGH_MEMORY - p;
+ memcpy_tofs(buf,(void *) p,count);
+ file->f_pos += count;
+ return count;
+}
+
+static int write_kmem(struct inode * inode, struct file * file,char * buf, int count)
+{
+ unsigned long p = file->f_pos;
+
+ if (count < 0)
+ return -EINVAL;
+ if (p >= HIGH_MEMORY)
+ return 0;
+ if (count > HIGH_MEMORY - p)
+ count = HIGH_MEMORY - p;
+ memcpy_fromfs((void *) p,buf,count);
+ file->f_pos += count;
+ return count;
+}
+
+static int read_port(struct inode * inode,struct file * file,char * buf, int count)
+{
+ unsigned int i = file->f_pos;
+ char * tmp = buf;
+
+ while (count-- > 0 && i < 65536) {
+ put_fs_byte(inb(i),tmp);
+ i++;
+ tmp++;
+ }
+ file->f_pos = i;
+ return tmp-buf;
+}
+
+static int write_port(struct inode * inode,struct file * file,char * buf, int count)
+{
+ unsigned int i = file->f_pos;
+ char * tmp = buf;
+
+ while (count-- > 0 && i < 65536) {
+ outb(get_fs_byte(tmp),i);
+ i++;
+ tmp++;
+ }
+ file->f_pos = i;
+ return tmp-buf;
+}
+
+/*
+ * The memory devices use the full 32 bits of the offset, and so we cannot
+ * check against negative addresses: they are ok. The return value is weird,
+ * though, in that case (0).
+ *
+ * also note that seeking relative to the "end of file" isn't supported:
+ * it has no meaning, so it returns -EINVAL.
+ */
+static int mem_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
+{
+ switch (orig) {
+ case 0:
+ file->f_pos = offset;
+ return file->f_pos;
+ case 1:
+ file->f_pos += offset;
+ return file->f_pos;
+ default:
+ return -EINVAL;
+ }
+ if (file->f_pos < 0)
+ return 0;
+ return file->f_pos;
+}
+
+static int mem_read(struct inode * inode, struct file * file, char * buf, int count)
+{
+ switch (MINOR(inode->i_rdev)) {
+ case 0:
+ return read_ram(inode,file,buf,count);
+ case 1:
+ return read_mem(inode,file,buf,count);
+ case 2:
+ return read_kmem(inode,file,buf,count);
+ case 3:
+ return 0; /* /dev/null */
+ case 4:
+ return read_port(inode,file,buf,count);
+ default:
+ return -ENODEV;
+ }
+}
+
+static int mem_write(struct inode * inode, struct file * file, char * buf, int count)
+{
+ switch (MINOR(inode->i_rdev)) {
+ case 0:
+ return write_ram(inode,file,buf,count);
+ case 1:
+ return write_mem(inode,file,buf,count);
+ case 2:
+ return write_kmem(inode,file,buf,count);
+ case 3:
+ return count; /* /dev/null */
+ case 4:
+ return write_port(inode,file,buf,count);
+ default:
+ return -ENODEV;
+ }
+}
+
+static int mem_readdir(struct inode * inode, struct file * file, struct dirent * de, int count)
+{
+ return -ENOTDIR;
+}
+
+static struct file_operations mem_fops = {
+ mem_lseek,
+ mem_read,
+ mem_write,
+ mem_readdir,
+ NULL, /* mem_close */
+ NULL, /* mem_select */
+ NULL /* mem_ioctl */
+};
+
+void chr_dev_init(void)
+{
+ chrdev_fops[1] = &mem_fops;
+ tty_init();
+ lp_init();
+}
diff --git a/kernel/chr_drv/pty.c b/kernel/chr_drv/pty.c
index aed5b6e..0647ce8 100644
--- a/kernel/chr_drv/pty.c
+++ b/kernel/chr_drv/pty.c
@@ -12,8 +12,9 @@
* void spty_write(struct tty_struct * queue);
*/
-#include <linux/tty.h>
#include <linux/sched.h>
+#include <linux/tty.h>
+
#include <asm/system.h>
#include <asm/io.h>
diff --git a/kernel/chr_drv/serial.c b/kernel/chr_drv/serial.c
index bd55ec1..f626071 100644
--- a/kernel/chr_drv/serial.c
+++ b/kernel/chr_drv/serial.c
@@ -13,9 +13,10 @@
* and all interrupts pertaining to serial IO.
*/
-#include <linux/tty.h>
#include <linux/sched.h>
#include <linux/timer.h>
+#include <linux/tty.h>
+
#include <asm/system.h>
#include <asm/io.h>
diff --git a/kernel/chr_drv/tty_io.c b/kernel/chr_drv/tty_io.c
index 511860a..8e376bb 100644
--- a/kernel/chr_drv/tty_io.c
+++ b/kernel/chr_drv/tty_io.c
@@ -11,7 +11,7 @@
* Kill-line thanks to John T Kohl, who also corrected VMIN = VTIME = 0.
*/
-#include <ctype.h>
+#include <linux/ctype.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
@@ -272,7 +272,7 @@ int tty_signal(int sig, struct tty_struct *tty)
/* (but restart after we continue) */
}
-int tty_read(unsigned channel, char * buf, int nr, unsigned short flags)
+static int read_chan(unsigned int channel, struct file * file, char * buf, int nr)
{
struct tty_struct * tty;
struct tty_struct * other_tty = NULL;
@@ -304,7 +304,7 @@ int tty_read(unsigned channel, char * buf, int nr, unsigned short flags)
current->timeout = time + jiffies;
time = 0;
}
- if (flags & O_NONBLOCK)
+ if (file->f_flags & O_NONBLOCK)
time = current->timeout = 0;
if (minimum>nr)
minimum = nr;
@@ -355,12 +355,12 @@ int tty_read(unsigned channel, char * buf, int nr, unsigned short flags)
return b-buf;
if (current->signal & ~current->blocked)
return -ERESTARTSYS;
- if (flags & O_NONBLOCK)
+ if (file->f_flags & O_NONBLOCK)
return -EAGAIN;
return 0;
}
-int tty_write(unsigned channel, char * buf, int nr)
+static int write_chan(unsigned int channel, struct file * file, char * buf, int nr)
{
static cr_flag=0;
struct tty_struct * tty;
@@ -412,14 +412,62 @@ int tty_write(unsigned channel, char * buf, int nr)
return 0;
}
-void chr_dev_init(void)
+static int tty_read(struct inode * inode, struct file * file, char * buf, int count)
{
+ return read_chan(current->tty,file,buf,count);
}
+static int ttyx_read(struct inode * inode, struct file * file, char * buf, int count)
+{
+ return read_chan(MINOR(inode->i_rdev),file,buf,count);
+}
+
+static int tty_write(struct inode * inode, struct file * file, char * buf, int count)
+{
+ return write_chan(current->tty,file,buf,count);
+}
+
+static int ttyx_write(struct inode * inode, struct file * file, char * buf, int count)
+{
+ return write_chan(MINOR(inode->i_rdev),file,buf,count);
+}
+
+static int tty_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
+{
+ return -EBADF;
+}
+
+static int tty_readdir(struct inode * inode, struct file * file, struct dirent * de, int count)
+{
+ return -ENOTDIR;
+}
+
+static struct file_operations tty_fops = {
+ tty_lseek,
+ tty_read,
+ tty_write,
+ tty_readdir,
+ NULL, /* tty_close */
+ NULL, /* tty_select */
+ tty_ioctl /* tty_ioctl */
+};
+
+static struct file_operations ttyx_fops = {
+ tty_lseek,
+ ttyx_read,
+ ttyx_write,
+ tty_readdir,
+ NULL, /* ttyx_close */
+ NULL, /* ttyx_select */
+ tty_ioctl /* ttyx_ioctl */
+};
+
void tty_init(void)
{
int i;
+ chrdev_fops[4] = &ttyx_fops;
+ chrdev_fops[5] = &tty_fops;
for (i=0 ; i < QUEUES ; i++)
tty_queues[i] = (struct tty_queue) {0,0,0,0,""};
rs_queues[0] = (struct tty_queue) {0x3f8,0,0,0,""};
@@ -507,5 +555,4 @@ void tty_init(void)
rs_init();
printk("%d virtual consoles\n\r",NR_CONSOLES);
printk("%d pty's\n\r",NR_PTYS);
- lp_init();
}
diff --git a/kernel/chr_drv/tty_ioctl.c b/kernel/chr_drv/tty_ioctl.c
index a8594f0..9601268 100644
--- a/kernel/chr_drv/tty_ioctl.c
+++ b/kernel/chr_drv/tty_ioctl.c
@@ -6,6 +6,7 @@
#include <errno.h>
#include <termios.h>
+#include <sys/types.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -19,6 +20,7 @@ extern int session_of_pgrp(int pgrp);
extern int do_screendump(int arg);
extern int kill_pg(int pgrp, int sig, int priv);
extern int tty_signal(int sig, struct tty_struct *tty);
+extern int vt_ioctl(struct tty_struct *tty, int dev, int cmd, int arg);
static unsigned short quotient[] = {
0, 2304, 1536, 1047, 857,
@@ -203,18 +205,20 @@ static int get_window_size(struct tty_struct * tty, struct winsize * ws)
return 0;
}
-int tty_ioctl(int dev, int cmd, int arg)
+int tty_ioctl(struct inode * inode, struct file * file,
+ unsigned int cmd, unsigned int arg)
{
struct tty_struct * tty;
struct tty_struct * other_tty;
int pgrp;
+ int dev;
- if (MAJOR(dev) == 5) {
+ if (MAJOR(inode->i_rdev) == 5) {
dev = current->tty;
if (dev<0)
return -EINVAL;
} else
- dev=MINOR(dev);
+ dev = MINOR(inode->i_rdev);
tty = tty_table + (dev ? ((dev < 64)? dev-1:dev) : fg_console);
if (IS_A_PTY(dev))
@@ -355,6 +359,6 @@ int tty_ioctl(int dev, int cmd, int arg)
return -EINVAL;
}
default:
- return -EINVAL;
+ return vt_ioctl(tty, dev, cmd, arg);
}
}
diff --git a/kernel/chr_drv/vt.c b/kernel/chr_drv/vt.c
new file mode 100644
index 0000000..549cb93
--- /dev/null
+++ b/kernel/chr_drv/vt.c
@@ -0,0 +1,170 @@
+/*
+ * kernel/chr_drv/vt.c
+ *
+ * (C) 1992 obz under the linux copyright
+ */
+
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/kd.h>
+#include <sys/vt.h>
+
+#include <asm/io.h>
+#include <asm/segment.h>
+
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/kernel.h>
+
+#include "vt_kern.h"
+
+/*
+ * console (vt and kd) routines, as defined by usl svr4 manual
+ */
+
+struct vt_info vt_info[MAX_CONSOLES];
+
+extern int NR_CONSOLES;
+extern unsigned char kleds;
+extern unsigned char kraw;
+extern unsigned char ke0;
+
+extern int sys_ioperm(unsigned long from, unsigned long num, int on);
+extern void set_leds(void);
+
+/*
+ * these are the valid i/o ports we're allowed to change. they map all the
+ * video ports
+ */
+#define GPFIRST 0x3b4
+#define GPLAST 0x3df
+#define GPNUM (GPLAST - GPFIRST + 1)
+
+/*
+ * turns on sound of some freq. 0 turns it off.
+ * stolen from console.c, so i'm not sure if its the correct interpretation
+ */
+static int
+kiocsound(unsigned int freq)
+{
+ if (freq == 0) {
+ /* disable counter 2 */
+ outb(inb_p(0x61)&0xFC, 0x61);
+ }
+ else {
+ /* enable counter 2 */
+ outb_p(inb_p(0x61)|3, 0x61);
+ /* set command for counter 2, 2 byte write */
+ outb_p(0xB6, 0x43);
+ /* select desired HZ */
+ outb_p(freq & 0xff, 0x42);
+ outb((freq >> 8) & 0xff, 0x42);
+ }
+ return 0;
+}
+
+int
+vt_ioctl(struct tty_struct *tty, int dev, int cmd, int arg)
+{
+ switch (cmd) {
+ case KIOCSOUND:
+ return kiocsound((unsigned int)arg);
+
+ case KDGKBTYPE:
+ verify_area((void *) arg, sizeof(unsigned char));
+ put_fs_byte(KB_101, (unsigned char *) arg);
+ return 0;
+
+ case KDADDIO:
+ case KDDELIO:
+ /*
+ * KDADDIO and KDDELIO may be able to add ports beyond what
+ * we reject here, but to be safe...
+ */
+ if (arg < GPFIRST || arg > GPLAST)
+ return -EINVAL;
+ return sys_ioperm(arg, 1, (cmd == KDADDIO)) ? -ENXIO : 0;
+
+ case KDENABIO:
+ case KDDISABIO:
+ return sys_ioperm(GPFIRST, GPNUM, (cmd == KDENABIO)) ? -ENXIO : 0;
+
+ case KDSETMODE:
+ /*
+ * currently, setting the mode from KD_TEXT to KD_GRAPHICS
+ * doesn't do a whole lot. i'm not sure if it should do any
+ * restoration of modes or what...
+ */
+ switch (arg) {
+ case KD_GRAPHICS:
+ break;
+ case KD_TEXT0:
+ case KD_TEXT1:
+ arg = KD_TEXT;
+ case KD_TEXT:
+ break;
+ default:
+ return -EINVAL;
+ }
+ vt_info[fg_console].mode = arg;
+ return 0;
+ case KDGETMODE:
+ verify_area((void *) arg, sizeof(unsigned long));
+ put_fs_long(vt_info[fg_console].mode, (unsigned long *) arg);
+ return 0;
+
+ case KDMAPDISP:
+ case KDUNMAPDISP:
+ /*
+ * these work like a combination of mmap and KDENABIO.
+ * this could be easily finished.
+ */
+ return -EINVAL;
+
+ case KDSKBMODE:
+ if (arg == K_RAW) {
+ kraw = 1;
+ ke0 = 0;
+ }
+ else if (arg == K_XLATE) {
+ kraw = 0;
+ }
+ else
+ return -EINVAL;
+ return 0;
+ case KDGKBMODE:
+ verify_area((void *) arg, sizeof(unsigned long));
+ put_fs_long(kraw ? K_RAW : K_XLATE, (unsigned long *) arg);
+ return 0;
+
+ case KDGETLED:
+ verify_area((void *) arg, sizeof(unsigned char));
+ put_fs_byte((((kleds & 1) ? LED_SCR : 0) |
+ ((kleds & 2) ? LED_NUM : 0) |
+ ((kleds & 4) ? LED_CAP : 0)),
+ (unsigned char *) arg);
+ return 0;
+ case KDSETLED:
+ if (arg & ~7)
+ return -EINVAL;
+ kleds = (((arg & LED_SCR) ? 1 : 0) |
+ ((arg & LED_NUM) ? 2 : 0) |
+ ((arg & LED_CAP) ? 4 : 0));
+ set_leds();
+ return 0;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+void
+vt_init(void)
+{
+ int i;
+
+ for (i = 0; i < NR_CONSOLES; ++i) {
+ vt_info[i].mode = KD_TEXT;
+ }
+}
diff --git a/kernel/chr_drv/vt_kern.h b/kernel/chr_drv/vt_kern.h
new file mode 100644
index 0000000..d90bf82
--- /dev/null
+++ b/kernel/chr_drv/vt_kern.h
@@ -0,0 +1,8 @@
+#ifndef _VT_KERN_H
+#define _VT_KERN_H
+
+extern struct vt_info {
+ int mode; /* KD_TEXT, ... */
+} vt_info[MAX_CONSOLES];
+
+#endif /* _VT_KERN_H */
diff --git a/kernel/exit.c b/kernel/exit.c
index 50f6146..5253ab2 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -287,8 +287,10 @@ volatile void do_exit(long code)
current->root = NULL;
iput(current->executable);
current->executable = NULL;
- iput(current->library);
- current->library = NULL;
+ for (i=0; i<current->numlibraries; i++) {
+ iput(current->libraries[i].library);
+ current->libraries[i].library = NULL;
+ }
current->state = TASK_ZOMBIE;
current->exit_code = code;
current->rss = 0;
diff --git a/kernel/fork.c b/kernel/fork.c
index ad65fb1..89277ab 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -11,6 +11,7 @@
* management can be a bitch. See 'mm/mm.c': 'copy_page_tables()'
*/
#include <errno.h>
+#include <stddef.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -106,6 +107,12 @@ int sys_fork(long ebx,long ecx,long edx,
*p = *current; /* NOTE! this doesn't copy the supervisor stack */
p->state = TASK_UNINTERRUPTIBLE;
p->pid = last_pid;
+ p->p_pptr = current;
+ p->p_cptr = NULL;
+ p->p_ysptr = NULL;
+ if (p->p_osptr = current->p_cptr)
+ p->p_osptr->p_ysptr = p;
+ current->p_cptr = p;
p->counter = p->priority;
p->signal = 0;
p->alarm = 0;
@@ -135,11 +142,19 @@ int sys_fork(long ebx,long ecx,long edx,
p->tss.fs = fs & 0xffff;
p->tss.gs = gs & 0xffff;
p->tss.ldt = _LDT(nr);
- p->tss.trace_bitmap = 0x80000000;
+ p->tss.trace_bitmap = offsetof(struct tss_struct,io_bitmap) << 16;
+ for (i = 0; i<IO_BITMAP_SIZE ; i++)
+ p->tss.io_bitmap[i] = ~0;
if (last_task_used_math == current)
__asm__("clts ; fnsave %0 ; frstor %0"::"m" (p->tss.i387));
if (copy_mem(nr,p)) {
task[nr] = NULL;
+ if (p->p_pptr->p_cptr == p)
+ p->p_pptr->p_cptr = p->p_osptr;
+ if (p->p_osptr)
+ p->p_osptr->p_ysptr = p->p_ysptr;
+ if (p->p_ysptr)
+ p->p_ysptr->p_osptr = p->p_osptr;
free_page((long) p);
return -EAGAIN;
}
@@ -152,17 +167,11 @@ int sys_fork(long ebx,long ecx,long edx,
current->root->i_count++;
if (current->executable)
current->executable->i_count++;
- if (current->library)
- current->library->i_count++;
+ for (i=0; i < current->numlibraries ; i++)
+ if (current->libraries[i].library)
+ current->libraries[i].library->i_count++;
set_tss_desc(gdt+(nr<<1)+FIRST_TSS_ENTRY,&(p->tss));
set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY,&(p->ldt));
- p->p_pptr = current;
- p->p_cptr = 0;
- p->p_ysptr = 0;
- p->p_osptr = current->p_cptr;
- if (p->p_osptr)
- p->p_osptr->p_ysptr = p;
- current->p_cptr = p;
p->state = TASK_RUNNING; /* do this last, just in case */
return p->pid;
}
diff --git a/kernel/ioport.c b/kernel/ioport.c
new file mode 100644
index 0000000..cdca95a
--- /dev/null
+++ b/kernel/ioport.c
@@ -0,0 +1,94 @@
+/*
+ * linux/kernel/ioport.c
+ *
+ * This contains the io-permission bitmap code - written by obz, with changes
+ * by Linus.
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+
+#include <sys/types.h>
+#include <errno.h>
+
+#define _IODEBUG
+
+#ifdef IODEBUG
+static char * ios(unsigned long l)
+{
+ static char str[33] = { '\0' };
+ int i;
+ unsigned long mask;
+
+ for (i = 0, mask = 0x80000000; i < 32; ++i, mask >>= 1)
+ str[i] = (l & mask) ? '1' : '0';
+ return str;
+}
+
+static void dump_io_bitmap(void)
+{
+ int i, j;
+ int numl = sizeof(current->tss.io_bitmap) >> 2;
+
+ for (i = j = 0; j < numl; ++i)
+ {
+ printk("%4d [%3x]: ", 64*i, 64*i);
+ printk("%s ", ios(current->tss.io_bitmap[j++]));
+ if (j < numl)
+ printk("%s", ios(current->tss.io_bitmap[j++]));
+ printk("\n");
+ }
+}
+#endif
+
+/*
+ * this changes the io permissions bitmap in the current task.
+ */
+int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
+{
+ unsigned long froml, lindex, tnum, numl, rindex, mask;
+ unsigned long *iop;
+
+ froml = from >> 5;
+ lindex = from & 0x1f;
+ tnum = lindex + num;
+ numl = (tnum + 0x1f) >> 5;
+ rindex = tnum & 0x1f;
+
+ if (!suser())
+ return -EPERM;
+ if (froml * 32 + tnum > sizeof(current->tss.io_bitmap) * 8 - 8)
+ return -EINVAL;
+
+#ifdef IODEBUG
+ printk("io: from=%d num=%d %s\n", from, num, (turn_on ? "on" : "off"));
+#endif
+
+ if (numl) {
+ iop = (unsigned long *)current->tss.io_bitmap + froml;
+ if (lindex != 0) {
+ mask = (~0 << lindex);
+ if (--numl == 0 && rindex)
+ mask &= ~(~0 << rindex);
+ if (turn_on)
+ *iop++ &= ~mask;
+ else
+ *iop++ |= mask;
+ }
+ if (numl) {
+ if (rindex)
+ --numl;
+ mask = (turn_on ? 0 : ~0);
+ while (numl--)
+ *iop++ = mask;
+ if (numl && rindex) {
+ mask = ~(~0 << rindex);
+ if (turn_on)
+ *iop++ &= ~mask;
+ else
+ *iop++ |= mask;
+ }
+ }
+ }
+ return 0;
+}
diff --git a/kernel/math/Makefile b/kernel/math/Makefile
index 3c06183..79e3276 100644
--- a/kernel/math/Makefile
+++ b/kernel/math/Makefile
@@ -40,51 +40,46 @@ dep:
cp tmp_make Makefile
### Dependencies:
-add.s add.o : add.c ../../include/linux/math_emu.h ../../include/linux/sched.h \
- ../../include/linux/head.h ../../include/linux/fs.h \
- ../../include/sys/types.h ../../include/linux/mm.h \
- ../../include/linux/kernel.h ../../include/signal.h \
- ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
+add.s add.o : add.c ../../include/linux/math_emu.h ../../include/linux/sched.h ../../include/linux/head.h \
+ ../../include/linux/fs.h ../../include/sys/types.h ../../include/sys/dirent.h \
+ ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \
+ ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
../../include/sys/resource.h
-compare.s compare.o : compare.c ../../include/linux/math_emu.h \
- ../../include/linux/sched.h ../../include/linux/head.h \
- ../../include/linux/fs.h ../../include/sys/types.h ../../include/linux/mm.h \
- ../../include/linux/kernel.h ../../include/signal.h \
- ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
+compare.s compare.o : compare.c ../../include/linux/math_emu.h ../../include/linux/sched.h \
+ ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/types.h \
+ ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \
+ ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
../../include/sys/resource.h
-convert.s convert.o : convert.c ../../include/linux/math_emu.h \
- ../../include/linux/sched.h ../../include/linux/head.h \
- ../../include/linux/fs.h ../../include/sys/types.h ../../include/linux/mm.h \
- ../../include/linux/kernel.h ../../include/signal.h \
- ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
+convert.s convert.o : convert.c ../../include/linux/math_emu.h ../../include/linux/sched.h \
+ ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/types.h \
+ ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \
+ ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
../../include/sys/resource.h
-div.s div.o : div.c ../../include/linux/math_emu.h ../../include/linux/sched.h \
- ../../include/linux/head.h ../../include/linux/fs.h \
- ../../include/sys/types.h ../../include/linux/mm.h \
- ../../include/linux/kernel.h ../../include/signal.h \
- ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
+div.s div.o : div.c ../../include/linux/math_emu.h ../../include/linux/sched.h ../../include/linux/head.h \
+ ../../include/linux/fs.h ../../include/sys/types.h ../../include/sys/dirent.h \
+ ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \
+ ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
../../include/sys/resource.h
-ea.s ea.o : ea.c ../../include/stddef.h ../../include/linux/math_emu.h \
- ../../include/linux/sched.h ../../include/linux/head.h \
- ../../include/linux/fs.h ../../include/sys/types.h ../../include/linux/mm.h \
- ../../include/linux/kernel.h ../../include/signal.h \
- ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
+ea.s ea.o : ea.c ../../include/stddef.h ../../include/linux/math_emu.h ../../include/linux/sched.h \
+ ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/types.h \
+ ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \
+ ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
../../include/sys/resource.h ../../include/asm/segment.h
-error.s error.o : error.c ../../include/signal.h ../../include/sys/types.h \
- ../../include/linux/sched.h ../../include/linux/head.h \
- ../../include/linux/fs.h ../../include/linux/mm.h \
- ../../include/linux/kernel.h ../../include/sys/param.h \
- ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h
-get_put.s get_put.o : get_put.c ../../include/signal.h ../../include/sys/types.h \
- ../../include/linux/math_emu.h ../../include/linux/sched.h \
- ../../include/linux/head.h ../../include/linux/fs.h \
- ../../include/linux/mm.h ../../include/linux/kernel.h \
- ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
- ../../include/sys/resource.h ../../include/asm/segment.h
-emulate.s emulate.o : emulate.c ../../include/linux/config.h
-mul.s mul.o : mul.c ../../include/linux/math_emu.h ../../include/linux/sched.h \
- ../../include/linux/head.h ../../include/linux/fs.h \
- ../../include/sys/types.h ../../include/linux/mm.h \
- ../../include/linux/kernel.h ../../include/signal.h \
- ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
+emulate.s emulate.o : emulate.c ../../include/signal.h ../../include/sys/types.h ../../include/linux/sched.h \
+ ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/dirent.h \
+ ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \
+ ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h
+error.s error.o : error.c ../../include/signal.h ../../include/sys/types.h ../../include/linux/sched.h \
+ ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/dirent.h \
+ ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \
+ ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h
+get_put.s get_put.o : get_put.c ../../include/signal.h ../../include/sys/types.h ../../include/linux/math_emu.h \
+ ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \
+ ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \
+ ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h \
+ ../../include/asm/segment.h
+mul.s mul.o : mul.c ../../include/linux/math_emu.h ../../include/linux/sched.h ../../include/linux/head.h \
+ ../../include/linux/fs.h ../../include/sys/types.h ../../include/sys/dirent.h \
+ ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \
+ ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
../../include/sys/resource.h
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 051241d..4602fc2 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -219,19 +219,11 @@ static int write_long(struct task_struct * tsk, unsigned long addr,
return 0;
}
-/* Perform ptrace(request, pid, addr, data) syscall */
-int sys_ptrace(unsigned long *buffer)
+int sys_ptrace(long request, long pid, long addr, long data)
{
- long request, pid, data;
- long addr;
struct task_struct *child;
int childno;
- request = get_fs_long(buffer++);
- pid = get_fs_long(buffer++);
- addr = get_fs_long(buffer++); /* assume long = void * */
- data = get_fs_long(buffer++);
-
if (request == 0) {
/* set the ptrace bit in the proccess flags. */
current->flags |= PF_PTRACED;
diff --git a/kernel/sched.c b/kernel/sched.c
index 3c274e6..098d096 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -46,21 +46,12 @@ void show_task(int nr,struct task_struct * p)
void show_state(void)
{
- static int lock = 0;
int i;
- cli();
- if (lock) {
- sti();
- return;
- }
- lock = 1;
- sti();
printk("\rTask-info:\n\r");
for (i=0 ; i<NR_TASKS ; i++)
if (task[i])
show_task(i,task[i]);
- lock = 0;
}
#define LATCH (1193180/HZ)
diff --git a/kernel/sys.c b/kernel/sys.c
index 4dd1059..a919028 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -15,7 +15,7 @@
#include <sys/utsname.h>
#include <sys/param.h>
#include <sys/resource.h>
-#include <string.h>
+#include <linux/string.h>
/*
* this indicates wether you can reboot with ctrl-alt-del: the deault is yes
@@ -30,6 +30,21 @@ struct timezone sys_tz = { 0, 0};
extern int session_of_pgrp(int pgrp);
+int sys_getpriority()
+{
+ return -ENOSYS;
+}
+
+int sys_setpriority()
+{
+ return -ENOSYS;
+}
+
+int sys_profil()
+{
+ return -ENOSYS;
+}
+
int sys_ftime()
{
return -ENOSYS;
@@ -378,7 +393,8 @@ int sys_uname(struct utsname * name)
{
int i;
- if (!name) return -ERROR;
+ if (!name)
+ return -EINVAL;
verify_area(name,sizeof *name);
for(i=0;i<sizeof *name;i++)
put_fs_byte(((char *) &thisname)[i],i+(char *) name);
diff --git a/kernel/sys_call.S b/kernel/sys_call.S
new file mode 100644
index 0000000..e6f7766
--- /dev/null
+++ b/kernel/sys_call.S
@@ -0,0 +1,369 @@
+/*
+ * linux/kernel/sys_call.S
+ *
+ * (C) 1991 Linus Torvalds
+ */
+
+/*
+ * sys_call.S contains the system-call and fault low-level handling routines.
+ * This also contains the timer-interrupt handler, as well as all interrupts
+ * and faults that can result in a task-switch.
+ *
+ * NOTE: This code handles signal-recognition, which happens every time
+ * after a timer-interrupt and after each system call.
+ *
+ * Stack layout in 'ret_from_system_call':
+ * ptrace needs to have all regs on the stack.
+ * if the order here is changed, it needs to be
+ * updated in fork.c:copy_process, signal.c:do_signal,
+ * ptrace.c and ptrace.h
+ *
+ * 0(%esp) - %ebx
+ * 4(%esp) - %ecx
+ * 8(%esp) - %edx
+ * C(%esp) - %esi
+ * 10(%esp) - %edi
+ * 14(%esp) - %ebp
+ * 18(%esp) - %eax
+ * 1C(%esp) - %ds
+ * 20(%esp) - %es
+ * 24(%esp) - %fs
+ * 28(%esp) - %gs
+ * 2C(%esp) - orig_eax
+ * 30(%esp) - %eip
+ * 34(%esp) - %cs
+ * 38(%esp) - %eflags
+ * 3C(%esp) - %oldesp
+ * 40(%esp) - %oldss
+ */
+
+SIG_CHLD = 17
+
+EBX = 0x00
+ECX = 0x04
+EDX = 0x08
+ESI = 0x0C
+EDI = 0x10
+EBP = 0x14
+EAX = 0x18
+DS = 0x1C
+ES = 0x20
+FS = 0x24
+GS = 0x28
+ORIG_EAX = 0x2C
+EIP = 0x30
+CS = 0x34
+EFLAGS = 0x38
+OLDESP = 0x3C
+OLDSS = 0x40
+
+/*
+ * these are offsets into the task-struct.
+ */
+state = 0
+counter = 4
+priority = 8
+signal = 12
+sigaction = 16 # MUST be 16 (=len of sigaction)
+blocked = (33*16)
+
+/*
+ * offsets within sigaction
+ */
+sa_handler = 0
+sa_mask = 4
+sa_flags = 8
+sa_restorer = 12
+
+ENOSYS = 38
+
+/*
+ * Ok, I get parallel printer interrupts while using the floppy for some
+ * strange reason. Urgel. Now I just ignore them.
+ */
+.globl _system_call,_timer_interrupt,_sys_execve
+.globl _device_not_available, _coprocessor_error
+.globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op
+.globl _double_fault,_coprocessor_segment_overrun
+.globl _invalid_TSS,_segment_not_present,_stack_segment
+.globl _general_protection,_irq13,_reserved
+.globl _alignment_check,_page_fault
+.globl _keyboard_interrupt
+
+#define SAVE_ALL \
+ cld; \
+ push %gs; \
+ push %fs; \
+ push %es; \
+ push %ds; \
+ pushl %eax; \
+ pushl %ebp; \
+ pushl %edi; \
+ pushl %esi; \
+ pushl %edx; \
+ pushl %ecx; \
+ pushl %ebx; \
+ movl $0x10,%edx; \
+ mov %dx,%ds; \
+ mov %dx,%es; \
+ movl $0x17,%edx; \
+ mov %dx,%fs
+
+#define ACK_FIRST(mask) \
+ inb $0x21,%al; \
+ jmp 1f; \
+1: jmp 1f; \
+1: orb $(mask),%al; \
+ outb %al,$0x21; \
+ jmp 1f; \
+1: jmp 1f; \
+1: movb $0x20,%al; \
+ outb %al,$0x20
+
+#define ACK_SECOND(mask) \
+ inb $0xA1,%al; \
+ jmp 1f; \
+1: jmp 1f; \
+1: orb $mask,%al; \
+ outb %al,$0xA1; \
+ jmp 1f; \
+1: jmp 1f; \
+1: movb $0x20,%al; \
+ outb %al,$0x20
+ jmp 1f; \
+1: jmp 1f; \
+1: outb %al,$0xA0
+
+#define UNBLK_FIRST(mask) \
+ inb $0x21,%al; \
+ jmp 1f; \
+1: jmp 1f; \
+1: andb $~(mask),%al; \
+ outb %al,$0x21
+
+#define UNBLK_SECOND(mask) \
+ inb $0xA1,%al; \
+ jmp 1f; \
+1: jmp 1f; \
+1: andb $~(mask),%al; \
+ outb %al,$0xA1
+
+.align 2
+bad_sys_call:
+ movl $-ENOSYS,EAX(%esp)
+ jmp ret_from_sys_call
+.align 2
+reschedule:
+ pushl $ret_from_sys_call
+ jmp _schedule
+.align 2
+_system_call:
+ pushl %eax # save orig_eax
+ SAVE_ALL
+ cmpl _NR_syscalls,%eax
+ jae bad_sys_call
+ call _sys_call_table(,%eax,4)
+ movl %eax,EAX(%esp) # save the return value
+ret_from_sys_call:
+ cmpw $0x0f,CS(%esp) # was old code segment supervisor ?
+ jne 2f
+ cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ?
+ jne 2f
+1: movl _current,%eax
+ cmpl _task,%eax # task[0] cannot have signals
+ je 2f
+ cmpl $0,state(%eax) # state
+ jne reschedule
+ cmpl $0,counter(%eax) # counter
+ je reschedule
+ movl signal(%eax),%ebx
+ movl blocked(%eax),%ecx
+ notl %ecx
+ andl %ebx,%ecx
+ bsfl %ecx,%ecx
+ je 2f
+ btrl %ecx,%ebx
+ movl %ebx,signal(%eax)
+ incl %ecx
+ pushl %ecx
+ call _do_signal
+ popl %ecx
+ testl %eax, %eax
+ jne 1b # see if we need to switch tasks, or do more signals
+2: popl %ebx
+ popl %ecx
+ popl %edx
+ popl %esi
+ popl %edi
+ popl %ebp
+ popl %eax
+ pop %ds
+ pop %es
+ pop %fs
+ pop %gs
+ addl $4,%esp # skip the orig_eax
+ iret
+
+.align 2
+_irq13:
+ pushl %eax
+ xorb %al,%al
+ outb %al,$0xF0
+ movb $0x20,%al
+ outb %al,$0x20
+ jmp 1f
+1: jmp 1f
+1: outb %al,$0xA0
+ popl %eax
+_coprocessor_error:
+ pushl $-1 # mark this as an int.
+ SAVE_ALL
+ pushl $ret_from_sys_call
+ jmp _math_error
+
+.align 2
+_device_not_available:
+ pushl $-1 # mark this as an int
+ SAVE_ALL
+ pushl $ret_from_sys_call
+ clts # clear TS so that we can use math
+ movl %cr0,%eax
+ testl $0x4,%eax # EM (math emulation bit)
+ je _math_state_restore
+ pushl $0 # temporary storage for ORIG_EIP
+ call _math_emulate
+ addl $4,%esp
+ ret
+
+.align 2
+_keyboard_interrupt:
+ pushl $-1
+ SAVE_ALL
+ ACK_FIRST(2)
+ sti
+ call _do_keyboard
+ cli
+ UNBLK_FIRST(2)
+ jmp ret_from_sys_call
+
+.align 2
+_timer_interrupt:
+ pushl $-1 # mark this as an int
+ SAVE_ALL
+ incl _jiffies
+ movb $0x20,%al # EOI to interrupt controller #1
+ outb %al,$0x20
+ movl CS(%esp),%eax
+ andl $3,%eax # %eax is CPL (0 or 3, 0=supervisor)
+ pushl %eax
+ call _do_timer # 'do_timer(long CPL)' does everything from
+ addl $4,%esp # task switching to accounting ...
+ jmp ret_from_sys_call
+
+.align 2
+_sys_execve:
+ lea (EIP+4)(%esp),%eax # don't forget about the return address.
+ pushl %eax
+ call _do_execve
+ addl $4,%esp
+ ret
+
+_divide_error:
+ pushl $0 # no error code
+ pushl $_do_divide_error
+error_code:
+ push %fs
+ push %es
+ push %ds
+ pushl %eax
+ pushl %ebp
+ pushl %edi
+ pushl %esi
+ pushl %edx
+ pushl %ecx
+ pushl %ebx
+ cld
+ movl $-1, %eax
+ xchgl %eax, ORIG_EAX(%esp) # orig_eax (get the error code. )
+ xorl %ebx,%ebx # zero ebx
+ mov %gs,%bx # get the lower order bits of gs
+ xchgl %ebx, GS(%esp) # get the address and save gs.
+ pushl %eax # push the error code
+ lea 52(%esp),%edx
+ pushl %edx
+ movl $0x10,%edx
+ mov %dx,%ds
+ mov %dx,%es
+ movl $0x17,%edx
+ mov %dx,%fs
+ call *%ebx
+ addl $8,%esp
+ jmp ret_from_sys_call
+
+_debug:
+ pushl $0
+ pushl $_do_int3 # _do_debug
+ jmp error_code
+
+_nmi:
+ pushl $0
+ pushl $_do_nmi
+ jmp error_code
+
+_int3:
+ pushl $0
+ pushl $_do_int3
+ jmp error_code
+
+_overflow:
+ pushl $0
+ pushl $_do_overflow
+ jmp error_code
+
+_bounds:
+ pushl $0
+ pushl $_do_bounds
+ jmp error_code
+
+_invalid_op:
+ pushl $0
+ pushl $_do_invalid_op
+ jmp error_code
+
+_coprocessor_segment_overrun:
+ pushl $0
+ pushl $_do_coprocessor_segment_overrun
+ jmp error_code
+
+_reserved:
+ pushl $0
+ pushl $_do_reserved
+ jmp error_code
+
+_double_fault:
+ pushl $_do_double_fault
+ jmp error_code
+
+_invalid_TSS:
+ pushl $_do_invalid_TSS
+ jmp error_code
+
+_segment_not_present:
+ pushl $_do_segment_not_present
+ jmp error_code
+
+_stack_segment:
+ pushl $_do_stack_segment
+ jmp error_code
+
+_general_protection:
+ pushl $_do_general_protection
+ jmp error_code
+
+_alignment_check:
+ pushl $_do_alignment_check
+ jmp error_code
+
+_page_fault:
+ pushl $_do_page_fault
+ jmp error_code
diff --git a/kernel/sys_call.s b/kernel/sys_call.s
deleted file mode 100644
index 8d7a982..0000000
--- a/kernel/sys_call.s
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * linux/kernel/system_call.s
- *
- * (C) 1991 Linus Torvalds
- */
-
-/*
- * system_call.s contains the system-call low-level handling routines.
- * This also contains the timer-interrupt handler, as some of the code is
- * the same. The hd- and flopppy-interrupts are also here.
- *
- * NOTE: This code handles signal-recognition, which happens every time
- * after a timer-interrupt and after each system call. Ordinary interrupts
- * don't handle signal-recognition, as that would clutter them up totally
- * unnecessarily.
- *
- * Stack layout in 'ret_from_system_call':
- * ptrace needs to have all regs on the stack.
- * if the order here is changed, it needs to be
- * updated in fork.c:copy_process, signal.c:do_signal,
- * ptrace.c ptrace.h
- *
- * 0(%esp) - %ebx
- * 4(%esp) - %ecx
- * 8(%esp) - %edx
- * C(%esp) - %esi
- * 10(%esp) - %edi
- * 14(%esp) - %ebp
- * 18(%esp) - %eax
- * 1C(%esp) - %ds
- * 20(%esp) - %es
- * 24(%esp) - %fs
- * 28(%esp) - %gs
- * 2C(%esp) - orig_eax
- * 30(%esp) - %eip
- * 34(%esp) - %cs
- * 38(%esp) - %eflags
- * 3C(%esp) - %oldesp
- * 40(%esp) - %oldss
- */
-
-SIG_CHLD = 17
-
-EBX = 0x00
-ECX = 0x04
-EDX = 0x08
-ESI = 0x0C
-EDI = 0x10
-EBP = 0x14
-EAX = 0x18
-DS = 0x1C
-ES = 0x20
-FS = 0x24
-GS = 0x28
-ORIG_EAX = 0x2C
-EIP = 0x30
-CS = 0x34
-EFLAGS = 0x38
-OLDESP = 0x3C
-OLDSS = 0x40
-
-state = 0 # these are offsets into the task-struct.
-counter = 4
-priority = 8
-signal = 12
-sigaction = 16 # MUST be 16 (=len of sigaction)
-blocked = (33*16)
-
-# offsets within sigaction
-sa_handler = 0
-sa_mask = 4
-sa_flags = 8
-sa_restorer = 12
-
-nr_system_calls = 82
-
-ENOSYS = 38
-
-/*
- * Ok, I get parallel printer interrupts while using the floppy for some
- * strange reason. Urgel. Now I just ignore them.
- */
-.globl _system_call,_timer_interrupt,_sys_execve
-.globl _hd_interrupt,_floppy_interrupt,_parallel_interrupt
-.globl _device_not_available, _coprocessor_error
-
-.align 2
-bad_sys_call:
- pushl $-ENOSYS
- jmp ret_from_sys_call
-.align 2
-reschedule:
- pushl $ret_from_sys_call
- jmp _schedule
-.align 2
-_system_call:
- cld
- pushl %eax # save orig_eax
- push %gs
- push %fs
- push %es
- push %ds
- pushl %eax # save eax. The return value will be put here.
- pushl %ebp
- pushl %edi
- pushl %esi
- pushl %edx
- pushl %ecx # push %ebx,%ecx,%edx as parameters
- pushl %ebx # to the system call
- movl $0x10,%edx # set up ds,es to kernel space
- mov %dx,%ds
- mov %dx,%es
- movl $0x17,%edx # fs points to local data space
- mov %dx,%fs
- cmpl _NR_syscalls,%eax
- jae bad_sys_call
- call _sys_call_table(,%eax,4)
- movl %eax,EAX(%esp) # save the return value
-2: movl _current,%eax
- cmpl $0,state(%eax) # state
- jne reschedule
- cmpl $0,counter(%eax) # counter
- je reschedule
-ret_from_sys_call:
- movl _current,%eax
- cmpl _task,%eax # task[0] cannot have signals
- je 3f
- cmpw $0x0f,CS(%esp) # was old code segment supervisor ?
- jne 3f
- cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ?
- jne 3f
- movl signal(%eax),%ebx
- movl blocked(%eax),%ecx
- notl %ecx
- andl %ebx,%ecx
- bsfl %ecx,%ecx
- je 3f
- btrl %ecx,%ebx
- movl %ebx,signal(%eax)
- incl %ecx
- pushl %ecx
- call _do_signal
- popl %ecx
- testl %eax, %eax
- jne 2b # see if we need to switch tasks, or do more signals
-3:
- popl %ebx
- popl %ecx
- popl %edx
- popl %esi
- popl %edi
- popl %ebp
- popl %eax
- pop %ds
- pop %es
- pop %fs
- pop %gs
- addl $4,%esp # skip the orig_eax
- iret
-
-.align 2
-_coprocessor_error:
- cld
- pushl $-1 # mark this as an int.
- push %gs
- push %fs
- push %es
- push %ds
- pushl %eax # save eax.
- pushl %ebp
- pushl %edi
- pushl %esi
- pushl %edx
- pushl %ecx
- pushl %ebx
- movl $0x10,%eax
- mov %ax,%ds
- mov %ax,%es
- movl $0x17,%eax
- mov %ax,%fs
- pushl $ret_from_sys_call
- jmp _math_error
-
-.align 2
-_device_not_available:
- cld
- pushl $-1 # mark this as an int
- push %gs
- push %fs
- push %es
- push %ds
- pushl %eax
- pushl %ebp
- pushl %edi
- pushl %esi
- pushl %edx
- pushl %ecx
- pushl %ebx
- movl $0x10,%eax
- mov %ax,%ds
- mov %ax,%es
- movl $0x17,%eax
- mov %ax,%fs
- pushl $ret_from_sys_call
- clts # clear TS so that we can use math
- movl %cr0,%eax
- testl $0x4,%eax # EM (math emulation bit)
- je _math_state_restore
- pushl $0 # temporary storage for ORIG_EIP
- call _math_emulate
- addl $4,%esp
- ret
-
-.align 2
-_timer_interrupt:
- cld
- pushl $-1 # mark this as an int
- push %gs
- push %fs
- push %es
- push %ds
- pushl %eax
- pushl %ebp
- pushl %edi
- pushl %esi
- pushl %edx
- pushl %ecx
- pushl %ebx
- movl $0x10,%eax
- mov %ax,%ds
- mov %ax,%es
- movl $0x17,%eax
- mov %ax,%fs
- incl _jiffies
- movb $0x20,%al # EOI to interrupt controller #1
- outb %al,$0x20
- movl CS(%esp),%eax
- andl $3,%eax # %eax is CPL (0 or 3, 0=supervisor)
- pushl %eax
- call _do_timer # 'do_timer(long CPL)' does everything from
- addl $4,%esp # task switching to accounting ...
- jmp ret_from_sys_call
-
-.align 2
-_sys_execve:
- lea (EIP+4)(%esp),%eax # don't forget about the return address.
- pushl %eax
- call _do_execve
- addl $4,%esp
- ret
-
-_hd_interrupt:
- cld
- pushl %eax
- pushl %ecx
- pushl %edx
- push %ds
- push %es
- push %fs
- movl $0x10,%eax
- mov %ax,%ds
- mov %ax,%es
- movl $0x17,%eax
- mov %ax,%fs
- movb $0x20,%al
- outb %al,$0xA0 # EOI to interrupt controller #1
- jmp 1f # give port chance to breathe
-1: jmp 1f
-1: outb %al,$0x20
- andl $0xfffeffff,_timer_active
- xorl %edx,%edx
- xchgl _do_hd,%edx
- testl %edx,%edx
- jne 1f
- movl $_unexpected_hd_interrupt,%edx
-1: call *%edx # "interesting" way of handling intr.
- pop %fs
- pop %es
- pop %ds
- popl %edx
- popl %ecx
- popl %eax
- iret
-
-_floppy_interrupt:
- cld
- pushl %eax
- pushl %ecx
- pushl %edx
- push %ds
- push %es
- push %fs
- movl $0x10,%eax
- mov %ax,%ds
- mov %ax,%es
- movl $0x17,%eax
- mov %ax,%fs
- movb $0x20,%al
- outb %al,$0x20 # EOI to interrupt controller #1
- xorl %eax,%eax
- xchgl _do_floppy,%eax
- testl %eax,%eax
- jne 1f
- movl $_unexpected_floppy_interrupt,%eax
-1: call *%eax # "interesting" way of handling intr.
- pop %fs
- pop %es
- pop %ds
- popl %edx
- popl %ecx
- popl %eax
- iret
-
-_parallel_interrupt:
- cld
- pushl %eax
- movb $0x20,%al
- outb %al,$0x20
- popl %eax
- iret
diff --git a/kernel/traps.c b/kernel/traps.c
index 797bb79..89b65f3 100644
--- a/kernel/traps.c
+++ b/kernel/traps.c
@@ -10,7 +10,7 @@
* to mainly kill the offending process (probably by giving it a signal,
* but possibly by killing it outright if necessary).
*/
-#include <string.h>
+#include <linux/string.h>
#include <linux/head.h>
#include <linux/sched.h>
diff --git a/kernel/vsprintf.c b/kernel/vsprintf.c
index 06b910e..8ce9873 100644
--- a/kernel/vsprintf.c
+++ b/kernel/vsprintf.c
@@ -10,7 +10,7 @@
*/
#include <stdarg.h>
-#include <string.h>
+#include <linux/string.h>
/* we use this so that we can do without the ctype library */
#define is_digit(c) ((c) >= '0' && (c) <= '9')
diff --git a/lib/Makefile b/lib/Makefile
index 83a543f..78afc1e 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -11,7 +11,7 @@ AS =as
LD =ld
LDFLAGS =-s -x
CC =gcc -nostdinc -I../include
-CPP =cpp -nostdinc -I../include
+CPP =gcc -E -nostdinc -I../include
.c.s:
$(CC) $(CFLAGS) \
@@ -40,32 +40,33 @@ dep:
cp tmp_make Makefile
### Dependencies:
-_exit.s _exit.o : _exit.c ../include/unistd.h ../include/sys/stat.h \
- ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \
- ../include/utime.h
-close.s close.o : close.c ../include/unistd.h ../include/sys/stat.h \
- ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \
- ../include/utime.h
-ctype.s ctype.o : ctype.c ../include/ctype.h
-dup.s dup.o : dup.c ../include/unistd.h ../include/sys/stat.h \
- ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \
- ../include/utime.h
+_exit.s _exit.o : _exit.c ../include/unistd.h ../include/sys/stat.h ../include/sys/types.h \
+ ../include/sys/time.h ../include/time.h ../include/sys/times.h ../include/sys/utsname.h \
+ ../include/sys/param.h ../include/sys/resource.h ../include/utime.h
+close.s close.o : close.c ../include/unistd.h ../include/sys/stat.h ../include/sys/types.h \
+ ../include/sys/time.h ../include/time.h ../include/sys/times.h ../include/sys/utsname.h \
+ ../include/sys/param.h ../include/sys/resource.h ../include/utime.h
+ctype.s ctype.o : ctype.c ../include/linux/ctype.h
+dup.s dup.o : dup.c ../include/unistd.h ../include/sys/stat.h ../include/sys/types.h \
+ ../include/sys/time.h ../include/time.h ../include/sys/times.h ../include/sys/utsname.h \
+ ../include/sys/param.h ../include/sys/resource.h ../include/utime.h
errno.s errno.o : errno.c
-execve.s execve.o : execve.c ../include/unistd.h ../include/sys/stat.h \
- ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \
- ../include/utime.h
-malloc.s malloc.o : malloc.c ../include/linux/kernel.h ../include/linux/mm.h \
+execve.s execve.o : execve.c ../include/unistd.h ../include/sys/stat.h ../include/sys/types.h \
+ ../include/sys/time.h ../include/time.h ../include/sys/times.h ../include/sys/utsname.h \
+ ../include/sys/param.h ../include/sys/resource.h ../include/utime.h
+malloc.s malloc.o : malloc.c ../include/linux/kernel.h ../include/linux/mm.h ../include/linux/fs.h \
+ ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h ../include/signal.h \
../include/asm/system.h
-open.s open.o : open.c ../include/unistd.h ../include/sys/stat.h \
- ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \
- ../include/utime.h ../include/stdarg.h
-setsid.s setsid.o : setsid.c ../include/unistd.h ../include/sys/stat.h \
- ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \
- ../include/utime.h
-string.s string.o : string.c ../include/string.h
-wait.s wait.o : wait.c ../include/unistd.h ../include/sys/stat.h \
- ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \
- ../include/utime.h ../include/sys/wait.h
-write.s write.o : write.c ../include/unistd.h ../include/sys/stat.h \
- ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \
- ../include/utime.h
+open.s open.o : open.c ../include/unistd.h ../include/sys/stat.h ../include/sys/types.h \
+ ../include/sys/time.h ../include/time.h ../include/sys/times.h ../include/sys/utsname.h \
+ ../include/sys/param.h ../include/sys/resource.h ../include/utime.h ../include/stdarg.h
+setsid.s setsid.o : setsid.c ../include/unistd.h ../include/sys/stat.h ../include/sys/types.h \
+ ../include/sys/time.h ../include/time.h ../include/sys/times.h ../include/sys/utsname.h \
+ ../include/sys/param.h ../include/sys/resource.h ../include/utime.h
+string.s string.o : string.c ../include/linux/string.h
+wait.s wait.o : wait.c ../include/unistd.h ../include/sys/stat.h ../include/sys/types.h \
+ ../include/sys/time.h ../include/time.h ../include/sys/times.h ../include/sys/utsname.h \
+ ../include/sys/param.h ../include/sys/resource.h ../include/utime.h ../include/sys/wait.h
+write.s write.o : write.c ../include/unistd.h ../include/sys/stat.h ../include/sys/types.h \
+ ../include/sys/time.h ../include/time.h ../include/sys/times.h ../include/sys/utsname.h \
+ ../include/sys/param.h ../include/sys/resource.h ../include/utime.h
diff --git a/lib/ctype.c b/lib/ctype.c
index 877e629..f1103a9 100644
--- a/lib/ctype.c
+++ b/lib/ctype.c
@@ -4,7 +4,7 @@
* (C) 1991 Linus Torvalds
*/
-#include <ctype.h>
+#include <linux/ctype.h>
char _ctmp;
unsigned char _ctype[] = {0x00, /* EOF */
diff --git a/lib/string.c b/lib/string.c
index 1182e63..ebbdfff 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -11,4 +11,4 @@
#define extern
#define inline
#define __LIBRARY__
-#include <string.h>
+#include <linux/string.h>
diff --git a/mm/Makefile b/mm/Makefile
index 27b2f4e..c60e25b 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -22,7 +22,7 @@ CPP =cpp -nostdinc -I../include
$(CC) $(CFLAGS) \
-S -o $*.s $<
-OBJS = memory.o swap.o
+OBJS = memory.o swap.o mmap.o
mm.o: $(OBJS)
$(LD) -r -o mm.o $(OBJS)
@@ -37,14 +37,17 @@ dep:
cp tmp_make Makefile
### Dependencies:
-memory.o : memory.c ../include/signal.h ../include/sys/types.h \
- ../include/asm/system.h ../include/linux/sched.h ../include/linux/head.h \
- ../include/linux/fs.h ../include/sys/dirent.h ../include/limits.h \
- ../include/linux/mm.h ../include/linux/kernel.h ../include/sys/param.h \
+memory.o : memory.c ../include/signal.h ../include/sys/types.h ../include/asm/system.h \
+ ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h ../include/sys/dirent.h \
+ ../include/limits.h ../include/linux/mm.h ../include/linux/kernel.h ../include/sys/param.h \
../include/sys/time.h ../include/time.h ../include/sys/resource.h
-swap.o : swap.c ../include/string.h ../include/errno.h \
- ../include/linux/mm.h ../include/linux/fs.h ../include/sys/types.h \
- ../include/sys/dirent.h ../include/limits.h ../include/linux/kernel.h \
- ../include/signal.h ../include/sys/stat.h ../include/linux/sched.h \
- ../include/linux/head.h ../include/sys/param.h ../include/sys/time.h \
- ../include/time.h ../include/sys/resource.h
+mmap.o : mmap.c ../include/sys/stat.h ../include/sys/types.h ../include/linux/sched.h \
+ ../include/linux/head.h ../include/linux/fs.h ../include/sys/dirent.h ../include/limits.h \
+ ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h \
+ ../include/sys/time.h ../include/time.h ../include/sys/resource.h ../include/asm/segment.h \
+ ../include/asm/system.h ../include/errno.h ../include/sys/mman.h
+swap.o : swap.c ../include/errno.h ../include/sys/stat.h ../include/sys/types.h \
+ ../include/linux/mm.h ../include/linux/fs.h ../include/sys/dirent.h ../include/limits.h \
+ ../include/linux/kernel.h ../include/signal.h ../include/linux/string.h ../include/linux/sched.h \
+ ../include/linux/head.h ../include/sys/param.h ../include/sys/time.h ../include/time.h \
+ ../include/sys/resource.h
diff --git a/mm/memory.c b/mm/memory.c
index 8e93a1b..866a5cb 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -186,6 +186,159 @@ int copy_page_tables(unsigned long from,unsigned long to,long size)
}
/*
+ * a more complete version of free_page_tables which performs with page
+ * granularity.
+ */
+int
+unmap_page_range(unsigned long from, unsigned long size)
+{
+ unsigned long page, page_dir;
+ unsigned long *page_table, *dir;
+ unsigned long poff, pcnt, pc;
+
+ if (from & 0xfff)
+ panic("unmap_page_range called with wrong alignment");
+ if (!from)
+ panic("unmap_page_range trying to free swapper memory space");
+ size = (size + 0xfff) >> 12;
+ dir = (unsigned long *) ((from >> 20) & 0xffc); /* _pg_dir = 0 */
+ poff = (from >> 12) & 0x3ff;
+ if ((pcnt = 1024 - poff) > size)
+ pcnt = size;
+
+ for ( ; size > 0; ++dir, size -= pcnt,
+ pcnt = (size > 1024 ? 1024 : size)) {
+ if (!(page_dir = *dir)) {
+ poff = 0;
+ continue;
+ }
+ if (!(page_dir & 1)) {
+ printk("unmap_page_range: bad page directory.");
+ continue;
+ }
+ page_table = (unsigned long *)(0xfffff000 & page_dir);
+ if (poff) {
+ page_table += poff;
+ poff = 0;
+ }
+ for (pc = pcnt; pc--; page_table++) {
+ if (page = *page_table) {
+ --current->rss;
+ *page_table = 0;
+ if (1 & page)
+ free_page(0xfffff000 & page);
+ else
+ swap_free(page >> 1);
+ }
+ }
+ if (pcnt == 1024) {
+ free_page(0xfffff000 & page_dir);
+ *dir = 0;
+ }
+ }
+ invalidate();
+ for (page = 0; page < CHECK_LAST_NR ; page++)
+ last_pages[page] = 0;
+ return 0;
+}
+
+/*
+ * maps a range of physical memory into the requested pages. the old
+ * mappings are removed. any references to nonexistent pages results
+ * in null mappings (currently treated as "copy-on-access")
+ *
+ * permiss is encoded as cxwr (copy,exec,write,read) where copy modifies
+ * the behavior of write to be copy-on-write.
+ *
+ * due to current limitations, we actually have the following
+ * on off
+ * read: yes yes
+ * write/copy: yes/copy copy/copy
+ * exec: yes yes
+ */
+int
+remap_page_range(unsigned long from, unsigned long to, unsigned long size,
+ int permiss)
+{
+ unsigned long *page_table, *dir;
+ unsigned long poff, pcnt;
+
+ if ((from & 0xfff) || (to & 0xfff))
+ panic("remap_page_range called with wrong alignment");
+ dir = (unsigned long *) ((from >> 20) & 0xffc); /* _pg_dir = 0 */
+ size = (size + 0xfff) >> 12;
+ poff = (from >> 12) & 0x3ff;
+ if ((pcnt = 1024 - poff) > size)
+ pcnt = size;
+
+ while (size > 0) {
+ if (!(1 & *dir)) {
+ if (!(page_table = (unsigned long *)get_free_page())) {
+ invalidate();
+ return -1;
+ }
+ *dir++ = ((unsigned long) page_table) | 7;
+ }
+ else
+ page_table = (unsigned long *)(0xfffff000 & *dir++);
+ if (poff) {
+ page_table += poff;
+ poff = 0;
+ }
+
+ for (size -= pcnt; pcnt-- ;) {
+ int mask;
+
+ mask = 4;
+ if (permiss & 1)
+ mask |= 1;
+ if (permiss & 2) {
+ if (permiss & 8)
+ mask |= 1;
+ else
+ mask |= 3;
+ }
+ if (permiss & 4)
+ mask |= 1;
+
+ if (*page_table) {
+ --current->rss;
+ if (1 & *page_table)
+ free_page(0xfffff000 & *page_table);
+ else
+ swap_free(*page_table >> 1);
+ }
+
+ /*
+ * i'm not sure of the second cond here. should we
+ * report failure?
+ * the first condition should return an invalid access
+ * when the page is referenced. current assumptions
+ * cause it to be treated as demand allocation.
+ */
+ if (mask == 4 || to >= HIGH_MEMORY)
+ *page_table++ = 0; /* not present */
+ else {
+ ++current->rss;
+ *page_table++ = (to | mask);
+ if (to > LOW_MEM) {
+ unsigned long frame;
+ frame = to - LOW_MEM;
+ frame >>= 12;
+ mem_map[frame]++;
+ }
+ }
+ to += PAGE_SIZE;
+ }
+ pcnt = (size > 1024 ? 1024 : size);
+ }
+ invalidate();
+ for (to = 0; to < CHECK_LAST_NR ; to++)
+ last_pages[to] = 0;
+ return 0;
+}
+
+/*
* This function puts a page in memory at the wanted address.
* It returns the physical address of the page gotten, 0 if
* out of memory (either when trying to access page-table or
@@ -410,6 +563,7 @@ static int try_to_share(unsigned long address, struct task_struct * p)
static int share_page(struct inode * inode, unsigned long address)
{
struct task_struct ** p;
+ int i;
if (inode->i_count < 2 || !inode)
return 0;
@@ -422,7 +576,10 @@ static int share_page(struct inode * inode, unsigned long address)
if (inode != (*p)->executable)
continue;
} else {
- if (inode != (*p)->library)
+ for (i=0; i < (*p)->numlibraries; i++)
+ if (inode == (*p)->libraries[i].library)
+ break;
+ if (i >= (*p)->numlibraries)
continue;
}
if (try_to_share(address,*p))
@@ -482,8 +639,18 @@ void do_no_page(unsigned long error_code, unsigned long address,
address &= 0xfffff000;
tmp = address - tsk->start_code;
if (tmp >= LIBRARY_OFFSET ) {
- inode = tsk->library;
- block = 1 + (tmp-LIBRARY_OFFSET) / BLOCK_SIZE;
+ inode = NULL;
+ block = 1;
+ i = tsk->numlibraries;
+ while (i-- > 0) {
+ if (tmp < (tsk->libraries[i].start +
+ tsk->libraries[i].length)) {
+ inode = tsk->libraries[i].library;
+ block = 1 + (tmp - tsk->libraries[i].start) /
+ BLOCK_SIZE;
+ break;
+ }
+ }
} else if (tmp < tsk->end_data) {
inode = tsk->executable;
block = 1 + tmp / BLOCK_SIZE;
@@ -493,7 +660,7 @@ void do_no_page(unsigned long error_code, unsigned long address,
}
if (!inode) {
++tsk->min_flt;
- if (tmp > tsk->brk && tsk == current &&
+ if (tmp < LIBRARY_OFFSET && tmp > tsk->brk && tsk == current &&
LIBRARY_OFFSET - tmp > tsk->rlim[RLIMIT_STACK].rlim_max)
do_exit(SIGSEGV);
get_empty_page(address);
@@ -546,15 +713,7 @@ void show_mem(void)
int i,j,k,free=0,total=0;
int shared = 0;
unsigned long * pg_tbl;
- static int lock = 0;
- cli();
- if (lock) {
- sti();
- return;
- }
- lock = 1;
- sti();
printk("Mem-info:\n\r");
for(i=0 ; i<PAGING_PAGES ; i++) {
if (mem_map[i] == USED)
@@ -595,7 +754,6 @@ void show_mem(void)
}
}
printk("Memory found: %d (%d)\n\r",free-shared,total);
- lock = 0;
}
diff --git a/mm/mmap.c b/mm/mmap.c
new file mode 100644
index 0000000..a8ea628
--- /dev/null
+++ b/mm/mmap.c
@@ -0,0 +1,196 @@
+/*
+ * linux/mm/mmap.c
+ *
+ * Written by obz.
+ */
+#include <sys/stat.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <asm/segment.h>
+#include <asm/system.h>
+#include <errno.h>
+#include <sys/mman.h>
+
+/*
+ * description of effects of mapping type and prot in current implementation.
+ * this is due to the current handling of page faults in memory.c. the expected
+ * behavior is in parens:
+ *
+ * map_type prot
+ * PROT_NONE PROT_READ PROT_WRITE PROT_EXEC
+ * MAP_SHARED r: (no) yes r: (yes) yes r: (no) yes r: (no) no
+ * w: (no) yes w: (no) copy w: (yes) yes w: (no) no
+ * x: (no) no x: (no) no x: (no) no x: (yes) no
+ *
+ * MAP_PRIVATE r: (no) yes r: (yes) yes r: (no) yes r: (no) no
+ * w: (no) copy w: (no) copy w: (copy) copy w: (no) no
+ * x: (no) no x: (no) no x: (no) no x: (yes) no
+ *
+ * the permissions are encoded as cxwr (copy,exec,write,read)
+ */
+#define MTYP(T) ((T) & MAP_TYPE)
+#define PREAD(T,P) (((P) & PROT_READ) ? 1 : 0)
+#define PWRITE(T,P) (((P) & PROT_WRITE) ? (MTYP(T) == MAP_SHARED ? 2 : 10) : 0)
+#define PEXEC(T,P) (((P) & PROT_EXEC) ? 4 : 0)
+#define PERMISS(T,P) (PREAD(T,P)|PWRITE(T,P)|PEXEC(T,P))
+
+#define CODE_SPACE(addr) ((((addr)+4095)&~4095) < \
+ current->start_code + current->end_code)
+
+extern int remap_page_range(unsigned long from, unsigned long to,
+ unsigned long size, int permiss);
+extern int unmap_page_range(unsigned long from, unsigned long size);
+
+static caddr_t
+mmap_chr(unsigned long addr, size_t len, int prot, int flags,
+ struct inode *inode, unsigned long off)
+{
+ int major, minor;
+ extern unsigned long HIGH_MEMORY;
+
+ major = MAJOR(inode->i_rdev);
+ minor = MINOR(inode->i_rdev);
+
+ /*
+ * for character devices, only /dev/mem may be mapped. when the
+ * swapping code is modified to allow arbitrary sources of pages,
+ * then we can open it up to regular files.
+ */
+
+ if (major != 1 || minor != 1)
+ return (caddr_t)-ENODEV;
+
+ /*
+ * we only allow mappings from address 0 to HIGH_MEMORY, since thats
+ * the range of our memory [actually this is a lie. the buffer cache
+ * and ramdisk occupy higher memory, but the paging stuff won't
+ * let us map to it anyway, so we break it here].
+ *
+ * this call is very dangerous! because of the lack of adequate
+ * tagging of frames, it is possible to mmap over a frame belonging
+ * to another (innocent) process. with MAP_SHARED|MAP_WRITE, this
+ * rogue process can trample over the other's data! we ignore this :{
+ * for now, we hope people will malloc the required amount of space,
+ * then mmap over it. the mm needs serious work before this can be
+ * truly useful.
+ */
+
+ if (len > HIGH_MEMORY || off > HIGH_MEMORY - len) /* avoid overflow */
+ return (caddr_t)-ENXIO;
+
+ if (remap_page_range(addr, off, len, PERMISS(flags, prot)))
+ return (caddr_t)-EAGAIN;
+
+ return (caddr_t)addr;
+}
+
+caddr_t
+sys_mmap(unsigned long *buffer)
+{
+ unsigned long base, addr;
+ unsigned long len, limit, off;
+ int prot, flags, fd;
+ struct file *file;
+ struct inode *inode;
+
+ addr = (unsigned long) get_fs_long(buffer); /* user address space*/
+ len = (size_t) get_fs_long(buffer+1); /* nbytes of mapping */
+ prot = (int) get_fs_long(buffer+2); /* protection */
+ flags = (int) get_fs_long(buffer+3); /* mapping type */
+ fd = (int) get_fs_long(buffer+4); /* object to map */
+ off = (unsigned long) get_fs_long(buffer+5); /* offset in object */
+
+ if (fd >= NR_OPEN || fd < 0 || !(file = current->filp[fd]))
+ return (caddr_t) -EBADF;
+ if (addr > TASK_SIZE || (addr+(unsigned long) len) > TASK_SIZE)
+ return (caddr_t) -EINVAL;
+ inode = file->f_inode;
+
+ /*
+ * do simple checking here so the lower-level routines won't have
+ * to. we assume access permissions have been handled by the open
+ * of the memory object, so we don't do any here.
+ */
+
+ switch (flags & MAP_TYPE) {
+ case MAP_SHARED:
+ if ((prot & PROT_WRITE) && !(file->f_mode & 2))
+ return (caddr_t)-EINVAL;
+ /* fall through */
+ case MAP_PRIVATE:
+ if (!(file->f_mode & 1))
+ return (caddr_t)-EINVAL;
+ break;
+
+ default:
+ return (caddr_t)-EINVAL;
+ }
+
+ /*
+ * obtain the address to map to. we verify (or select) it and ensure
+ * that it represents a valid section of the address space. we assume
+ * that if PROT_EXEC is specified this should be in the code segment.
+ */
+ if (prot & PROT_EXEC) {
+ base = get_base(current->ldt[1]); /* cs */
+ limit = get_limit(0x0f); /* cs limit */
+ } else {
+ base = get_base(current->ldt[2]); /* ds */
+ limit = get_limit(0x17); /* ds limit */
+ }
+
+ if (flags & MAP_FIXED) {
+ /*
+ * if MAP_FIXED is specified, we have to map exactly at this
+ * address. it must be page aligned and not ambiguous.
+ */
+ if ((addr & 0xfff) || addr > 0x7fffffff || addr == 0 ||
+ (off & 0xfff))
+ return (caddr_t)-EINVAL;
+ if (addr + len > limit)
+ return (caddr_t)-ENOMEM;
+ } else {
+ /*
+ * we're given a hint as to where to put the address.
+ * that we still need to search for a range of pages which
+ * are not mapped and which won't impact the stack or data
+ * segment.
+ * in linux, we only have a code segment and data segment.
+ * since data grows up and stack grows down, we're sort of
+ * stuck. placing above the data will break malloc, below
+ * the stack will cause stack overflow. because of this
+ * we don't allow nonspecified mappings...
+ */
+ return (caddr_t)-ENOMEM;
+ }
+
+ /*
+ * determine the object being mapped and call the appropriate
+ * specific mapper. the address has already been validated, but
+ * not unmapped
+ */
+ if (S_ISCHR(inode->i_mode))
+ addr = (unsigned long)mmap_chr(base + addr, len, prot, flags,
+ inode, off);
+ else
+ addr = (unsigned long)-ENODEV;
+ if ((long)addr > 0)
+ addr -= base;
+
+ return (caddr_t)addr;
+}
+
+int sys_munmap(unsigned long addr, size_t len)
+{
+ unsigned long base, limit;
+
+ base = get_base(current->ldt[2]); /* map into ds */
+ limit = get_limit(0x17); /* ds limit */
+
+ if ((addr & 0xfff) || addr > 0x7fffffff || addr == 0 ||
+ addr + len > limit)
+ return -EINVAL;
+ if (unmap_page_range(base + addr, len))
+ return -EAGAIN; /* should never happen */
+ return 0;
+}
diff --git a/mm/swap.c b/mm/swap.c
index 819bbe3..ba41399 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -9,11 +9,11 @@
* Started 18.12.91
*/
-#include <string.h>
#include <errno.h>
+#include <sys/stat.h>
#include <linux/mm.h>
-#include <sys/stat.h>
+#include <linux/string.h>
#include <linux/sched.h>
#include <linux/head.h>
#include <linux/kernel.h>
@@ -149,6 +149,12 @@ int try_to_swap_out(unsigned long * table_ptr)
/*
* Go through the page tables, searching for a user page that
* we can swap out.
+ *
+ * Here it's easy to add a check for tasks that may not be swapped out:
+ * loadable device drivers or similar. Just add an entry to the task-struct
+ * and check it at the same time you check for the existence of the task.
+ * The code assumes tasks are page-table aligned, but so do other parts
+ * of the memory manager...
*/
int swap_out(void)
{
@@ -156,12 +162,18 @@ int swap_out(void)
static int page_entry = -1;
int counter = VM_PAGES;
int pg_table;
+ struct task_struct * p;
check_dir:
if (counter < 0)
goto no_swap;
if (dir_entry >= 1024)
dir_entry = FIRST_VM_PAGE>>10;
+ if (!(p = task[dir_entry >> 4])) {
+ counter -= 1024;
+ dir_entry++;
+ goto check_dir;
+ }
if (!(1 & (pg_table = pg_dir[dir_entry]))) {
if (pg_table) {
printk("bad page-table at pg_dir[%d]: %08x\n\r",
@@ -184,10 +196,7 @@ check_table:
goto check_dir;
}
if (try_to_swap_out(page_entry + (unsigned long *) pg_table)) {
- if (! task[dir_entry >> 4])
- printk("swapping out page from non-existent task\n\r");
- else
- task[dir_entry >> 4]->rss--;
+ p->rss--;
return 1;
}
goto check_table;