diff options
author | Linus Benedict Torvalds <torvalds@klaava.Helsinki.FI> | 1992-04-04 14:42:10 +0000 |
---|---|---|
committer | Nicolas Pitre <nico@cam.org> | 2007-08-19 14:19:02 -0400 |
commit | 4fd4c0232da4a9f7e163df707699cd74c1dc6fa8 (patch) | |
tree | 87ac70daf7404f03dcd0957ce9e255f232feb82c | |
parent | edb046236801c4975482840240127aeefdd0f7d7 (diff) | |
download | archive-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
52 files changed, 1381 insertions, 663 deletions
@@ -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) @@ -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 :-) */ @@ -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) { @@ -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; @@ -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); @@ -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 *) ×->actime); modtime = get_fs_long((unsigned long *) ×->modtime); } else @@ -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; } @@ -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; } |