aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Benedict Torvalds <torvalds@klaava.Helsinki.FI>1992-04-04 14:42:10 +0000
committerNicolas Pitre <nico@cam.org>2007-08-19 14:19:02 -0400
commit4fd4c0232da4a9f7e163df707699cd74c1dc6fa8 (patch)
tree87ac70daf7404f03dcd0957ce9e255f232feb82c
parentedb046236801c4975482840240127aeefdd0f7d7 (diff)
downloadarchive-4fd4c0232da4a9f7e163df707699cd74c1dc6fa8.tar.gz
Second 0.95a alpha-patchv0.95c
This is the promised patch to 0.95a, which hopefully corrects some of the problems encountered. This is /not/ an offical new release: it's just a set of patches to get the same kernel I am currently running. Bugfixes: - extended partitions should finally work correctly (this release also contains code for the hd-ioctl call, needed for fdisk). Code mostly by hedrick. - I corrected my original ptrace-fix (writing a long word to another process' data space could fail with my original patches) - 387-emulation bug with the instructions "fcom[p] %st(x)" which resulted in bad results on non-387 machines with newer versions of gcc. The emulation is still ugly, but it seems to work. - the cooked mode deletion/linekill bugs should be fixed. - various error-returns were wrong: I correted some of them (thanks to bruce evans who pointed them out). The bad error-values resulted in incorrect or spurious error-messages from 'rm' etc. - various minor fixes (including some in the hd-driver: this might help persons with unexpected-interrupt and/or timeout errors) Additionally this version contains VFS-code from entropy, and a readdir() system call needed for the VFS. The latter was inspired by patches sent by Remy Card, who did it with a getdirents sys-call. My version is slightly simpler, but is probably slower. Things might yet change. The installation has also changed slightly: the keyboard type and math-emulation are specified in the main Makefile. That one also contains the -fcombine-regs flag needed for 1.40. The other makefiles should no longer need editing. I've also incorporated the ps095 kernel patches: to get the actual user-level stuff you still have to get the ps-distribution. Printer ports /still/ aren't in there, but this time I positively /promise/ to put it in next week. Really. People who have been patching their kernel might have problems getting this patch to work: it was made against a clean 0.95a kernel. I'll consider a patched-up kernel version 0.95c - and I'd appreciate if future patches to me would be sent against this version. I'll still accept older patches, or course. Linus
-rw-r--r--Makefile78
-rw-r--r--boot/bootsect.S129
-rw-r--r--boot/setup.S20
-rw-r--r--fs/Makefile139
-rw-r--r--fs/buffer.c8
-rw-r--r--fs/char_dev.c85
-rw-r--r--fs/exec.c11
-rw-r--r--fs/inode.c28
-rw-r--r--fs/ioctl.c3
-rw-r--r--fs/minix/Makefile53
-rw-r--r--fs/minix/file_dev.c48
-rw-r--r--fs/minix/inode.c99
-rw-r--r--fs/minix/minix_op.c17
-rw-r--r--fs/minix/namei.c8
-rw-r--r--fs/namei.c20
-rw-r--r--fs/open.c5
-rw-r--r--fs/pipe.c2
-rw-r--r--fs/read_write.c31
-rw-r--r--fs/super.c123
-rw-r--r--include/a.out.h130
-rw-r--r--include/asm/io.h13
-rw-r--r--include/limits.h62
-rw-r--r--include/linux/fs.h28
-rw-r--r--include/linux/hdreg.h6
-rw-r--r--include/linux/minix_fs.h9
-rw-r--r--include/linux/sched.h7
-rw-r--r--include/linux/sys.h3
-rw-r--r--include/linux/tty.h32
-rw-r--r--include/sys/dirent.h13
-rw-r--r--include/unistd.h49
-rw-r--r--kernel/Makefile84
-rw-r--r--kernel/blk_drv/Makefile31
-rw-r--r--kernel/blk_drv/blk.h19
-rw-r--r--kernel/blk_drv/hd.c170
-rw-r--r--kernel/blk_drv/ll_rw_blk.c2
-rw-r--r--kernel/chr_drv/Makefile59
-rw-r--r--kernel/chr_drv/console.c4
-rw-r--r--kernel/chr_drv/keyboard.S1
-rw-r--r--kernel/chr_drv/pty.c4
-rw-r--r--kernel/chr_drv/serial.c8
-rw-r--r--kernel/chr_drv/tty_io.c24
-rw-r--r--kernel/chr_drv/tty_ioctl.c4
-rw-r--r--kernel/exit.c23
-rw-r--r--kernel/fork.c2
-rw-r--r--kernel/math/Makefile10
-rw-r--r--kernel/math/math_emulate.c10
-rw-r--r--kernel/ptrace.c246
-rw-r--r--kernel/sched.c11
-rw-r--r--kernel/sys.c4
-rw-r--r--lib/Makefile9
-rw-r--r--mm/Makefile28
-rw-r--r--mm/memory.c32
52 files changed, 1381 insertions, 663 deletions
diff --git a/Makefile b/Makefile
index e397dab..e06ae02 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,44 @@
#
+# comment this line if you don't want the emulation-code
+#
+
+MATH_EMULATION = -DKERNEL_MATH_EMULATION
+
+#
+# uncomment the correct keyboard:
+#
+
+KEYBOARD = -DKBD_FINNISH
+# KEYBOARD = -DKBD_US
+# KEYBOARD = -DKBD_GR
+# KEYBOARD = -DKBD_FR
+# KEYBOARD = -DKBD_UK
+# KEYBOARD = -DKBD_DK
+
+#
+# uncomment this line if you are using gcc-1.40
+#
+#GCC_OPT = -fcombine-regs
+
+#
+# standard CFLAGS
+#
+
+CFLAGS =-Wall -O -fstrength-reduce -fomit-frame-pointer $(GCC_OPT)
+
+#
+# ROOT_DEV specifies the default root-device when making the image.
+# This can be either FLOPPY, /dev/xxxx or empty, in which case the
+# default of FLOPPY is used by 'build'.
+#
+
+ROOT_DEV = /dev/hdb1
+
+#
# if you want the ram-disk device, define this to be the
# size in blocks.
#
+
#RAMDISK = -DRAMDISK=512
AS86 =as86 -0 -a
@@ -9,18 +46,12 @@ LD86 =ld86 -0
AS =as
LD =ld
-LDFLAGS =-s -x -M
+#LDFLAGS =-s -x -M
+LDFLAGS = -M
CC =gcc $(RAMDISK)
-CFLAGS =-Wall -O -fstrength-reduce -fomit-frame-pointer
+MAKE =make CFLAGS="$(CFLAGS)"
CPP =cpp -nostdinc -Iinclude
-#
-# ROOT_DEV specifies the default root-device when making the image.
-# This can be either FLOPPY, /dev/xxxx or empty, in which case the
-# default of FLOPPY is used by 'build'.
-#
-ROOT_DEV=/dev/hdb1
-
ARCHIVES =kernel/kernel.o mm/mm.o fs/fs.o
FILESYSTEMS =fs/minix/minix.o
DRIVERS =kernel/blk_drv/blk_drv.a kernel/chr_drv/chr_drv.a
@@ -39,7 +70,10 @@ LIBS =lib/lib.a
all: Image
Image: boot/bootsect boot/setup tools/system tools/build
- tools/build boot/bootsect boot/setup tools/system $(ROOT_DEV) > Image
+ cp tools/system system.tmp
+ strip system.tmp
+ tools/build boot/bootsect boot/setup system.tmp $(ROOT_DEV) > Image
+ rm system.tmp
sync
disk: Image
@@ -62,28 +96,28 @@ tools/system: boot/head.o init/main.o \
-o tools/system > System.map
kernel/math/math.a: dummy
- (cd kernel/math; make)
+ (cd kernel/math; $(MAKE) MATH_EMULATION="$(MATH_EMULATION)")
kernel/blk_drv/blk_drv.a: dummy
- (cd kernel/blk_drv; make)
+ (cd kernel/blk_drv; $(MAKE))
kernel/chr_drv/chr_drv.a: dummy
- (cd kernel/chr_drv; make)
+ (cd kernel/chr_drv; $(MAKE) KEYBOARD="$(KEYBOARD)")
kernel/kernel.o: dummy
- (cd kernel; make)
+ (cd kernel; $(MAKE))
mm/mm.o: dummy
- (cd mm; make)
+ (cd mm; $(MAKE))
fs/fs.o: dummy
- (cd fs; make)
+ (cd fs; $(MAKE))
fs/minix/minix.o: dummy
- (cd fs/minix; make)
+ (cd fs/minix; $(MAKE))
lib/lib.a: dummy
- (cd lib; make)
+ (cd lib; $(MAKE))
boot/setup: boot/setup.s
$(AS86) -o boot/setup.o boot/setup.s
@@ -127,7 +161,7 @@ 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/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
+ 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
diff --git a/boot/bootsect.S b/boot/bootsect.S
index 8a8ecb8..837be32 100644
--- a/boot/bootsect.S
+++ b/boot/bootsect.S
@@ -8,9 +8,13 @@ SYSSIZE = DEF_SYSSIZE
!
! bootsect.s (C) 1991 Linus Torvalds
! modified by Drew Eckhardt
+! modified by Bruce Evans (bde)
!
! bootsect.s is loaded at 0x7c00 by the bios-startup routines, and moves
-! iself out of the way to address 0x90000, and jumps there.
+! itself out of the way to address 0x90000, and jumps there.
+!
+! bde - should not jump blindly, there may be systems with only 512K low
+! memory. Use int 0x12 to get the top of memory, etc.
!
! It then loads 'setup' directly after itself (0x90200), and the system
! at 0x10000, using BIOS interrupts.
@@ -22,30 +26,27 @@ SYSSIZE = DEF_SYSSIZE
!
! The loader has been made as simple as possible, and continuos
! read errors will result in a unbreakable loop. Reboot by hand. It
-! loads pretty fast by getting whole sectors at a time whenever possible.
+! loads pretty fast by getting whole tracks at a time whenever possible.
-.globl begtext, begdata, begbss, endtext, enddata, endbss
-.text
-begtext:
-.data
-begdata:
-.bss
-begbss:
.text
-SETUPLEN = 4 ! nr of setup-sectors
-BOOTSEG = 0x07c0 ! original address of boot-sector
-INITSEG = DEF_INITSEG ! we move boot here - out of the way
-SETUPSEG = DEF_SETUPSEG ! setup starts here
-SYSSEG = DEF_SYSSEG ! system loaded at 0x10000 (65536).
-ENDSEG = SYSSEG + SYSSIZE ! where to stop loading
+SETUPSECS = 4 ! nr of setup-sectors
+BOOTSEG = 0x07C0 ! original address of boot-sector
+INITSEG = DEF_INITSEG ! we move boot here - out of the way
+SETUPSEG = DEF_SETUPSEG ! setup starts here
+SYSSEG = DEF_SYSSEG ! system loaded at 0x10000 (65536).
+ENDSEG = SYSSEG + SYSSIZE ! where to stop loading
! ROOT_DEV & SWAP_DEV are now written by "build".
ROOT_DEV = 0
SWAP_DEV = 0
-entry start
-start:
+! ld86 requires an entry symbol. This may as well be the usual one.
+.globl _main
+_main:
+#if 0 /* hook for debugger, harmless unless BIOS is fussy (old HP) */
+ int 3
+#endif
mov ax,#BOOTSEG
mov ds,ax
mov ax,#INITSEG
@@ -55,17 +56,25 @@ start:
sub di,di
cld
rep
- movw
+ movsw
jmpi go,INITSEG
go: mov ax,cs
- mov dx,#0xfef4 ! arbitrary value >>512 - disk parm size
+ mov dx,#0x4000-12 ! 0x4000 is arbitrary value >= length of
+ ! bootsect + length of setup + room for stack
+ ! 12 is disk parm size
+
+! bde - changed 0xff00 to 0x4000 to use debugger at 0x6400 up (bde). We
+! wouldn't have to worry about this if we checked the top of memory. Also
+! my BIOS can be configured to put the wini drive tables in high memory
+! instead of in the vector table. The old stack might have clobbered the
+! drive table.
mov ds,ax
mov es,ax
push ax
- mov ss,ax ! put stack at 0x9ff00 - 12.
+ mov ss,ax ! put stack at INITSEG:0x4000-12.
mov sp,dx
/*
* Many BIOS's default disk parameter tables will not
@@ -96,7 +105,7 @@ go: mov ax,cs
rep
seg gs
- movw
+ movsw
mov di,dx
movb 4(di),*18 ! patch sector count
@@ -121,7 +130,8 @@ load_setup:
xor dx, dx ! drive 0, head 0
mov cx,#0x0002 ! sector 2, track 0
mov bx,#0x0200 ! address = 512, in INITSEG
- mov ax,#0x0200+SETUPLEN ! service 2, nr of sectors
+ mov ax,#0x0200+SETUPSECS ! service 2, nr of sectors
+ ! (assume all on head 0, track 0)
int 0x13 ! read it
jnc ok_load_setup ! ok - continue
@@ -134,16 +144,43 @@ load_setup:
xor dl, dl ! reset FDC
xor ah, ah
int 0x13
- j load_setup
+ jmp load_setup
ok_load_setup:
! Get disk drive parameters, specifically nr of sectors/track
+#if 0
+
+! bde - the Phoenix BIOS manual says function 0x08 only works for fixed
+! disks. It doesn't work for one of my BIOS's (1987 Award). It was
+! fatal not to check the error code.
+
xor dl,dl
mov ah,#0x08 ! AH=8 is get drive parameters
int 0x13
xor ch,ch
+#else
+
+! It seems that there is no BIOS call to get the number of sectors. Guess
+! 18 sectors if sector 18 can be read, 15 if sector 15 can be read.
+! Otherwise guess 9.
+
+ xor dx, dx ! drive 0, head 0
+ mov cx,#0x0012 ! sector 18, track 0
+ mov bx,#0x0200+SETUPSECS*0x200 ! address after setup (es = cs)
+ mov ax,#0x0201 ! service 2, 1 sector
+ int 0x13
+ jnc got_sectors
+ mov cl,#0x0f ! sector 15
+ mov ax,#0x0201 ! service 2, 1 sector
+ int 0x13
+ jnc got_sectors
+ mov cl,#0x09
+
+#endif
+
+got_sectors:
seg cs
mov sectors,cx
mov ax,#INITSEG
@@ -205,7 +242,7 @@ root_defined:
!
! in: es - starting address segment (normally 0x1000)
!
-sread: .word 1+SETUPLEN ! sectors read of current track
+sread: .word 1+SETUPSECS ! sectors read of current track
head: .word 0 ! current head
track: .word 0 ! current track
@@ -264,23 +301,23 @@ read_track:
int 0x10
popa
- mov dx,track
- mov cx,sread
- inc cx
- mov ch,dl
- mov dx,head
- mov dh,dl
- and dx,#0x0100
- mov ah,#2
+ mov dx,track
+ mov cx,sread
+ inc cx
+ mov ch,dl
+ mov dx,head
+ mov dh,dl
+ and dx,#0x0100
+ mov ah,#2
push dx ! save for error dump
push cx
push bx
push ax
- int 0x13
- jc bad_rt
- add sp, #8
+ int 0x13
+ jc bad_rt
+ add sp, #8
popa
ret
@@ -317,16 +354,18 @@ print_all:
print_loop:
push cx ! save count left
call print_nl ! nl for readability
+
+ cmp cl, 5
jae no_reg ! see if register name is needed
- mov ax, #0xe05 + 0x41 - 1
+ mov ax, #0xe05 + 'A - 1
sub al, cl
int 0x10
- mov al, #0x58 ! X
+ mov al, #'X
int 0x10
- mov al, #0x3a ! :
+ mov al, #':
int 0x10
no_reg:
@@ -356,10 +395,10 @@ print_digit:
mov ah, #0xe
mov al, dl ! mask off so we have only next nibble
and al, #0xf
- add al, #0x30 ! convert to 0 based digit, '0'
- cmp al, #0x39 ! check for overflow
+ add al, #'0 ! convert to 0-based digit
+ cmp al, #'9 ! check for overflow
jbe good_digit
- add al, #0x41 - 0x30 - 0xa ! 'A' - '0' - 0xa
+ add al, #'A - '0 - 10
good_digit:
int 0x10
@@ -394,11 +433,3 @@ root_dev:
.word ROOT_DEV
boot_flag:
.word 0xAA55
-
-.text
-endtext:
-.data
-enddata:
-.bss
-endbss:
-
diff --git a/boot/setup.S b/boot/setup.S
index 7e9d132..bd23161 100644
--- a/boot/setup.S
+++ b/boot/setup.S
@@ -217,6 +217,22 @@ empty_8042:
jnz empty_8042 ! yes - loop
ret
+getkey:
+ in al,#0x60 ! Quick and dirty...
+ .word 0x00eb,0x00eb ! jmp $+2, jmp $+2
+ mov bl,al
+ in al,#0x61
+ .word 0x00eb,0x00eb
+ mov ah,al
+ or al,#0x80
+ out #0x61,al
+ .word 0x00eb,0x00eb
+ mov al,ah
+ out #0x61,al
+ .word 0x00eb,0x00eb
+ mov al,bl
+ ret
+
! Routine trying to recognize type of SVGA-board present (if any)
! and if it recognize one gives the choices of resolution it offers.
! If one is found the resolution chosen is given by al,ah (rows,cols).
@@ -233,7 +249,7 @@ flush: in al,#0x60 ! Flush the keyboard buffer
cmp al,#0x82
jb nokey
jmp flush
-nokey: in al,#0x60
+nokey: call getkey
cmp al,#0x82
jb nokey
cmp al,#0xe0
@@ -481,7 +497,7 @@ tbl: pop bx
call prtstr
pop si
add cl,#0x80
-nonum: in al,#0x60 ! Quick and dirty...
+nonum: call getkey
cmp al,#0x82
jb nonum
cmp al,#0x8b
diff --git a/fs/Makefile b/fs/Makefile
index 55bcd62..312f2f6 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -1,10 +1,17 @@
+#
+# Makefile for the linux filesystem.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
AR =ar
AS =as
-CC =gcc
LD =ld
-CFLAGS =-Wall -O -fstrength-reduce -fomit-frame-pointer \
- -fno-defer-pop -nostdinc -I../include
-CPP =gcc -E -nostdinc -I../include
+CC =gcc -nostdinc -I../include
+CPP =cpp -nostdinc -I../include
.c.s:
$(CC) $(CFLAGS) \
@@ -36,83 +43,95 @@ 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/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/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/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/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/io.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/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
+ ../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/string.h ../include/errno.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 ../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/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/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/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/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/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/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
+ ../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/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/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/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/sys/stat.h ../include/sys/types.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/signal.h ../include/sys/param.h ../include/sys/time.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 \
+ ../include/asm/segment.h
select.o : select.c ../include/linux/fs.h ../include/sys/types.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
+ ../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/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/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/linux/minix_fs.h \
- ../include/asm/system.h ../include/errno.h ../include/sys/stat.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
diff --git a/fs/buffer.c b/fs/buffer.c
index d4aaa06..54fa805 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -27,8 +27,8 @@
#include <asm/io.h>
extern int end;
-struct buffer_head * start_buffer = (struct buffer_head *) &end;
-struct buffer_head * hash_table[NR_HASH];
+static struct buffer_head * start_buffer = (struct buffer_head *) &end;
+static struct buffer_head * hash_table[NR_HASH];
static struct buffer_head * free_list;
static struct task_struct * buffer_wait = NULL;
int NR_BUFFERS = 0;
@@ -406,6 +406,10 @@ void buffer_init(long buffer_end)
else
b = (void *) buffer_end;
while ( (b -= BLOCK_SIZE) >= ((void *) (h+1)) ) {
+ if (((unsigned long) (h+1)) > 0xA0000) {
+ printk("buffer-list doesn't fit in low meg - contact Linus\n");
+ break;
+ }
h->b_dev = 0;
h->b_dirt = 0;
h->b_count = 0;
diff --git a/fs/char_dev.c b/fs/char_dev.c
index daf0269..b174dcb 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -38,26 +38,81 @@ static int rw_ram(int rw,char * buf, int count, off_t *pos)
static int rw_mem(int rw,char * buf, int count, off_t * pos)
{
- return -EIO;
+ 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)
{
- /* kmem by Damiano */
- int i = *pos; /* Current position where to read */
-
- /* i can go from 0 to LOW_MEM (See include/linux/mm.h */
- /* I am not shure about it but it doesn't mem fault :-) */
- while ( (count-- > 0) && (i <LOW_MEM) ) {
- if (rw==READ)
- put_fs_byte( *(char *)i ,buf++);
- else
- return (-EIO);
- i++;
+ 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;
}
- i -= *pos; /* Count how many read or write */
- *pos += i; /* Update position */
- return (i); /* Return number read */
+ p -= *pos;
+ *pos += (int) p;
+ return (int) p;
}
static int rw_port(int rw,char * buf, int count, off_t * pos)
diff --git a/fs/exec.c b/fs/exec.c
index 2195ff9..f27b51f 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -216,6 +216,7 @@ int do_execve(unsigned long * eip,long tmp,char * filename,
int retval;
int sh_bang = 0;
unsigned long p=PAGE_SIZE*MAX_ARG_PAGES-4;
+ int ch;
if ((0xffff & eip[1]) != 0x000f)
panic("execve called from supervisor mode");
@@ -348,6 +349,15 @@ 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;
+ else
+ if (i < 8)
+ current->comm[i++] = ch;
+ if (i < 8)
+ current->comm[i] = '\0';
+
if (current->executable)
iput(current->executable);
current->executable = inode;
@@ -374,6 +384,7 @@ restart_interp:
(current->end_data = ex.a_data +
(current->end_code = ex.a_text));
current->start_stack = p;
+ current->rss = (LIBRARY_OFFSET - p + PAGE_SIZE-1) / PAGE_SIZE;
current->suid = current->euid = e_uid;
current->sgid = current->egid = e_gid;
eip[0] = ex.a_entry; /* eip, magic happens :-) */
diff --git a/fs/inode.c b/fs/inode.c
index 7173e23..c1634d8 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -8,16 +8,12 @@
#include <sys/stat.h>
#include <linux/sched.h>
-#include <linux/minix_fs.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <asm/system.h>
struct inode inode_table[NR_INODE]={{0,},};
-extern void minix_read_inode(struct inode * inode);
-extern void minix_write_inode(struct inode * inode);
-
static inline void wait_on_inode(struct inode * inode)
{
cli();
@@ -48,20 +44,34 @@ static void write_inode(struct inode * inode)
unlock_inode(inode);
return;
}
- minix_write_inode(inode);
+ if (inode->i_op && inode->i_op->write_inode)
+ inode->i_op->write_inode(inode);
unlock_inode(inode);
}
static void read_inode(struct inode * inode)
{
lock_inode(inode);
- minix_read_inode(inode);
+ if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->read_inode)
+ inode->i_sb->s_op->read_inode(inode);
unlock_inode(inode);
}
+/*
+ * bmap is needed for demand-loading and paging: if this function
+ * doesn't exist for a filesystem, then those things are impossible:
+ * executables cannot be run from the filesystem etc...
+ *
+ * This isn't as bad as it sounds: the read-routines might still work,
+ * so the filesystem would be otherwise ok (for example, you might have
+ * a DOS filesystem, which doesn't lend itself to bmap very well, but
+ * you could still transfer files to/from the filesystem)
+ */
int bmap(struct inode * inode, int block)
{
- return minix_bmap(inode,block);
+ if (inode->i_op && inode->i_op->bmap)
+ return inode->i_op->bmap(inode,block);
+ return 0;
}
void invalidate_inodes(int dev)
@@ -127,8 +137,8 @@ repeat:
return;
}
if (!inode->i_nlink) {
- minix_truncate(inode);
- minix_free_inode(inode);
+ if (inode->i_op && inode->i_op->put_inode)
+ inode->i_op->put_inode(inode);
return;
}
if (inode->i_dirt) {
diff --git a/fs/ioctl.c b/fs/ioctl.c
index d293a92..284a0dc 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -10,6 +10,7 @@
#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);
@@ -21,7 +22,7 @@ static ioctl_ptr ioctl_table[]={
NULL, /* nodev */
NULL, /* /dev/mem */
NULL, /* /dev/fd */
- NULL, /* /dev/hd */
+ hd_ioctl, /* /dev/hd */
tty_ioctl, /* /dev/ttyx */
tty_ioctl, /* /dev/tty */
NULL, /* /dev/lp */
diff --git a/fs/minix/Makefile b/fs/minix/Makefile
index 967bda5..fd1a331 100644
--- a/fs/minix/Makefile
+++ b/fs/minix/Makefile
@@ -1,10 +1,17 @@
+#
+# Makefile for the linux minix-filesystem routines.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
AR =ar
AS =as
-CC =gcc
LD =ld
-CFLAGS =-Wall -O -fstrength-reduce -fomit-frame-pointer \
- -nostdinc -I../../include
-CPP =gcc -E -nostdinc -I../../include
+CC =gcc -nostdinc -I../../include
+CPP =cpp -nostdinc -I../../include
.c.s:
$(CC) $(CFLAGS) \
@@ -32,12 +39,14 @@ dep:
### Dependencies:
bitmap.o : bitmap.c ../../include/string.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 \
- ../../include/sys/resource.h ../../include/linux/minix_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/linux/sched.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 \
@@ -46,14 +55,17 @@ file_dev.o : file_dev.c ../../include/errno.h ../../include/fcntl.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/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/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/linux/mm.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 \
@@ -61,9 +73,10 @@ namei.o : namei.c ../../include/linux/sched.h ../../include/linux/head.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/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/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/file_dev.c b/fs/minix/file_dev.c
index d9d1fb9..525aa7b 100644
--- a/fs/minix/file_dev.c
+++ b/fs/minix/file_dev.c
@@ -6,6 +6,8 @@
#include <errno.h>
#include <fcntl.h>
+#include <sys/dirent.h>
+#include <sys/stat.h>
#include <linux/sched.h>
#include <linux/minix_fs.h>
@@ -15,6 +17,48 @@
#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)
+{
+ unsigned int block,offset,i;
+ char c;
+ struct buffer_head * bh;
+ struct minix_dir_entry * de;
+
+ if (!S_ISDIR(inode->i_mode))
+ return -EBADF;
+ if (filp->f_pos & 15)
+ return -EBADF;
+ while (filp->f_pos < inode->i_size) {
+ offset = filp->f_pos & 1023;
+ block = minix_bmap(inode,(filp->f_pos)>>BLOCK_SIZE_BITS);
+ if (!block || !(bh = bread(inode->i_dev,block))) {
+ filp->f_pos += 1024-offset;
+ continue;
+ }
+ de = (struct minix_dir_entry *) (offset + bh->b_data);
+ while (offset < 1024 && filp->f_pos < inode->i_size) {
+ offset += 16;
+ filp->f_pos += 16;
+ if (de->inode) {
+ for (i = 0; i < 14; i++)
+ if (c = de->name[i])
+ put_fs_byte(c,i+dirent->d_name);
+ else
+ break;
+ if (i) {
+ put_fs_long(de->inode,&dirent->d_ino);
+ put_fs_byte(0,i+dirent->d_name);
+ put_fs_word(i,&dirent->d_reclen);
+ return i;
+ }
+ }
+ de++;
+ }
+ brelse(bh);
+ }
+ return 0;
+}
+
int minix_file_read(struct inode * inode, struct file * filp, char * buf, int count)
{
int read,left,chars,nr;
@@ -28,7 +72,7 @@ int minix_file_read(struct inode * inode, struct file * filp, char * buf, int co
left = count;
read = 0;
while (left > 0) {
- if (nr = bmap(inode,(filp->f_pos)>>BLOCK_SIZE_BITS)) {
+ if (nr = minix_bmap(inode,(filp->f_pos)>>BLOCK_SIZE_BITS)) {
if (!(bh=bread(inode->i_dev,nr)))
return read?read:-EIO;
} else
@@ -98,7 +142,7 @@ int minix_file_write(struct inode * inode, struct file * filp, char * buf, int c
if (!(filp->f_flags & O_APPEND)) {
filp->f_pos = pos;
inode->i_ctime = CURRENT_TIME;
- inode->i_dirt = 1;
}
+ inode->i_dirt = 1;
return written;
}
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index a4dab05..75ec7a2 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -13,15 +13,100 @@
#include <linux/mm.h>
#include <asm/system.h>
-static int _bmap(struct inode * inode,int block,int create)
+int sync_dev(int dev);
+
+void minix_put_super(struct super_block *sb)
+{
+ int i;
+
+ lock_super(sb);
+ sb->s_dev = 0;
+ for(i = 0 ; i < MINIX_I_MAP_SLOTS ; i++)
+ brelse(sb->s_imap[i]);
+ for(i = 0 ; i < MINIX_Z_MAP_SLOTS ; i++)
+ brelse(sb->s_zmap[i]);
+ free_super(sb);
+ return;
+}
+
+static struct super_operations minix_sops = {
+ minix_read_inode,
+ minix_put_super
+};
+
+struct super_block *minix_read_super(struct super_block *s,void *data)
+{
+ struct buffer_head *bh;
+ int i,dev=s->s_dev,block;
+
+ lock_super(s);
+ if (!(bh = bread(dev,1))) {
+ s->s_dev=0;
+ free_super(s);
+ printk("bread failed\n");
+ return NULL;
+ }
+ *((struct minix_super_block *) s) =
+ *((struct minix_super_block *) bh->b_data);
+ brelse(bh);
+ if (s->s_magic != MINIX_SUPER_MAGIC) {
+ s->s_dev = 0;
+ free_super(s);
+ printk("magic match failed\n");
+ return NULL;
+ }
+ for (i=0;i < MINIX_I_MAP_SLOTS;i++)
+ s->s_imap[i] = NULL;
+ for (i=0;i < MINIX_Z_MAP_SLOTS;i++)
+ s->s_zmap[i] = NULL;
+ block=2;
+ for (i=0 ; i < s->s_imap_blocks ; i++)
+ if (s->s_imap[i]=bread(dev,block))
+ block++;
+ else
+ break;
+ for (i=0 ; i < s->s_zmap_blocks ; i++)
+ if (s->s_zmap[i]=bread(dev,block))
+ block++;
+ else
+ break;
+ if (block != 2+s->s_imap_blocks+s->s_zmap_blocks) {
+ for(i=0;i<MINIX_I_MAP_SLOTS;i++)
+ brelse(s->s_imap[i]);
+ for(i=0;i<MINIX_Z_MAP_SLOTS;i++)
+ brelse(s->s_zmap[i]);
+ s->s_dev=0;
+ free_super(s);
+ printk("block failed\n");
+ return NULL;
+ }
+ s->s_imap[0]->b_data[0] |= 1;
+ s->s_zmap[0]->b_data[0] |= 1;
+ free_super(s);
+ /* set up enough so that it can read an inode */
+ s->s_dev = dev;
+ s->s_op = &minix_sops;
+ if (!(s->s_mounted = iget(dev,MINIX_ROOT_INO))) {
+ s->s_dev=0;
+ printk("get root inode failed\n");
+ return NULL;
+ }
+ return s;
+}
+
+static int _minix_bmap(struct inode * inode,int block,int create)
{
struct buffer_head * bh;
int i;
- if (block<0)
- panic("_bmap: block<0");
- if (block >= 7+512+512*512)
- panic("_bmap: block>big");
+ if (block<0) {
+ printk("_minix_bmap: block<0");
+ return 0;
+ }
+ if (block >= 7+512+512*512) {
+ printk("_minix_bmap: block>big");
+ return 0;
+ }
if (block<7) {
if (create && !inode->i_data[block])
if (inode->i_data[block]=minix_new_block(inode->i_dev)) {
@@ -83,12 +168,12 @@ static int _bmap(struct inode * inode,int block,int create)
int minix_bmap(struct inode * inode,int block)
{
- return _bmap(inode,block,0);
+ return _minix_bmap(inode,block,0);
}
int minix_create_block(struct inode * inode, int block)
{
- return _bmap(inode,block,1);
+ return _minix_bmap(inode,block,1);
}
void minix_read_inode(struct inode * inode)
diff --git a/fs/minix/minix_op.c b/fs/minix/minix_op.c
index a85e3a8..7fd5559 100644
--- a/fs/minix/minix_op.c
+++ b/fs/minix/minix_op.c
@@ -7,6 +7,12 @@
#include <linux/fs.h>
#include <linux/minix_fs.h>
+void minix_put_inode(struct inode *inode)
+{
+ minix_truncate(inode);
+ minix_free_inode(inode);
+}
+
/*
* These are the low-level inode operations for minix filesystem inodes.
*/
@@ -23,16 +29,21 @@ struct inode_operations minix_inode_operations = {
minix_readlink,
minix_open,
minix_release,
- minix_follow_link
+ minix_follow_link,
+ minix_bmap,
+ minix_truncate,
+ minix_write_inode,
+ minix_put_inode
};
/*
- * We have just NULL's here: the current defaults are ok for
+ * We have mostly NULL's here: the current defaults are ok for
* the minix filesystem.
*/
struct file_operations minix_file_operations = {
NULL, /* lseek */
NULL, /* read */
- NULL /* write */
+ NULL, /* write */
+ minix_readdir
};
diff --git a/fs/minix/namei.c b/fs/minix/namei.c
index d3c0224..ba891cb 100644
--- a/fs/minix/namei.c
+++ b/fs/minix/namei.c
@@ -15,10 +15,6 @@
#include <const.h>
#include <sys/stat.h>
-extern int permission(struct inode * inode,int mask);
-extern struct inode * _namei(const char * filename, struct inode * base,
- int follow_links);
-
/*
* comment out this line if you want names > MINIX_NAME_LEN chars to be
* truncated. Else they will be disallowed.
@@ -89,7 +85,7 @@ static struct buffer_head * minix_find_entry(struct inode * dir,
if ((char *)de >= BLOCK_SIZE+bh->b_data) {
brelse(bh);
bh = NULL;
- if (!(block = bmap(dir,i/MINIX_DIR_ENTRIES_PER_BLOCK)) ||
+ if (!(block = minix_bmap(dir,i/MINIX_DIR_ENTRIES_PER_BLOCK)) ||
!(bh = bread(dir->i_dev,block))) {
i += MINIX_DIR_ENTRIES_PER_BLOCK;
continue;
@@ -398,7 +394,7 @@ static int empty_dir(struct inode * inode)
while (nr<len) {
if ((void *) de >= (void *) (bh->b_data+BLOCK_SIZE)) {
brelse(bh);
- block=bmap(inode,nr/MINIX_DIR_ENTRIES_PER_BLOCK);
+ block = minix_bmap(inode,nr/MINIX_DIR_ENTRIES_PER_BLOCK);
if (!block) {
nr += MINIX_DIR_ENTRIES_PER_BLOCK;
continue;
diff --git a/fs/namei.c b/fs/namei.c
index f1a0e8f..6833d62 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -9,7 +9,6 @@
*/
#include <linux/sched.h>
-#include <linux/minix_fs.h>
#include <linux/kernel.h>
#include <asm/segment.h>
@@ -249,7 +248,8 @@ int open_namei(const char * pathname, int flag, int mode,
}
inode->i_atime = CURRENT_TIME;
if (flag & O_TRUNC)
- minix_truncate(inode);
+ if (inode->i_op && inode->i_op->truncate)
+ inode->i_op->truncate(inode);
*res_inode = inode;
return 0;
}
@@ -270,7 +270,7 @@ int sys_mknod(const char * filename, int mode, int dev)
}
if (!permission(dir,MAY_WRITE)) {
iput(dir);
- return -EPERM;
+ return -EACCES;
}
if (!dir->i_op || !dir->i_op->mknod) {
iput(dir);
@@ -293,7 +293,7 @@ int sys_mkdir(const char * pathname, int mode)
}
if (!permission(dir,MAY_WRITE)) {
iput(dir);
- return -EPERM;
+ return -EACCES;
}
if (!dir->i_op || !dir->i_op->mkdir) {
iput(dir);
@@ -316,7 +316,7 @@ int sys_rmdir(const char * name)
}
if (!permission(dir,MAY_WRITE)) {
iput(dir);
- return -EPERM;
+ return -EACCES;
}
if (!dir->i_op || !dir->i_op->rmdir) {
iput(dir);
@@ -335,11 +335,11 @@ int sys_unlink(const char * name)
return -ENOENT;
if (!namelen) {
iput(dir);
- return -ENOENT;
+ return -EPERM;
}
if (!permission(dir,MAY_WRITE)) {
iput(dir);
- return -EPERM;
+ return -EACCES;
}
if (!dir->i_op || !dir->i_op->unlink) {
iput(dir);
@@ -356,14 +356,14 @@ int sys_symlink(const char * oldname, const char * newname)
dir = dir_namei(newname,&namelen,&basename, NULL);
if (!dir)
- return -EACCES;
+ return -ENOENT;
if (!namelen) {
iput(dir);
- return -EPERM;
+ return -ENOENT;
}
if (!permission(dir,MAY_WRITE)) {
iput(dir);
- return -EPERM;
+ return -EACCES;
}
if (!dir->i_op || !dir->i_op->symlink) {
iput(dir);
diff --git a/fs/open.c b/fs/open.c
index 9653b83..fe0fb5b 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -29,6 +29,11 @@ int sys_utime(char * filename, struct utimbuf * times)
if (!(inode=namei(filename)))
return -ENOENT;
if (times) {
+ if (current->euid != inode->i_uid &&
+ !permission(inode,MAY_WRITE)) {
+ iput(inode);
+ return -EPERM;
+ }
actime = get_fs_long((unsigned long *) &times->actime);
modtime = get_fs_long((unsigned long *) &times->modtime);
} else
diff --git a/fs/pipe.c b/fs/pipe.c
index d1b6e7c..5f773d9 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -41,7 +41,7 @@ int pipe_read(struct inode * inode, struct file * filp, char * buf, int count)
put_fs_byte(((char *)inode->i_size)[size++],buf++);
}
wake_up(& PIPE_WRITE_WAIT(*inode));
- return read;
+ return read?read:-EAGAIN;
}
int pipe_write(struct inode * inode, struct file * filp, char * buf, int count)
diff --git a/fs/read_write.c b/fs/read_write.c
index da81a6f..e99c287 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -4,18 +4,33 @@
* (C) 1991 Linus Torvalds
*/
-#include <sys/stat.h>
#include <errno.h>
#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/dirent.h>
#include <linux/kernel.h>
#include <linux/sched.h>
+#include <linux/minix_fs.h>
#include <asm/segment.h>
-int sys_lseek(unsigned int fd,off_t offset, unsigned int origin)
+int sys_readdir(unsigned int fd, struct dirent * dirent)
{
struct file * file;
- int tmp;
+ struct inode * inode;
+
+ if (fd >= NR_OPEN || !(file = current->filp[fd]) ||
+ !(inode = file->f_inode))
+ return -EBADF;
+ if (file->f_op && file->f_op->readdir)
+ return file->f_op->readdir(inode,file,dirent);
+ return -EBADF;
+}
+
+int sys_lseek(unsigned int fd, off_t offset, unsigned int origin)
+{
+ struct file * file;
+ int tmp, mem_dev;
if (fd >= NR_OPEN || !(file=current->filp[fd]) || !(file->f_inode))
return -EBADF;
@@ -25,21 +40,25 @@ int sys_lseek(unsigned int fd,off_t offset, unsigned int origin)
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) return -EINVAL;
+ if (offset<0 && !mem_dev) return -EINVAL;
file->f_pos=offset;
break;
case 1:
- if (file->f_pos+offset<0) return -EINVAL;
+ if (file->f_pos+offset<0 && !mem_dev) return -EINVAL;
file->f_pos += offset;
break;
case 2:
- if ((tmp=file->f_inode->i_size+offset) < 0)
+ if ((tmp=file->f_inode->i_size+offset)<0 && !mem_dev)
return -EINVAL;
file->f_pos = tmp;
}
+ if (mem_dev && file->f_pos < 0)
+ return 0;
return file->f_pos;
}
diff --git a/fs/super.c b/fs/super.c
index eedff32..b4c95e0 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -29,7 +29,26 @@ struct super_block super_block[NR_SUPER];
/* this is initialized in init/main.c */
int ROOT_DEV = 0;
-static void lock_super(struct super_block * sb)
+/* Move into include file later */
+
+static struct file_system_type file_systems[] = {
+ {minix_read_super,"minix"},
+ {NULL,NULL}
+};
+
+/* end of include file */
+
+struct file_system_type *get_fs_type(char *name)
+{
+ int a;
+
+ for(a = 0 ; file_systems[a].read_super ; a++)
+ if (!strcmp(name,file_systems[a].name))
+ return(&file_systems[a]);
+ return(NULL);
+}
+
+void lock_super(struct super_block * sb)
{
cli();
while (sb->s_lock)
@@ -38,7 +57,7 @@ static void lock_super(struct super_block * sb)
sti();
}
-static void free_super(struct super_block * sb)
+void free_super(struct super_block * sb)
{
cli();
sb->s_lock = 0;
@@ -46,7 +65,7 @@ static void free_super(struct super_block * sb)
sti();
}
-static void wait_on_super(struct super_block * sb)
+void wait_on_super(struct super_block * sb)
{
cli();
while (sb->s_lock)
@@ -75,7 +94,6 @@ struct super_block * get_super(int dev)
void put_super(int dev)
{
struct super_block * sb;
- int i;
if (dev == ROOT_DEV) {
printk("root diskette changed: prepare for armageddon\n\r");
@@ -87,27 +105,24 @@ void put_super(int dev)
printk("Mounted disk changed - tssk, tssk\n\r");
return;
}
- lock_super(sb);
- sb->s_dev = 0;
- for(i=0;i<MINIX_I_MAP_SLOTS;i++)
- brelse(sb->s_imap[i]);
- for(i=0;i<MINIX_Z_MAP_SLOTS;i++)
- brelse(sb->s_zmap[i]);
- free_super(sb);
- return;
+ if (sb->s_op && sb->s_op->put_super)
+ sb->s_op->put_super(sb);
}
-static struct super_block * read_super(int dev)
+static struct super_block * read_super(int dev,char *name,void *data)
{
struct super_block * s;
- struct buffer_head * bh;
- int i,block;
+ struct file_system_type *type;
if (!dev)
return NULL;
check_disk_change(dev);
if (s = get_super(dev))
return s;
+ if (!(type=get_fs_type(name))) {
+ printk("get fs type failed %s\n",name);
+ return NULL;
+ }
for (s = 0+super_block ;; s++) {
if (s >= NR_SUPER+super_block)
return NULL;
@@ -115,53 +130,14 @@ static struct super_block * read_super(int dev)
break;
}
s->s_dev = dev;
- s->s_mounted = NULL;
+ if (!type->read_super(s,data))
+ return(NULL);
+ s->s_dev = dev;
s->s_covered = NULL;
s->s_time = 0;
s->s_rd_only = 0;
s->s_dirt = 0;
- lock_super(s);
- if (!(bh = bread(dev,1))) {
- s->s_dev=0;
- free_super(s);
- return NULL;
- }
- *((struct minix_super_block *) s) =
- *((struct minix_super_block *) bh->b_data);
- brelse(bh);
- if (s->s_magic != MINIX_SUPER_MAGIC) {
- s->s_dev = 0;
- free_super(s);
- return NULL;
- }
- for (i=0;i < MINIX_I_MAP_SLOTS;i++)
- s->s_imap[i] = NULL;
- for (i=0;i < MINIX_Z_MAP_SLOTS;i++)
- s->s_zmap[i] = NULL;
- block=2;
- for (i=0 ; i < s->s_imap_blocks ; i++)
- if (s->s_imap[i]=bread(dev,block))
- block++;
- else
- break;
- for (i=0 ; i < s->s_zmap_blocks ; i++)
- if (s->s_zmap[i]=bread(dev,block))
- block++;
- else
- break;
- if (block != 2+s->s_imap_blocks+s->s_zmap_blocks) {
- for(i=0;i<MINIX_I_MAP_SLOTS;i++)
- brelse(s->s_imap[i]);
- for(i=0;i<MINIX_Z_MAP_SLOTS;i++)
- brelse(s->s_zmap[i]);
- s->s_dev=0;
- free_super(s);
- return NULL;
- }
- s->s_imap[0]->b_data[0] |= 1;
- s->s_zmap[0]->b_data[0] |= 1;
- free_super(s);
- return s;
+ return(s);
}
int sys_umount(char * dev_name)
@@ -184,7 +160,7 @@ int sys_umount(char * dev_name)
return -ENOENT;
if (!sb->s_covered->i_mount)
printk("Mounted inode has i_mount=0\n");
- for (inode=inode_table+0 ; inode<inode_table+NR_INODE ; inode++)
+ for (inode = inode_table+0 ; inode < inode_table+NR_INODE ; inode++)
if (inode->i_dev==dev && inode->i_count)
if (inode == sb->s_mounted && inode->i_count == 1)
continue;
@@ -195,8 +171,8 @@ int sys_umount(char * dev_name)
sb->s_covered = NULL;
iput(sb->s_mounted);
sb->s_mounted = NULL;
- put_super(dev);
- sync_dev(dev);
+ put_super(dev);
+ sync_dev(dev);
return 0;
}
@@ -224,25 +200,21 @@ int sys_mount(char * dev_name, char * dir_name, int rw_flag)
iput(dir_i);
return -EPERM;
}
- if (!(sb=read_super(dev))) {
+ if (dir_i->i_mount) {
iput(dir_i);
- return -EBUSY;
+ return -EPERM;
}
- if (sb->s_covered) {
+ if (!(sb=read_super(dev,"minix",NULL))) {
iput(dir_i);
return -EBUSY;
}
- if (dir_i->i_mount) {
- iput(dir_i);
- return -EPERM;
- }
- if (!(sb->s_mounted = iget(dev,MINIX_ROOT_INO))) {
+ if (sb->s_covered) {
iput(dir_i);
- return -EPERM;
+ return -EBUSY;
}
- sb->s_covered=dir_i;
- dir_i->i_mount=1;
- dir_i->i_dirt=1; /* NOTE! we don't iput(dir_i) */
+ sb->s_covered = dir_i;
+ dir_i->i_mount = 1;
+ dir_i->i_dirt = 1; /* NOTE! we don't iput(dir_i) */
return 0; /* we do that in umount */
}
@@ -265,10 +237,13 @@ void mount_root(void)
p->s_lock = 0;
p->s_wait = NULL;
}
- if (!(p=read_super(ROOT_DEV)))
+ if (!(p=read_super(ROOT_DEV,"minix",NULL)))
panic("Unable to mount root");
+ /*wait_for_keypress();
if (!(mi=iget(ROOT_DEV,MINIX_ROOT_INO)))
panic("Unable to read root i-node");
+ wait_for_keypress();*/
+ mi=p->s_mounted;
mi->i_count += 3 ; /* NOTE! it is logically used 4 times, not 1 */
p->s_mounted = p->s_covered = mi;
current->pwd = mi;
diff --git a/include/a.out.h b/include/a.out.h
index 3e67974..5468aa4 100644
--- a/include/a.out.h
+++ b/include/a.out.h
@@ -1,10 +1,13 @@
-#ifndef _A_OUT_H
-#define _A_OUT_H
+#ifndef __A_OUT_GNU_H__
+#define __A_OUT_GNU_H__
#define __GNU_EXEC_MACROS__
-struct exec {
- unsigned long a_magic; /* Use macros N_MAGIC, etc for access */
+#ifndef __STRUCT_EXEC_OVERRIDE__
+
+struct exec
+{
+ unsigned long a_info; /* Use macros N_MAGIC, etc for access */
unsigned a_text; /* length of text, in bytes */
unsigned a_data; /* length of data, in bytes */
unsigned a_bss; /* length of uninitialized data area for file, in bytes */
@@ -14,20 +17,62 @@ struct exec {
unsigned a_drsize; /* length of relocation info for data, in bytes */
};
-#ifndef N_MAGIC
-#define N_MAGIC(exec) ((exec).a_magic)
+#endif /* __STRUCT_EXEC_OVERRIDE__ */
+
+/* these go in the N_MACHTYPE field */
+enum machine_type {
+#if defined (M_OLDSUN2)
+ M__OLDSUN2 = M_OLDSUN2,
+#else
+ M_OLDSUN2 = 0,
+#endif
+#if defined (M_68010)
+ M__68010 = M_68010,
+#else
+ M_68010 = 1,
+#endif
+#if defined (M_68020)
+ M__68020 = M_68020,
+#else
+ M_68020 = 2,
+#endif
+#if defined (M_SPARC)
+ M__SPARC = M_SPARC,
+#else
+ M_SPARC = 3,
+#endif
+ /* skip a bunch so we don't run into any of sun's numbers */
+ M_386 = 100,
+};
+
+#if !defined (N_MAGIC)
+#define N_MAGIC(exec) ((exec).a_info & 0xffff)
#endif
+#define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff))
+#define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff)
+#define N_SET_INFO(exec, magic, type, flags) \
+ ((exec).a_info = ((magic) & 0xffff) \
+ | (((int)(type) & 0xff) << 16) \
+ | (((flags) & 0xff) << 24))
+#define N_SET_MAGIC(exec, magic) \
+ ((exec).a_info = (((exec).a_info & 0xffff0000) | ((magic) & 0xffff)))
+
+#define N_SET_MACHTYPE(exec, machtype) \
+ ((exec).a_info = \
+ ((exec).a_info&0xff00ffff) | ((((int)(machtype))&0xff) << 16))
+
+#define N_SET_FLAGS(exec, flags) \
+ ((exec).a_info = \
+ ((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24))
-#ifndef OMAGIC
/* Code indicating object file or impure executable. */
#define OMAGIC 0407
/* Code indicating pure executable. */
#define NMAGIC 0410
/* Code indicating demand-paged executable. */
#define ZMAGIC 0413
-#endif /* not OMAGIC */
-#ifndef N_BADMAG
+#if !defined (N_BADMAG)
#define N_BADMAG(x) \
(N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC \
&& N_MAGIC(x) != ZMAGIC)
@@ -37,35 +82,35 @@ struct exec {
(N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC \
&& N_MAGIC(x) != ZMAGIC)
-#define _N_HDROFF(x) (SEGMENT_SIZE - sizeof (struct exec))
+#define _N_HDROFF(x) (1024 - sizeof (struct exec))
-#ifndef N_TXTOFF
+#if !defined (N_TXTOFF)
#define N_TXTOFF(x) \
(N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : sizeof (struct exec))
#endif
-#ifndef N_DATOFF
+#if !defined (N_DATOFF)
#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
#endif
-#ifndef N_TRELOFF
+#if !defined (N_TRELOFF)
#define N_TRELOFF(x) (N_DATOFF(x) + (x).a_data)
#endif
-#ifndef N_DRELOFF
+#if !defined (N_DRELOFF)
#define N_DRELOFF(x) (N_TRELOFF(x) + (x).a_trsize)
#endif
-#ifndef N_SYMOFF
+#if !defined (N_SYMOFF)
#define N_SYMOFF(x) (N_DRELOFF(x) + (x).a_drsize)
#endif
-#ifndef N_STROFF
+#if !defined (N_STROFF)
#define N_STROFF(x) (N_SYMOFF(x) + (x).a_syms)
#endif
/* Address of text segment in memory after it is loaded. */
-#ifndef N_TXTADDR
+#if !defined (N_TXTADDR)
#define N_TXTADDR(x) 0
#endif
@@ -73,10 +118,7 @@ struct exec {
Note that it is up to you to define SEGMENT_SIZE
on machines not listed here. */
#if defined(vax) || defined(hp300) || defined(pyr)
-#define SEGMENT_SIZE PAGE_SIZE
-#endif
-#ifdef hp300
-#define PAGE_SIZE 4096
+#define SEGMENT_SIZE page_size
#endif
#ifdef sony
#define SEGMENT_SIZE 0x2000
@@ -89,8 +131,10 @@ struct exec {
#define SEGMENT_SIZE PAGE_SIZE
#endif
-#define PAGE_SIZE 4096
-#define SEGMENT_SIZE 1024
+#ifdef linux
+#define PAGE_SIZE 4096
+#define SEGMENT_SIZE 1024
+#endif
#define _N_SEGMENT_ROUND(x) (((x) + SEGMENT_SIZE - 1) & ~(SEGMENT_SIZE - 1))
@@ -103,11 +147,11 @@ struct exec {
#endif
/* Address of bss segment in memory after it is loaded. */
-#ifndef N_BSSADDR
+#if !defined (N_BSSADDR)
#define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data)
#endif
-
-#ifndef N_NLIST_DECLARED
+
+#if !defined (N_NLIST_DECLARED)
struct nlist {
union {
char *n_name;
@@ -119,37 +163,34 @@ struct nlist {
short n_desc;
unsigned long n_value;
};
-#endif
+#endif /* no N_NLIST_DECLARED. */
-#ifndef N_UNDF
+#if !defined (N_UNDF)
#define N_UNDF 0
#endif
-#ifndef N_ABS
+#if !defined (N_ABS)
#define N_ABS 2
#endif
-#ifndef N_TEXT
+#if !defined (N_TEXT)
#define N_TEXT 4
#endif
-#ifndef N_DATA
+#if !defined (N_DATA)
#define N_DATA 6
#endif
-#ifndef N_BSS
+#if !defined (N_BSS)
#define N_BSS 8
#endif
-#ifndef N_COMM
-#define N_COMM 18
-#endif
-#ifndef N_FN
+#if !defined (N_FN)
#define N_FN 15
#endif
-#ifndef N_EXT
+#if !defined (N_EXT)
#define N_EXT 1
#endif
-#ifndef N_TYPE
+#if !defined (N_TYPE)
#define N_TYPE 036
#endif
-#ifndef N_STAB
+#if !defined (N_STAB)
#define N_STAB 0340
#endif
@@ -182,9 +223,8 @@ struct nlist {
/* This is output from LD. */
#define N_SETV 0x1C /* Pointer to set vector in data area. */
-
-#ifndef N_RELOCATION_INFO_DECLARED
-
+
+#if !defined (N_RELOCATION_INFO_DECLARED)
/* This structure describes a single relocation to be performed.
The text-relocation section of the file is a vector of these structures,
all of which apply to the text section.
@@ -212,7 +252,13 @@ struct relocation_info
unsigned int r_extern:1;
/* Four bits that aren't used, but when writing an object file
it is desirable to clear them. */
+#ifdef NS32K
+ unsigned r_bsr:1;
+ unsigned r_disp:1;
+ unsigned r_pad:2;
+#else
unsigned int r_pad:4;
+#endif
};
#endif /* no N_RELOCATION_INFO_DECLARED. */
diff --git a/include/asm/io.h b/include/asm/io.h
index 9886d7b..226f343 100644
--- a/include/asm/io.h
+++ b/include/asm/io.h
@@ -1,10 +1,13 @@
-static void inline outb(char value, unsigned short port)
+#ifndef _ASM_IO_H
+#define _ASM_IO_H
+
+extern void inline outb(char value, unsigned short port)
{
__asm__ volatile ("outb %0,%1"
::"a" ((char) value),"d" ((unsigned short) port));
}
-static void inline outb_p(char value, unsigned short port)
+extern void inline outb_p(char value, unsigned short port)
{
__asm__ volatile ("outb %0,%1\n"
"\tjmp 1f\n"
@@ -15,7 +18,7 @@ __asm__ volatile ("outb %0,%1\n"
::"a" ((char) value),"d" ((unsigned short) port));
}
-static unsigned char inline inb(unsigned short port)
+extern unsigned char inline inb(unsigned short port)
{
unsigned char _v;
__asm__ volatile ("inb %1,%0"
@@ -23,7 +26,7 @@ __asm__ volatile ("inb %1,%0"
return _v;
}
-static unsigned char inb_p(unsigned short port)
+extern unsigned char inline inb_p(unsigned short port)
{
unsigned char _v;
__asm__ volatile ("inb %1,%0\n"
@@ -35,3 +38,5 @@ __asm__ volatile ("inb %1,%0\n"
:"=a" (_v):"d" ((unsigned short) port));
return _v;
}
+
+#endif
diff --git a/include/limits.h b/include/limits.h
new file mode 100644
index 0000000..1303adf
--- /dev/null
+++ b/include/limits.h
@@ -0,0 +1,62 @@
+#ifndef _LIMITS_H
+#define _LIMITS_H
+
+#define RAND_MAX 0x7ffffffd /* don't ask - see rand.c */
+
+#define CHAR_BIT 8
+#define MB_LEN_MAX 1
+
+#define SCHAR_MIN (-128)
+#define SCHAR_MAX 127
+
+#define UCHAR_MAX 255U
+
+#ifdef __CHAR_UNSIGNED__
+#define CHAR_MIN 0
+#define CHAR_MAX UCHAR_MAX
+#else
+#define CHAR_MIN SCHAR_MIN
+#define CHAR_MAX SCHAR_MAX
+#endif
+
+#define SHRT_MIN (-32768)
+#define SHRT_MAX 32767
+
+#define USHRT_MAX 65535U
+
+#define INT_MIN (-2147483648)
+#define INT_MAX 2147483647
+
+#define UINT_MAX 4294967295U
+
+#define LONG_MIN (-2147483648)
+#define LONG_MAX 2147483647
+
+#define ULONG_MAX 4294967295U
+
+/*
+ * Why are these different from the section below? -- TYT
+ */
+#define _POSIX_ARG_MAX 40960 /* exec() may have 40K worth of args */
+#define _POSIX_CHILD_MAX 6 /* a process may have 6 children */
+#define _POSIX_LINK_MAX 8 /* a file may have 8 links */
+#define _POSIX_MAX_CANON 255 /* size of the canonical input queue */
+#define _POSIX_MAX_INPUT 255 /* you can type 255 chars ahead */
+#define _POSIX_NAME_MAX 14 /* a file name may have 14 chars */
+#define _POSIX_NGROUPS_MAX 32 /* supplementary group IDs are optional */
+#define _POSIX_OPEN_MAX 16 /* a process may have 16 files open */
+#define _POSIX_PATH_MAX 255 /* a pathname may contain 255 chars */
+#define _POSIX_PIPE_BUF 512 /* pipes writes of 512 bytes must be atomic */
+
+#define NGROUPS_MAX 32 /* supplemental group IDs are available */
+#define ARG_MAX 40960 /* # bytes of args + environ for exec() */
+#define CHILD_MAX 999 /* no limit :-) */
+#define OPEN_MAX 20 /* # open files a process may have */
+#define LINK_MAX 127 /* # links a file may have */
+#define MAX_CANON 255 /* size of the canonical input queue */
+#define MAX_INPUT 255 /* size of the type-ahead buffer */
+#define NAME_MAX 255 /* # chars in a file name */
+#define PATH_MAX 1024 /* # chars in a path name */
+#define PIPE_BUF 4095 /* # bytes in atomic write to a pipe */
+
+#endif
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 8851646..d75dd80 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -7,6 +7,7 @@
#define _FS_H
#include <sys/types.h>
+#include <sys/dirent.h>
/* devices are as follows: (same as minix, so we can use the minix
* file system. These are major numbers.)
@@ -134,12 +135,15 @@ struct super_block {
unsigned char s_lock;
unsigned char s_rd_only;
unsigned char s_dirt;
+ /* TUBE */
+ struct super_operations *s_op;
};
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 *);
};
struct inode_operations {
@@ -156,8 +160,25 @@ struct inode_operations {
int (*open) (struct inode *, struct file *);
void (*release) (struct inode *, struct file *);
struct inode * (*follow_link) (struct inode *, struct inode *);
+ int (*bmap) (struct inode *,int);
+ void (*truncate) (struct inode *);
+ /* added by entropy */
+ void (*write_inode)(struct inode *inode);
+ void (*put_inode)(struct inode *inode);
};
+struct super_operations {
+ void (*read_inode)(struct inode *inode);
+ void (*put_super)(struct super_block *sb);
+};
+
+struct file_system_type {
+ struct super_block *(*read_super)(struct super_block *sb,void *mode);
+ char *name;
+};
+
+extern struct file_system_type *get_fs_type(char *name);
+
extern struct inode inode_table[NR_INODE];
extern struct file file_table[NR_FILE];
extern struct super_block super_block[NR_SUPER];
@@ -175,6 +196,9 @@ extern void wait_on(struct inode * inode);
extern int bmap(struct inode * inode,int block);
extern struct inode * namei(const char * pathname);
extern struct inode * lnamei(const char * pathname);
+extern int permission(struct inode * inode,int mask);
+extern struct inode * _namei(const char * filename, struct inode * base,
+ int follow_links);
extern int open_namei(const char * pathname, int flag, int mode,
struct inode ** res_inode);
extern void iput(struct inode * inode);
@@ -195,13 +219,13 @@ extern struct super_block * get_super(int dev);
extern int ROOT_DEV;
extern void mount_root(void);
+extern void lock_super(struct super_block * sb);
+extern void free_super(struct super_block * sb);
-extern int minix_file_read(struct inode *, struct file *, char *, int);
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 minix_file_write(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/hdreg.h b/include/linux/hdreg.h
index 883c7ae..e7e1347 100644
--- a/include/linux/hdreg.h
+++ b/include/linux/hdreg.h
@@ -64,4 +64,10 @@ struct partition {
unsigned int nr_sects; /* nr of sectors in partition */
};
+#define HDIO_REQ 0x301
+struct hd_geometry {
+ unsigned char heads;
+ unsigned char sectors;
+ unsigned short cylinders;
+};
#endif
diff --git a/include/linux/minix_fs.h b/include/linux/minix_fs.h
index 4ccb845..189f438 100644
--- a/include/linux/minix_fs.h
+++ b/include/linux/minix_fs.h
@@ -68,9 +68,18 @@ 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 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 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_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;
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 99f919b..e1fac82 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -129,9 +129,13 @@ struct task_struct {
unsigned short gid,egid,sgid;
unsigned long timeout,alarm;
long utime,stime,cutime,cstime,start_time;
+ unsigned long min_flt, maj_flt;
+ unsigned long cmin_flt, cmaj_flt;
struct rlimit rlim[RLIM_NLIMITS];
unsigned int flags; /* per process flags, defined below */
unsigned short used_math;
+ unsigned short rss; /* number of resident pages */
+ char comm[8];
/* file system info */
int link_count;
int tty; /* -1 if no tty, so it must be signed */
@@ -171,11 +175,14 @@ struct task_struct {
/* proc links*/ &init_task.task,NULL,NULL,NULL,NULL, \
/* uid etc */ 0,0,0,0,0,0, \
/* timeout */ 0,0,0,0,0,0,0, \
+/* min_flt */ 0,0,0,0, \
/* rlimits */ { {0x7fffffff, 0x7fffffff}, {0x7fffffff, 0x7fffffff}, \
{0x7fffffff, 0x7fffffff}, {0x7fffffff, 0x7fffffff}, \
{0x7fffffff, 0x7fffffff}, {0x7fffffff, 0x7fffffff}}, \
/* flags */ 0, \
/* math */ 0, \
+/* rss */ 2, \
+/* comm */ "swapper", \
/* fs info */ 0,-1,0022,NULL,NULL,NULL,NULL,0, \
/* filp */ {NULL,}, \
{ \
diff --git a/include/linux/sys.h b/include/linux/sys.h
index 1e6f2c3..e721865 100644
--- a/include/linux/sys.h
+++ b/include/linux/sys.h
@@ -91,6 +91,7 @@ extern int sys_readlink();
extern int sys_uselib();
extern int sys_swapon();
extern int sys_reboot();
+extern int sys_readdir();
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,
@@ -107,7 +108,7 @@ 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_lstat, sys_readlink, sys_uselib, sys_swapon, sys_reboot, sys_readdir };
/* 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 805894d..d185dd6 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -68,16 +68,38 @@ struct tty_struct {
struct tty_queue *secondary;
};
-#define TTY_WRITE(tty) \
+/*
+ * so that interrupts won't be able to mess up the
+ * queues, copy_to_cooked must be atomic with repect
+ * to itself, as must tty->write.
+ */
+#define TTY_WRITE_BUSY 1
+#define TTY_READ_BUSY 2
+
+#define TTY_WRITE_FLUSH(tty) \
do { \
cli(); \
- if (!(tty)->busy) { \
- (tty)->busy = 1; \
+ if (!EMPTY((tty)->write_q) && !(TTY_WRITE_BUSY & (tty)->busy)) { \
+ (tty)->busy |= TTY_WRITE_BUSY; \
sti(); \
(tty)->write((tty)); \
- (tty)->busy = 0; \
- } else \
+ cli(); \
+ (tty)->busy &= ~TTY_WRITE_BUSY; \
+ } \
+ sti(); \
+} while (0)
+
+#define TTY_READ_FLUSH(tty) \
+do { \
+ cli(); \
+ if (!EMPTY((tty)->read_q) && !(TTY_READ_BUSY & (tty)->busy)) { \
+ (tty)->busy |= TTY_READ_BUSY; \
sti(); \
+ copy_to_cooked((tty)); \
+ cli(); \
+ (tty)->busy &= ~TTY_READ_BUSY; \
+ } \
+ sti(); \
} while (0)
extern struct tty_struct tty_table[];
diff --git a/include/sys/dirent.h b/include/sys/dirent.h
new file mode 100644
index 0000000..d0873a9
--- /dev/null
+++ b/include/sys/dirent.h
@@ -0,0 +1,13 @@
+#ifndef _SYS_DIRENT_H
+#define _SYS_DIRENT_H
+
+#include <limits.h>
+
+struct dirent {
+ long d_ino;
+ off_t d_off;
+ unsigned short d_reclen;
+ char d_name[NAME_MAX+1];
+};
+
+#endif
diff --git a/include/unistd.h b/include/unistd.h
index 622aa6f..f297df9 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -50,6 +50,12 @@
#define _PC_VDISABLE 8
#define _PC_CHOWN_RESTRICTED 9
+#if 0
+/* XXX - <sys/stat.h> illegally <sys/types.h> already.
+ * The rest of these includes are also illegal (too much pollution).
+ */
+#include <sys/types.h>
+#endif
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/times.h>
@@ -148,7 +154,9 @@
#define __NR_uselib 86
#define __NR_swapon 87
#define __NR_reboot 88
+#define __NR_readdir 89
+/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
#define _syscall0(type,name) \
type name(void) \
{ \
@@ -206,19 +214,26 @@ return -1; \
#endif /* __LIBRARY__ */
+/* XXX - illegal. */
extern int errno;
-int access(const char * filename, mode_t mode);
+/* XXX - several non-POSIX functions here, and POSIX functions that are
+ * supposed to be declared elsewhere. Non-promotion of short types in
+ * prototypes may cause trouble. Arg names should be prefixed by
+ * underscores.
+ */
+int access(const char * filename, mode_t mode); /* XXX - short type */
int acct(const char * filename);
-int alarm(int sec);
int brk(void * end_data_segment);
+/* XXX - POSIX says unsigned alarm(unsigned sec) */
+int alarm(int sec);
void * sbrk(ptrdiff_t increment);
int chdir(const char * filename);
-int chmod(const char * filename, mode_t mode);
-int chown(const char * filename, uid_t owner, gid_t group);
+int chmod(const char * filename, mode_t mode); /* XXX - short type */
+int chown(const char * filename, uid_t owner, gid_t group); /* XXX - shorts */
int chroot(const char * filename);
int close(int fildes);
-int creat(const char * filename, mode_t mode);
+int creat(const char * filename, mode_t mode); /* XXX - short type */
int dup(int fildes);
int execve(const char * filename, char ** argv, char ** envp);
int execv(const char * pathname, char ** argv);
@@ -229,27 +244,28 @@ int execle(const char * pathname, char * arg0, ...);
volatile void exit(int status);
volatile void _exit(int status);
int fcntl(int fildes, int cmd, ...);
-int fork(void);
-int getpid(void);
-int getuid(void);
-int geteuid(void);
-int getgid(void);
-int getegid(void);
+pid_t fork(void);
+pid_t getpid(void);
+uid_t getuid(void);
+uid_t geteuid(void);
+gid_t getgid(void);
+gid_t getegid(void);
int ioctl(int fildes, int cmd, ...);
int kill(pid_t pid, int signal);
int link(const char * filename1, const char * filename2);
-int lseek(int fildes, off_t offset, int origin);
-int mknod(const char * filename, mode_t mode, dev_t dev);
+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 nice(int val);
int open(const char * filename, int flag, ...);
int pause(void);
int pipe(int * fildes);
+/* XXX**2 - POSIX says unsigned count */
int read(int fildes, char * buf, off_t count);
int setpgrp(void);
-int setpgid(pid_t pid,pid_t pgid);
-int setuid(uid_t uid);
-int setgid(gid_t gid);
+int setpgid(pid_t pid,pid_t pgid); /* XXX - short types */
+int setuid(uid_t uid); /* XXX - short type */
+int setgid(gid_t gid); /* XXX - short type */
void (*signal(int sig, void (*fn)(int)))(int);
int stat(const char * filename, struct stat * stat_buf);
int fstat(int fildes, struct stat * stat_buf);
@@ -266,6 +282,7 @@ int ustat(dev_t dev, struct ustat * ubuf);
int utime(const char * filename, struct utimbuf * times);
pid_t waitpid(pid_t pid,int * wait_stat,int options);
pid_t wait(int * wait_stat);
+/* XXX**2 - POSIX says unsigned count */
int write(int fildes, const char * buf, off_t count);
int dup2(int oldfd, int newfd);
int getppid(void);
diff --git a/kernel/Makefile b/kernel/Makefile
index 5a5444f..a822e41 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -5,18 +5,15 @@
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
-
-# gcc2 doesn't have these:
-#GCC_OPT = -fcombine-regs
+# Note 2! The CFLAGS definitions are now in the main makefile...
AR =ar
AS =as
LD =ld
LDFLAGS =-s -x
-CC =gcc
-CFLAGS =-Wall -O -fstrength-reduce -fomit-frame-pointer $(GCC_OPT) \
- -finline-functions -nostdinc -I../include
-CPP =gcc -E -nostdinc -I../include
+CC =gcc -nostdinc -I../include
+CPP =cpp -nostdinc -I../include
+
.c.s:
$(CC) $(CFLAGS) \
@@ -35,6 +32,9 @@ kernel.o: $(OBJS)
$(LD) -r -o kernel.o $(OBJS)
sync
+sched.o: sched.c
+ $(CC) $(CFLAGS) -fno-omit-frame-pointer -c $<
+
clean:
rm -f core *.o *.a tmp_make keyboard.s
for i in *.c;do rm -f `basename $$i .c`.s;done
@@ -53,51 +53,57 @@ 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/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
+ ../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/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/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
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/linux/mm.h ../include/signal.h ../include/sys/param.h \
- ../include/sys/time.h ../include/time.h ../include/sys/resource.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/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
+ ../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/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
+ ../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/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
+ ../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/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
+ ../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/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
+ ../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/string.h
diff --git a/kernel/blk_drv/Makefile b/kernel/blk_drv/Makefile
index ee05aaa..516ab48 100644
--- a/kernel/blk_drv/Makefile
+++ b/kernel/blk_drv/Makefile
@@ -5,15 +5,16 @@
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
+# Note 2! The CFLAGS definition is now inherited from the
+# parent makefile.
+#
AR =ar
AS =as
LD =ld
LDFLAGS =-s -x
-CC =gcc
-CFLAGS =-Wall -O -fstrength-reduce -fomit-frame-pointer \
- -finline-functions -nostdinc -I../../include
-CPP =gcc -E -nostdinc -I../../include
+CC =gcc -nostdinc -I../../include
+CPP =cpp -nostdinc -I../../include
.c.s:
$(CC) $(CFLAGS) \
@@ -42,15 +43,17 @@ dep:
### Dependencies:
floppy.s floppy.o : floppy.c ../../include/linux/sched.h ../../include/linux/head.h \
- ../../include/linux/fs.h ../../include/sys/types.h ../../include/linux/mm.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/linux/config.h ../../include/linux/sched.h \
- ../../include/linux/head.h ../../include/linux/fs.h \
- ../../include/sys/types.h ../../include/linux/mm.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 \
@@ -58,13 +61,15 @@ hd.s hd.o : hd.c ../../include/linux/config.h ../../include/linux/sched.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/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
+ ../../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/linux/mm.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 \
diff --git a/kernel/blk_drv/blk.h b/kernel/blk_drv/blk.h
index c159025..746f5f0 100644
--- a/kernel/blk_drv/blk.h
+++ b/kernel/blk_drv/blk.h
@@ -78,10 +78,11 @@ extern int * blk_size[NR_BLK_DEV];
#define DEVICE_OFF(device) floppy_off(DEVICE_NR(device))
#elif (MAJOR_NR == 3)
-/* harddisk */
+/* harddisk: timeout is 6 seconds.. */
#define DEVICE_NAME "harddisk"
#define DEVICE_INTR do_hd
#define DEVICE_TIMEOUT HD_TIMER
+#define TIMEOUT_VALUE 600
#define DEVICE_REQUEST do_hd_request
#define DEVICE_NR(device) (MINOR(device)>>6)
#define DEVICE_ON(device)
@@ -101,10 +102,18 @@ void (*DEVICE_INTR)(void) = NULL;
#endif
#ifdef DEVICE_TIMEOUT
-#define SET_INTR(x) if (DEVICE_INTR = (x)) { \
-timer_table[DEVICE_TIMEOUT].expires = jiffies + 200; \
-timer_active |= 1<<DEVICE_TIMEOUT; \
-} else timer_active &= ~(1<<DEVICE_TIMEOUT)
+#define SET_TIMER \
+((timer_table[DEVICE_TIMEOUT].expires = jiffies + TIMEOUT_VALUE), \
+(timer_active |= 1<<DEVICE_TIMEOUT))
+
+#define CLEAR_TIMER \
+timer_active &= ~(1<<DEVICE_TIMEOUT)
+
+#define SET_INTR(x) \
+if (DEVICE_INTR = (x)) \
+ SET_TIMER; \
+else \
+ CLEAR_TIMER;
#else
diff --git a/kernel/blk_drv/hd.c b/kernel/blk_drv/hd.c
index e3a6ca5..187a406 100644
--- a/kernel/blk_drv/hd.c
+++ b/kernel/blk_drv/hd.c
@@ -16,6 +16,8 @@
* in the early extended-partition checks and added DM partitions
*/
+#include <errno.h>
+
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/timer.h>
@@ -43,7 +45,7 @@ static void recal_intr(void);
static void bad_rw_intr(void);
static int recalibrate = 0;
-static int reset = 1;
+static int reset = 0;
/*
* This struct defines the HD's and their types.
@@ -77,28 +79,103 @@ extern void rd_load(void);
static unsigned int current_minor;
+/*
+ * Create devices for each logical partition in an extended partition.
+ * The logical partitions form a linked list, with each entry being
+ * a partition table with two entries. The first entry
+ * is the real data partition (with a start relative to the partition
+ * table start). The second is a pointer to the next logical partition
+ * (with a start relative to the entire extended partition).
+ * We do not create a Linux partition for the partition tables, but
+ * only for the actual data partitions.
+ */
+static void extended_partition(unsigned int dev)
+{
+ struct buffer_head *bh;
+ struct partition *p;
+ unsigned long first_sector, this_sector;
+
+ first_sector = hd[MINOR(dev)].start_sect;
+ this_sector = first_sector;
+
+ while (1) {
+ if ((current_minor & 0x3f) >= 60)
+ return;
+ if (!(bh = bread(dev,0))) {
+ printk("Unable to read partition table of device %04x\n",dev);
+ return;
+ }
+ /*
+ * This block is from a device that we're about to stomp on.
+ * So make sure nobody thinks this block is usable.
+ */
+ bh->b_dirt=0;
+ bh->b_uptodate=0;
+ if (*(unsigned short *) (bh->b_data+510) == 0xAA55) {
+ p = 0x1BE + (void *)bh->b_data;
+ /*
+ * Process the first entry, which should be the real
+ * data partition.
+ */
+ if (p->sys_ind == EXTENDED_PARTITION ||
+ !(hd[current_minor].nr_sects = p->nr_sects))
+ goto done; /* shouldn't happen */
+ hd[current_minor].start_sect = this_sector + p->start_sect;
+ printk(" Logical part %d start %d size %d end %d\n\r",
+ current_minor, hd[current_minor].start_sect,
+ hd[current_minor].nr_sects,
+ hd[current_minor].start_sect +
+ hd[current_minor].nr_sects);
+ current_minor++;
+ p++;
+ /*
+ * Process the second entry, which should be a link
+ * to the next logical partition. Create a minor
+ * for this just long enough to get the next partition
+ * table. The minor will be reused for the real
+ * data partition.
+ */
+ if (p->sys_ind != EXTENDED_PARTITION ||
+ !(hd[current_minor].nr_sects = p->nr_sects))
+ goto done; /* no more logicals in this partition */
+ hd[current_minor].start_sect = first_sector + p->start_sect;
+ this_sector = first_sector + p->start_sect;
+ dev = 0x0300 | current_minor;
+ brelse(bh);
+ } else
+ goto done;
+ }
+done:
+ brelse(bh);
+}
+
static void check_partition(unsigned int dev)
{
- int minor, i;
+ int i, minor = current_minor;
struct buffer_head *bh;
struct partition *p;
+ unsigned long first_sector;
+ first_sector = hd[MINOR(dev)].start_sect;
if (!(bh = bread(dev,0))) {
printk("Unable to read partition table of device %04x\n",dev);
return;
}
- minor = current_minor;
+ printk("Drive %d:\n\r",minor >> 6);
+ current_minor += 4; /* first "extra" minor */
if (*(unsigned short *) (bh->b_data+510) == 0xAA55) {
p = 0x1BE + (void *)bh->b_data;
- for (i=0 ; i<4 ; i++,p++) {
- if (!(hd[i+minor].nr_sects = p->nr_sects))
+ for (i=1 ; i<=4 ; minor++,i++,p++) {
+ if (!(hd[minor].nr_sects = p->nr_sects))
continue;
- hd[i+minor].start_sect = p->start_sect;
+ 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);
if ((current_minor & 0x3f) >= 60)
continue;
if (p->sys_ind == EXTENDED_PARTITION) {
- current_minor += 4;
- check_partition(0x0300 | (i+minor));
+ extended_partition(0x0300 | minor);
}
}
/*
@@ -106,14 +183,20 @@ static void check_partition(unsigned int dev)
*/
if (*(unsigned short *) (bh->b_data+0xfc) == 0x55AA) {
p = 0x1BE + (void *)bh->b_data;
- for (i=4; i<16; i++) {
+ for (i = 4 ; i < 16 ; i++, current_minor++) {
p--;
if ((current_minor & 0x3f) >= 60)
break;
- if (!(hd[current_minor+4].start_sect = p->start_sect))
+ if (!(p->start_sect && p->nr_sects))
continue;
- hd[current_minor+4].nr_sects = p->nr_sects;
- current_minor++;
+ hd[current_minor].start_sect = p->start_sect;
+ hd[current_minor].nr_sects = p->nr_sects;
+ printk(" DM part %d start %d size %d end %d\n\r",
+ current_minor,
+ hd[current_minor].start_sect,
+ hd[current_minor].nr_sects,
+ hd[current_minor].start_sect +
+ hd[current_minor].nr_sects);
}
}
} else
@@ -141,16 +224,6 @@ int sys_setup(void * BIOS)
hd_info[drive].sect = *(unsigned char *) (14+BIOS);
BIOS += 16;
}
- if (hd_info[1].cyl)
- NR_HD=2;
- else
- NR_HD=1;
-#endif
- for (i=0 ; i<NR_HD ; i++) {
- hd[i<<6].start_sect = 0;
- hd[i<<6].nr_sects = hd_info[i].head*
- hd_info[i].sect*hd_info[i].cyl;
- }
/*
We querry CMOS about hard disks : it could be that
@@ -181,10 +254,14 @@ int sys_setup(void * BIOS)
NR_HD = 1;
else
NR_HD = 0;
- for (i = NR_HD ; i < 2 ; i++) {
- hd[i<<6].start_sect = 0;
- hd[i<<6].nr_sects = 0;
+#endif
+ for (i = 0 ; i < (MAX_HD<<6) ; i++) {
+ hd[i].start_sect = 0;
+ hd[i].nr_sects = 0;
}
+ for (i = 0 ; i < NR_HD ; i++)
+ hd[i<<6].nr_sects = hd_info[i].head*
+ hd_info[i].sect*hd_info[i].cyl;
for (drive=0 ; drive<NR_HD ; drive++) {
current_minor = 1+(drive<<6);
check_partition(0x0300+(drive<<6));
@@ -299,15 +376,25 @@ repeat:
do_hd_request();
}
+/*
+ * Ok, don't know what to do with the unexpected interrupts: on some machines
+ * doing a reset and a retry seems to result in an eternal loop. Right now I
+ * ignore it, and just set the timeout.
+ */
void unexpected_hd_interrupt(void)
{
printk("Unexpected HD interrupt\n\r");
+ SET_TIMER;
+#if 0
reset = 1;
do_hd_request();
+#endif
}
static void bad_rw_intr(void)
{
+ if (!CURRENT)
+ return;
if (++CURRENT->errors >= MAX_ERRORS)
end_request(0);
if (CURRENT->errors > MAX_ERRORS/2)
@@ -361,19 +448,24 @@ static void recal_intr(void)
do_hd_request();
}
+/*
+ * This is another of the error-routines I don't know what to do with. The
+ * best idea seems to just set reset, and start all over again.
+ */
static void hd_times_out(void)
{
do_hd = NULL;
reset = 1;
if (!CURRENT)
return;
- printk("HD timeout");
+ printk("HD timeout\n\r");
+ cli();
if (++CURRENT->errors >= MAX_ERRORS)
end_request(0);
do_hd_request();
}
-void do_hd_request(void)
+static void do_hd_request(void)
{
int i,r;
unsigned int block,dev;
@@ -435,3 +527,27 @@ void hd_init(void)
outb(inb_p(0xA1)&0xbf,0xA1);
timer_table[HD_TIMER].fn = hd_times_out;
}
+
+int hd_ioctl(int dev, int cmd, int arg)
+{
+ struct hd_geometry *loc = (void *) arg;
+
+ if (!loc)
+ return -EINVAL;
+ dev = MINOR(dev) >> 6;
+ if (dev >= NR_HD)
+ return -EINVAL;
+
+ switch (cmd) {
+ case HDIO_REQ:
+ put_fs_byte(hd_info[dev].head,
+ (char *) &loc->heads);
+ put_fs_byte(hd_info[dev].sect,
+ (char *) &loc->sectors);
+ put_fs_word(hd_info[dev].cyl,
+ (short *) &loc->cylinders);
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
diff --git a/kernel/blk_drv/ll_rw_blk.c b/kernel/blk_drv/ll_rw_blk.c
index 777dcc3..7b17306 100644
--- a/kernel/blk_drv/ll_rw_blk.c
+++ b/kernel/blk_drv/ll_rw_blk.c
@@ -83,8 +83,8 @@ static void add_request(struct blk_dev_struct * dev, struct request * req)
req->bh->b_dirt = 0;
if (!(tmp = dev->current_request)) {
dev->current_request = req;
- sti();
(dev->request_fn)();
+ sti();
return;
}
for ( ; tmp->next ; tmp = tmp->next) {
diff --git a/kernel/chr_drv/Makefile b/kernel/chr_drv/Makefile
index 4c28f9c..dc5d532 100644
--- a/kernel/chr_drv/Makefile
+++ b/kernel/chr_drv/Makefile
@@ -5,18 +5,16 @@
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
-
-# gcc2 doesn't understand this option:
-#GCC_OPT = -fcombine-regs
+# Note 2! The CFLAGS definitions are now inherited from the
+# parent makes..
+#
AR =ar
AS =as
LD =ld
LDFLAGS =-s -x
-CC =gcc
-CFLAGS =-Wall -O -fstrength-reduce -fomit-frame-pointer $(GCC_OPT) \
- -finline-functions -nostdinc -I../../include
-CPP =gcc -E -nostdinc -I../../include
+CC =gcc -nostdinc -I../../include
+CPP =cpp -nostdinc -I../../include
.c.s:
$(CC) $(CFLAGS) \
@@ -35,7 +33,7 @@ chr_drv.a: $(OBJS)
sync
keyboard.s: keyboard.S
- $(CPP) -traditional keyboard.S -o keyboard.s
+ $(CPP) $(KEYBOARD) -traditional keyboard.S -o keyboard.s
clean:
rm -f core *.o *.a tmp_make keyboard.s
@@ -50,29 +48,30 @@ dep:
### Dependencies:
console.s console.o : console.c ../../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 \
- ../../include/sys/resource.h ../../include/linux/timer.h \
- ../../include/linux/tty.h ../../include/termios.h \
- ../../include/linux/config.h ../../include/asm/io.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/asm/io.h \
../../include/asm/system.h ../../include/asm/segment.h \
../../include/string.h ../../include/errno.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/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
+ ../../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
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/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/asm/system.h \
- ../../include/asm/io.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/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 \
@@ -80,14 +79,16 @@ tty_io.s tty_io.o : tty_io.c ../../include/ctype.h ../../include/errno.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/linux/mm.h ../../include/linux/kernel.h \
- ../../include/linux/tty.h ../../include/termios.h \
- ../../include/asm/segment.h ../../include/asm/system.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/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/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
diff --git a/kernel/chr_drv/console.c b/kernel/chr_drv/console.c
index f506c4c..6c65e32 100644
--- a/kernel/chr_drv/console.c
+++ b/kernel/chr_drv/console.c
@@ -456,7 +456,7 @@ static void respond(int currcons, struct tty_struct * tty)
p++;
}
sti();
- copy_to_cooked(tty);
+ TTY_READ_FLUSH(tty);
}
static void insert_char(int currcons)
@@ -823,7 +823,7 @@ void con_write(struct tty_struct * tty)
void do_keyboard_interrupt(void)
{
- copy_to_cooked(TTY_TABLE(0));
+ TTY_READ_FLUSH(TTY_TABLE(0));
timer_active &= ~(1<<BLANK_TIMER);
if (console_blanked) {
timer_table[BLANK_TIMER].expires = 0;
diff --git a/kernel/chr_drv/keyboard.S b/kernel/chr_drv/keyboard.S
index 6a26867..fa5e2b5 100644
--- a/kernel/chr_drv/keyboard.S
+++ b/kernel/chr_drv/keyboard.S
@@ -19,7 +19,6 @@
* KBD_UK for British extended keyboard
* KBD_DK for Danish keyboard
*/
-#define KBD_FINNISH
.text
.globl _hard_reset_now
diff --git a/kernel/chr_drv/pty.c b/kernel/chr_drv/pty.c
index 43407dc..aed5b6e 100644
--- a/kernel/chr_drv/pty.c
+++ b/kernel/chr_drv/pty.c
@@ -25,7 +25,7 @@ static inline void pty_copy(struct tty_struct * from, struct tty_struct * to)
if (FULL(to->read_q)) {
if (FULL(to->secondary))
break;
- copy_to_cooked(to);
+ TTY_READ_FLUSH(to);
continue;
}
GETCH(from->write_q,c);
@@ -33,7 +33,7 @@ static inline void pty_copy(struct tty_struct * from, struct tty_struct * to)
if (current->signal & ~current->blocked)
break;
}
- copy_to_cooked(to);
+ TTY_READ_FLUSH(to);
wake_up(&from->write_q->proc_list);
}
diff --git a/kernel/chr_drv/serial.c b/kernel/chr_drv/serial.c
index 741cc43..bd55ec1 100644
--- a/kernel/chr_drv/serial.c
+++ b/kernel/chr_drv/serial.c
@@ -26,22 +26,22 @@ extern void rs2_interrupt(void);
static void com1_timer(void)
{
- copy_to_cooked(tty_table+64);
+ TTY_READ_FLUSH(tty_table+64);
}
static void com2_timer(void)
{
- copy_to_cooked(tty_table+65);
+ TTY_READ_FLUSH(tty_table+65);
}
static void com3_timer(void)
{
- copy_to_cooked(tty_table+66);
+ TTY_READ_FLUSH(tty_table+66);
}
static void com4_timer(void)
{
- copy_to_cooked(tty_table+67);
+ TTY_READ_FLUSH(tty_table+67);
}
static inline void do_rs_write(unsigned int port)
diff --git a/kernel/chr_drv/tty_io.c b/kernel/chr_drv/tty_io.c
index 12c6479..95d7933 100644
--- a/kernel/chr_drv/tty_io.c
+++ b/kernel/chr_drv/tty_io.c
@@ -129,13 +129,6 @@ void copy_to_cooked(struct tty_struct * tty)
printk("copy_to_cooked: missing queues\n\r");
return;
}
- cli();
- if (tty->busy) {
- sti();
- return;
- }
- tty->busy = 1;
- sti();
while (1) {
if (EMPTY(tty->read_q))
break;
@@ -167,6 +160,7 @@ void copy_to_cooked(struct tty_struct * tty)
if (c<32)
PUTCH(127,tty->write_q);
PUTCH(127,tty->write_q);
+ TTY_WRITE_FLUSH(tty);
}
DEC(tty->secondary->head);
}
@@ -183,6 +177,7 @@ void copy_to_cooked(struct tty_struct * tty)
if (c<32)
PUTCH(127,tty->write_q);
PUTCH(127,tty->write_q);
+ TTY_WRITE_FLUSH(tty);
}
DEC(tty->secondary->head);
continue;
@@ -197,6 +192,7 @@ void copy_to_cooked(struct tty_struct * tty)
if ((START_CHAR(tty) != _POSIX_VDISABLE) &&
(c==START_CHAR(tty))) {
tty->stopped=0;
+ TTY_WRITE_FLUSH(tty);
continue;
}
}
@@ -232,11 +228,13 @@ void copy_to_cooked(struct tty_struct * tty)
PUTCH(c,tty->write_q);
}
PUTCH(c,tty->secondary);
+ TTY_WRITE_FLUSH(tty);
}
- tty->write(tty);
- tty->busy = 0;
+ TTY_WRITE_FLUSH(tty);
if (!EMPTY(tty->secondary))
wake_up(&tty->secondary->proc_list);
+ if (LEFT(tty->write_q) > TTY_BUF_SIZE/2)
+ wake_up(&tty->write_q->proc_list);
}
/*
@@ -305,10 +303,10 @@ int tty_read(unsigned channel, char * buf, int nr, unsigned short flags)
time = current->timeout = 0;
if (minimum>nr)
minimum = nr;
- copy_to_cooked(tty);
+ TTY_READ_FLUSH(tty);
while (nr>0) {
if (other_tty && other_tty->write)
- TTY_WRITE(other_tty);
+ TTY_WRITE_FLUSH(other_tty);
cli();
if (EMPTY(tty->secondary) || (L_CANON(tty) &&
!FULL(tty->read_q) && !tty->secondary->data)) {
@@ -320,7 +318,7 @@ int tty_read(unsigned channel, char * buf, int nr, unsigned short flags)
break;
interruptible_sleep_on(&tty->secondary->proc_list);
sti();
- copy_to_cooked(tty);
+ TTY_READ_FLUSH(tty);
continue;
}
sti();
@@ -398,7 +396,7 @@ int tty_write(unsigned channel, char * buf, int nr)
cr_flag = 0;
PUTCH(c,tty->write_q);
}
- TTY_WRITE(tty);
+ TTY_WRITE_FLUSH(tty);
if (nr>0)
schedule();
}
diff --git a/kernel/chr_drv/tty_ioctl.c b/kernel/chr_drv/tty_ioctl.c
index eabfbed..a8594f0 100644
--- a/kernel/chr_drv/tty_ioctl.c
+++ b/kernel/chr_drv/tty_ioctl.c
@@ -260,11 +260,11 @@ int tty_ioctl(int dev, int cmd, int arg)
switch (arg) {
case TCOOFF:
tty->stopped = 1;
- TTY_WRITE(tty);
+ TTY_WRITE_FLUSH(tty);
return 0;
case TCOON:
tty->stopped = 0;
- TTY_WRITE(tty);
+ TTY_WRITE_FLUSH(tty);
return 0;
case TCIOFF:
if (STOP_CHAR(tty))
diff --git a/kernel/exit.c b/kernel/exit.c
index be284bd..f3fa393 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -48,9 +48,6 @@ inline int send_sig(long sig,struct task_struct * p,int priv)
/* we have to make sure that the process stops. */
if (p->state == TASK_INTERRUPTIBLE || p->state == TASK_RUNNING)
p->state = TASK_STOPPED;
-
- if (p == current)
- schedule();
}
return 0;
}
@@ -218,15 +215,18 @@ int kill_proc(int pid, int sig, int priv)
int sys_kill(int pid,int sig)
{
struct task_struct **p = NR_TASKS + task;
- int err, retval = 0;
+ int err, retval = 0, count = 0;
if (!pid)
- return(kill_pg(current->pid,sig,0));
+ return(kill_pg(current->pgrp,sig,0));
if (pid == -1) {
while (--p > &FIRST_TASK)
- if (err = send_sig(sig,*p,0))
- retval = err;
- return(retval);
+ if ((*p)->pid > 1 && *p != current) {
+ ++count;
+ if ((err = send_sig(sig,*p,0)) != -EPERM)
+ retval = err;
+ }
+ return(count ? retval : -ESRCH);
}
if (pid < 0)
return(kill_pg(-pid,sig,0));
@@ -292,6 +292,7 @@ volatile void do_exit(long code)
current->library = NULL;
current->state = TASK_ZOMBIE;
current->exit_code = code;
+ current->rss = 0;
/*
* Check to see if any process groups have become orphaned
* as a result of our exiting, and if they have any stopped
@@ -413,8 +414,10 @@ repeat:
p->exit_code = 0;
return p->pid;
case TASK_ZOMBIE:
- current->cutime += p->utime;
- current->cstime += p->stime;
+ current->cutime += p->utime + p->cutime;
+ current->cstime += p->stime + p->cstime;
+ current->cmin_flt += p->min_flt + p->cmin_flt;
+ current->cmaj_flt += p->maj_flt + p->cmaj_flt;
flag = p->pid;
if (stat_addr)
put_fs_long(p->exit_code, stat_addr);
diff --git a/kernel/fork.c b/kernel/fork.c
index e3e1e67..ad65fb1 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -112,6 +112,8 @@ int sys_fork(long ebx,long ecx,long edx,
p->leader = 0; /* process leadership doesn't inherit */
p->utime = p->stime = 0;
p->cutime = p->cstime = 0;
+ p->min_flt = p->maj_flt = 0;
+ p->cmin_flt = p->cmaj_flt = 0;
p->start_time = jiffies;
p->tss.back_link = 0;
p->tss.esp0 = PAGE_SIZE + (long) p;
diff --git a/kernel/math/Makefile b/kernel/math/Makefile
index d136ef5..8406a2a 100644
--- a/kernel/math/Makefile
+++ b/kernel/math/Makefile
@@ -10,18 +10,16 @@ AR =ar
AS =as
LD =ld
LDFLAGS =-s -x
-CC =gcc
-CFLAGS =-Wall -O -fstrength-reduce -fomit-frame-pointer \
- -finline-functions -nostdinc -I../../include
-CPP =gcc -E -nostdinc -I../../include
+CC =gcc -nostdinc -I../../include
+CPP =cpp -nostdinc -I../../include
.c.s:
- $(CC) $(CFLAGS) \
+ $(CC) $(CFLAGS) $(MATH_EMULATION) \
-S -o $*.s $<
.s.o:
$(AS) -c -o $*.o $<
.c.o:
- $(CC) $(CFLAGS) \
+ $(CC) $(CFLAGS) $(MATH_EMULATION) \
-c -o $*.o $<
OBJS = math_emulate.o error.o convert.o ea.o get_put.o \
diff --git a/kernel/math/math_emulate.c b/kernel/math/math_emulate.c
index 6fb6e6f..b57d65b 100644
--- a/kernel/math/math_emulate.c
+++ b/kernel/math/math_emulate.c
@@ -30,8 +30,6 @@
* hide most of the 387-specific things here.
*/
-#include <linux/config.h>
-
#ifdef KERNEL_MATH_EMULATION
#include <signal.h>
@@ -172,12 +170,10 @@ static void do_emu(struct info * info)
real_to_real(&tmp,&ST(0));
return;
case 0x1a:
- fcom(PST(code & 7),&tmp);
- real_to_real(&tmp,&ST(0));
+ fcom(PST(code & 7),PST(0));
return;
case 0x1b:
- fcom(PST(code & 7),&tmp);
- real_to_real(&tmp,&ST(0));
+ fcom(PST(code & 7),PST(0));
fpop();
return;
case 0x1c:
@@ -201,7 +197,7 @@ static void do_emu(struct info * info)
return;
case 0x38:
fpush();
- ST(0) = ST((code & 7)+1);
+ ST(0) = ST((code+1) & 7);
return;
case 0x39:
fxchg(&ST(0),&ST(code & 7));
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 6722ef7..051241d 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -1,5 +1,6 @@
/* ptrace.c */
/* By Ross Biro 1/23/92 */
+/* edited by Linus Torvalds */
#include <linux/head.h>
#include <linux/kernel.h>
@@ -22,9 +23,6 @@
/* set's the trap flag. */
#define TRAP_FLAG 0x100
-/* check's for granularity. */
-#define GRANULARITY 0x00800000
-
/*
* this is the number to subtract from the top of the stack. To find
* the local frame.
@@ -51,8 +49,7 @@ static inline int get_task(int pid)
* the offset is how far from the base addr as stored in the TSS.
* this routine assumes that all the priviledged stacks are in our
* data space.
- */
-
+ */
static inline int get_stack_long(struct task_struct *task, int offset)
{
unsigned char *stack;
@@ -69,144 +66,158 @@ static inline int get_stack_long(struct task_struct *task, int offset)
* data space.
*/
static inline int put_stack_long(struct task_struct *task, int offset,
- unsigned short data)
+ unsigned long data)
{
unsigned char * stack;
stack = (unsigned char *) task->tss.esp0;
stack += offset;
- *(int *) stack = data;
+ *(unsigned long *) stack = data;
return 0;
}
/*
- * this routine will get a word out of an arbitrary
- * tasks data space. It likes to have the task number
- * rather than the task pointer. Perhaps the number
- * should be included in the pointer.
+ * This routine gets a long from any process space by following the page
+ * tables. NOTE! You should check that the long isn't on a page boundary,
+ * and that it is in the task area before calling this: this routine does
+ * no checking.
+ *
+ * NOTE2! This uses "tsk->tss.cr3" even though we know it's currently always
+ * zero. This routine shouldn't have to change when we make a better mm.
*/
-/* seg = 0 if I space */
-static inline int get_long(int tsk, long addr, unsigned seg, int *data)
+static unsigned long get_long(struct task_struct * tsk,
+ unsigned long addr)
{
- int i;
- int limit;
- int cur;
- unsigned long address;
unsigned long page;
- unsigned oldfs;
- /* find the task number of the current task. */
- for (i = 0; i < NR_TASKS ; i ++) {
- if (task[i] == current) break;
+ addr += tsk->start_code;
+repeat:
+ page = tsk->tss.cr3 + ((addr >> 20) & 0xffc);
+ page = *(unsigned long *) page;
+ if (page & PAGE_PRESENT) {
+ page &= 0xfffff000;
+ page += (addr >> 10) & 0xffc;
+ page = *((unsigned long *) page);
}
- if (i == NR_TASKS) {
- printk("PTRACE: Can't find current task\n");
- do_exit(SIGSEGV);
- }
- cur = i;
-
- /* we will need to check the readability of the segment
- and then the byte in order to avoid segment violations. */
- seg++;
- limit = (task[tsk]->ldt[seg].a) & 0xffff;
- /* this should be constant amound all of our segments, but we
- had better check anyway. */
- if (task[tsk]->ldt[seg].b & GRANULARITY)
- limit = limit << 12;
-
- if (limit <= addr+4)
- return -EIO;
-
- /* Now compute the address, and make sure that it is present. */
- address = task[tsk]->start_code + addr;
-
- page = *((unsigned long*) ((address >> 20) & 0xffc));
- /* see if it is present. */
if (!(page & PAGE_PRESENT)) {
- do_no_page(0, address, task[tsk]);
+ do_no_page(0,addr,tsk);
+ goto repeat;
}
-
- oldfs = get_fs();
- /* now convert seg to the right format. */
- seg = (seg << 3) | 0x4;
-
- cli(); /* we are about to change our ldt, we better do it
- with interrupts off. Perhaps we should call schedule
- first so that we won't be taking too much extra time. */
- lldt(tsk);
- set_fs(seg);
- *data = get_fs_long((void *)addr); /* we are assuming kernel space
- is in the gdt here. */
- lldt(cur);
- set_fs(oldfs);
- sti();
- return 0;
+ page &= 0xfffff000;
+ page += addr & 0xfff;
+ return *(unsigned long *) page;
}
/*
- * this routine will get a word out of an arbitrary
- * tasks data space. It likes to have the task number
- * rather than the task pointer. Perhaps the number
- * should be included in the pointer.
+ * This routine puts a long into any process space by following the page
+ * tables. NOTE! You should check that the long isn't on a page boundary,
+ * and that it is in the task area before calling this: this routine does
+ * no checking.
*/
-/* seg = 0 if I space */
-static inline int put_long(int tsk, long addr, int data, unsigned seg)
+static void put_long(struct task_struct * tsk, unsigned long addr,
+ unsigned long data)
{
- int i;
- int limit;
- unsigned oldfs;
- unsigned long address;
unsigned long page;
- int cur;
- /* find the task number of the current task. */
- for (i = 0; i < NR_TASKS ; i++) {
- if (task[i] == current) break;
+ addr += tsk->start_code;
+repeat:
+ page = tsk->tss.cr3 + ((addr >> 20) & 0xffc);
+ page = *(unsigned long *) page;
+ if (page & PAGE_PRESENT) {
+ page &= 0xfffff000;
+ page += (addr >> 10) & 0xffc;
+ page = *((unsigned long *) page);
+ }
+ if (!(page & PAGE_PRESENT)) {
+ do_no_page(0,addr,tsk);
+ goto repeat;
}
- if (i == NR_TASKS) {
- printk("PTRACE: Can't find current task\n");
- do_exit(SIGSEGV);
+ if (!(page & PAGE_RW)) {
+ write_verify(addr);
+ goto repeat;
}
- cur = i;
-
- /* we will need to check the readability of the segment
- and then the byte in order to avoid segment violations. */
- seg++;
- limit = (task[tsk]->ldt[seg].a) & 0xffff;
- /* this should be constant amound all of our segments, but we
- had better check anyway. */
- if (task[tsk]->ldt[seg].b & GRANULARITY)
- limit = limit << 12;
-
- if (limit <= addr+4)
- return -EIO;
+ page &= 0xfffff000;
+ page += addr & 0xfff;
+ *(unsigned long *) page = data;
+}
- /* Now compute the address, and make sure that it is present. */
- address = task[tsk]->start_code + addr;
+/*
+ * This routine checks the page boundaries, and that the offset is
+ * within the task area. It then calls get_long() to read a long.
+ */
+static int read_long(struct task_struct * tsk, unsigned long addr,
+ unsigned long * result)
+{
+ unsigned long low,high;
- page = *((unsigned long*) ((address >> 20) & 0xffc));
- /* see if it is present. */
- if (!(page & PAGE_PRESENT)) {
- do_no_page(0, address, task[tsk]);
- }
- write_verify(address);
-
- oldfs=get_fs();
- /* now convert seg to the right format. */
- seg = (seg << 3) | 0x4;
-
- cli(); /* we are about to change our ldt, we better do it
- with interrupts off. Perhaps we should call schedule
- first so that we won't be taking too much extra time. */
- lldt(tsk);
- set_fs(seg);
- put_fs_long(data,(void *)addr);
- lldt(cur);
- set_fs(oldfs);
- sti();
+ if (addr > TASK_SIZE-4)
+ return -EIO;
+ if ((addr & 0xfff) > PAGE_SIZE-4) {
+ low = get_long(tsk,addr & 0xfffffffc);
+ high = get_long(tsk,(addr+4) & 0xfffffffc);
+ switch (addr & 3) {
+ case 1:
+ low >>= 8;
+ low |= high << 24;
+ break;
+ case 2:
+ low >>= 16;
+ low |= high << 16;
+ break;
+ case 3:
+ low >>= 24;
+ low |= high << 8;
+ break;
+ }
+ *result = low;
+ } else
+ *result = get_long(tsk,addr);
return 0;
}
+/*
+ * This routine checks the page boundaries, and that the offset is
+ * within the task area. It then calls put_long() to write a long.
+ */
+static int write_long(struct task_struct * tsk, unsigned long addr,
+ unsigned long data)
+{
+ unsigned long low,high;
+
+ if (addr > TASK_SIZE-4)
+ return -EIO;
+ if ((addr & 0xfff) > PAGE_SIZE-4) {
+ low = get_long(tsk,addr & 0xfffffffc);
+ high = get_long(tsk,(addr+4) & 0xfffffffc);
+ switch (addr & 3) {
+ case 0: /* shouldn't happen, but safety first */
+ low = data;
+ break;
+ case 1:
+ low &= 0x000000ff;
+ low |= data << 8;
+ high &= 0xffffff00;
+ high |= data >> 24;
+ break;
+ case 2:
+ low &= 0x0000ffff;
+ low |= data << 16;
+ high &= 0xffff0000;
+ high |= data >> 16;
+ break;
+ case 3:
+ low &= 0x00ffffff;
+ low |= data << 24;
+ high &= 0xff000000;
+ high |= data >> 8;
+ break;
+ }
+ put_long(tsk,addr & 0xfffffffc,low);
+ put_long(tsk,(addr+4) & 0xfffffffc,high);
+ } else
+ put_long(tsk,addr,data);
+ return 0;
+}
/* Perform ptrace(request, pid, addr, data) syscall */
int sys_ptrace(unsigned long *buffer)
@@ -244,7 +255,7 @@ int sys_ptrace(unsigned long *buffer)
case 2: {
int tmp,res;
- res = get_long(childno, addr, 1, &tmp);
+ res = read_long(task[childno], addr, &tmp);
if (res < 0)
return res;
verify_area((void *) data, 4);
@@ -267,21 +278,18 @@ int sys_ptrace(unsigned long *buffer)
/* when I and D space are seperate, this will have to be fixed. */
case 4: /* write the word at location addr. */
case 5:
- if (put_long(childno, addr, data, 1))
- return -EIO;
- return 0;
+ return write_long(task[childno],addr,data);
case 6: /* write the word at location addr in the USER area */
addr = addr >> 2; /* temproary hack. */
if (addr < 0 || addr >= 17)
- return -EIO;
+ return -EIO;
if (addr == ORIG_EAX)
return -EIO;
if (addr == EFL) { /* flags. */
data &= FLAG_MASK;
data |= get_stack_long(child, EFL*4-MAGICNUMBER) & ~FLAG_MASK;
}
-
if (put_stack_long(child, 4*addr-MAGICNUMBER, data))
return -EIO;
return 0;
diff --git a/kernel/sched.c b/kernel/sched.c
index 2c8a845..989fad9 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -46,12 +46,21 @@ 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++)
+ 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 40b8b40..4dd1059 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -457,11 +457,15 @@ int sys_getrusage(int who, struct rusage *ru)
r.ru_utime.tv_usec = CT_TO_USECS(current->utime);
r.ru_stime.tv_sec = CT_TO_SECS(current->stime);
r.ru_stime.tv_usec = CT_TO_USECS(current->stime);
+ r.ru_minflt = current->min_flt;
+ r.ru_majflt = current->maj_flt;
} else {
r.ru_utime.tv_sec = CT_TO_SECS(current->cutime);
r.ru_utime.tv_usec = CT_TO_USECS(current->cutime);
r.ru_stime.tv_sec = CT_TO_SECS(current->cstime);
r.ru_stime.tv_usec = CT_TO_USECS(current->cstime);
+ r.ru_minflt = current->cmin_flt;
+ r.ru_majflt = current->cmaj_flt;
}
lp = (unsigned long *) &r;
lpend = (unsigned long *) (&r+1);
diff --git a/lib/Makefile b/lib/Makefile
index 9f678c8..83a543f 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -6,17 +6,12 @@
# unless it's something special (ie not a .c file).
#
-# gcc2 doesn't understand some options..
-# GCC_OPT = -fcombine-regs
-
AR =ar
AS =as
LD =ld
LDFLAGS =-s -x
-CC =gcc
-CFLAGS =-Wall -O -fstrength-reduce -fomit-frame-pointer $(GCC_OPT) \
- -finline-functions -nostdinc -I../include
-CPP =gcc -E -nostdinc -I../include
+CC =gcc -nostdinc -I../include
+CPP =cpp -nostdinc -I../include
.c.s:
$(CC) $(CFLAGS) \
diff --git a/mm/Makefile b/mm/Makefile
index cc6e209..27b2f4e 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -1,10 +1,17 @@
-CC =gcc
-CFLAGS =-O -Wall -fstrength-reduce -fomit-frame-pointer \
- -finline-functions -nostdinc -I../include
+#
+# Makefile for the linux memory manager.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
AS =as
AR =ar
LD =ld
-CPP =gcc -E -nostdinc -I../include
+CC =gcc -nostdinc -I../include
+CPP =cpp -nostdinc -I../include
.c.o:
$(CC) $(CFLAGS) \
@@ -32,11 +39,12 @@ dep:
### 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/linux/mm.h ../include/linux/kernel.h \
- ../include/sys/param.h ../include/sys/time.h ../include/time.h \
- ../include/sys/resource.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/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
+ ../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
diff --git a/mm/memory.c b/mm/memory.c
index 574f281..8e93a1b 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -165,6 +165,7 @@ int copy_page_tables(unsigned long from,unsigned long to,long size)
if (!(1 & this_page)) {
if (!(new_page = get_free_page()))
return -1;
+ ++current->rss;
read_swap_page(this_page>>1, (char *) new_page);
*to_page_table = this_page;
*from_page_table = new_page | (PAGE_DIRTY | 7);
@@ -316,6 +317,7 @@ void do_wp_page(unsigned long error_code,unsigned long address)
printk("Bad things happen: page error in do_wp_page\n\r");
do_exit(SIGSEGV);
}
+ ++current->min_flt;
un_wp_page((unsigned long *)
(((address>>10) & 0xffc) + (0xfffff000 &
*((unsigned long *) ((address>>20) &0xffc)))));
@@ -429,8 +431,8 @@ static int share_page(struct inode * inode, unsigned long address)
return 0;
}
-void do_no_page(unsigned long error_code,
- unsigned long address, struct task_struct *tsk)
+void do_no_page(unsigned long error_code, unsigned long address,
+ struct task_struct *tsk)
{
static unsigned int last_checked = 0;
int nr[4];
@@ -439,7 +441,7 @@ void do_no_page(unsigned long error_code,
int block,i;
struct inode * inode;
- /* Trashing ? Make it interruptible, but don't penalize otherwise */
+ /* Thrashing ? Make it interruptible, but don't penalize otherwise */
for (i = 0; i < CHECK_LAST_NR; i++)
if ((address & 0xfffff000) == last_pages[i]) {
current->counter = 0;
@@ -457,6 +459,7 @@ void do_no_page(unsigned long error_code,
printk("Bad things happen: nonexistent page error in do_no_page\n\r");
do_exit(SIGSEGV);
}
+ ++tsk->rss;
page = *(unsigned long *) ((address >> 20) & 0xffc);
/* check the page directory: make a page dir entry if no such exists */
if (page & 1) {
@@ -464,6 +467,7 @@ void do_no_page(unsigned long error_code,
page += (address >> 10) & 0xffc;
tmp = *(unsigned long *) page;
if (tmp && !(1 & tmp)) {
+ ++tsk->maj_flt;
swap_in((unsigned long *) page);
return;
}
@@ -488,12 +492,19 @@ void do_no_page(unsigned long error_code,
block = 0;
}
if (!inode) {
+ ++tsk->min_flt;
+ if (tmp > tsk->brk && tsk == current &&
+ LIBRARY_OFFSET - tmp > tsk->rlim[RLIMIT_STACK].rlim_max)
+ do_exit(SIGSEGV);
get_empty_page(address);
return;
}
if (tsk == current)
- if (share_page(inode,tmp))
- return;
+ if (share_page(inode,tmp)) {
+ ++tsk->min_flt;
+ return;
+ }
+ ++tsk->maj_flt;
if (!(page = get_free_page()))
oom();
/* remember that 1 block is used for header */
@@ -533,9 +544,17 @@ void mem_init(long start_mem, long end_mem)
void show_mem(void)
{
int i,j,k,free=0,total=0;
- int shared=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)
@@ -576,6 +595,7 @@ void show_mem(void)
}
}
printk("Memory found: %d (%d)\n\r",free-shared,total);
+ lock = 0;
}