From 6891759b5340b54c3408ca7d80dc722f95d6b9e0 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:09:00 -0500 Subject: [PATCH] [PATCH] Linux-0.95c+ (April 9, 1992 ??) Bruce Evans shows up here quickly. Bruce was the author of the Minix/386 patches, and had been one of my sounding boards for my early development, so it was very gratifying to see him get interested in Linux. As it turned out, what he was _really_ interested in was the serial driver, and the Linux serial driver was already in reasonably good shape. As a result, Bruce went off to work on 386BSD instead (where the serial driver was truly crappy), but here he worked on some boot loader cleanups. Bruce was my hero. Anyway... More VFS work here: readdir, bmap and ioctl's are now virtual operations, and the superblock code is properly virtualized. Other changes: - James Wiegand writes initial parallell port printer driver - major/minor fault tracking - I rewrote big chunks of ptrace.c --- .version | 1 + Makefile | 86 ++++++-- boot/bootsect.S | 129 +++++++----- boot/setup.S | 20 +- fs/Makefile | 139 ++++++------ fs/buffer.c | 8 +- fs/char_dev.c | 94 +++++++-- fs/exec.c | 11 + fs/fasterdisk.pat | 153 -------------- fs/inode.c | 28 ++- fs/ioctl.c | 3 +- fs/minix/Makefile | 53 +++-- fs/minix/file_dev.c | 49 ++++- fs/minix/inode.c | 99 ++++++++- fs/minix/minix_op.c | 17 +- fs/minix/namei.c | 8 +- fs/namei.c | 20 +- fs/open.c | 5 + fs/pipe.c | 2 +- fs/read_write.c | 37 +++- fs/super.c | 123 +++++------ include/a.out.h | 130 ++++++++---- include/asm/io.h | 13 +- include/limits.h | 62 ++++++ include/linux/config.h | 23 +- include/linux/config_rel.h | 1 + include/linux/config_ver.h | 1 + include/linux/fs.h | 28 ++- include/linux/hdreg.h | 6 + include/linux/lp.h | 114 ++++++++++ include/linux/minix_fs.h | 9 + include/linux/sched.h | 7 + include/linux/sys.h | 3 +- include/linux/tty.h | 32 ++- include/sys/dirent.h | 13 ++ include/unistd.h | 49 +++-- kernel/Makefile | 84 ++++---- kernel/blk_drv/Makefile | 31 +-- kernel/blk_drv/blk.h | 19 +- kernel/blk_drv/floppy.c | 2 + kernel/blk_drv/hd.c | 172 ++++++++++++--- kernel/blk_drv/ll_rw_blk.c | 2 +- kernel/chr_drv/Makefile | 74 ++++--- kernel/chr_drv/console.c | 50 +++-- kernel/chr_drv/keyboard.S | 1 - kernel/chr_drv/lp.c | 127 +++++++++++ kernel/chr_drv/pty.c | 4 +- kernel/chr_drv/serial.c | 8 +- kernel/chr_drv/tty_io.c | 36 ++-- kernel/chr_drv/tty_ioctl.c | 4 +- kernel/exit.c | 84 ++++---- kernel/fork.c | 2 + kernel/math/Makefile | 14 +- kernel/math/{math_emulate.c => emulate.c} | 12 +- kernel/ptrace.c | 246 +++++++++++----------- kernel/sched.c | 15 +- kernel/sys.c | 4 + lib/Makefile | 9 +- makever.sh | 13 ++ mm/Makefile | 28 ++- mm/memory.c | 32 ++- mm/swap.c | 7 +- 62 files changed, 1764 insertions(+), 892 deletions(-) create mode 100644 .version delete mode 100644 fs/fasterdisk.pat create mode 100644 include/limits.h create mode 100644 include/linux/config_rel.h create mode 100644 include/linux/config_ver.h create mode 100644 include/linux/lp.h create mode 100644 include/sys/dirent.h create mode 100644 kernel/chr_drv/lp.c rename kernel/math/{math_emulate.c => emulate.c} (98%) create mode 100644 makever.sh diff --git a/.version b/.version new file mode 100644 index 000000000000..3c032078a4a2 --- /dev/null +++ b/.version @@ -0,0 +1 @@ +18 diff --git a/Makefile b/Makefile index e397dab0ffc2..59d5f66b4057 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,44 @@ +# +# comment this line if you don't want the emulation-code +# + +MATH_EMULATION = -DKERNEL_MATH_EMULATION + +# +# uncomment the correct keyboard: +# + +# KEYBOARD = -DKBD_FINNISH +KEYBOARD = -DKBD_US +# KEYBOARD = -DKBD_GR +# KEYBOARD = -DKBD_FR +# KEYBOARD = -DKBD_UK +# KEYBOARD = -DKBD_DK + +# +# uncomment this line if you are using gcc-1.40 +# +#GCC_OPT = -fcombine-regs -fstrength-reduce + +# +# standard CFLAGS +# + +CFLAGS =-Wall -O6 -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 @@ -36,10 +67,19 @@ LIBS =lib/lib.a $(CC) $(CFLAGS) \ -nostdinc -Iinclude -c -o $*.o $< -all: Image +all: Version Image + +Version: + @./makever.sh + @echo \#define UTS_RELEASE \"0.95c-`cat .version`\" > include/linux/config_rel.h + @echo \#define UTS_VERSION \"`date +%D`\" > include/linux/config_ver.h + touch include/linux/config.h 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 +102,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 +167,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 8a8ecb89b09a..837be3219e07 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 7e9d1327dbff..bd23161825c2 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 55bcd62b6dd7..312f2f689fca 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 d4aaa06da5c3..54fa80562f1e 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -27,8 +27,8 @@ #include 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 daf0269697d3..081b18ec2725 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c @@ -10,11 +10,13 @@ #include #include +#include #include #include extern int tty_read(unsigned minor,char * buf,int count,unsigned short flags); extern int tty_write(unsigned minor,char * buf,int count); +extern int lp_write(unsigned minor,char *buf, int count); typedef (*crw_ptr)(int,unsigned,char *,int,off_t *,unsigned short); @@ -24,6 +26,11 @@ static int rw_ttyx(int rw,unsigned minor,char * buf,int count,off_t * pos, unsig tty_write(minor,buf,count)); } +static int rw_lp(int rw,unsigned minor,char * buf,int count,off_t * pos, unsigned short flags) +{ + return ((rw==READ)?-EINVAL:lp_write(minor,buf,count)); +} + static int rw_tty(int rw,unsigned minor,char * buf,int count, off_t * pos, unsigned short flags) { if (current->tty<0) @@ -38,26 +45,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 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) @@ -104,7 +166,7 @@ static crw_ptr crw_table[]={ NULL, /* /dev/hd */ rw_ttyx, /* /dev/ttyx */ rw_tty, /* /dev/tty */ - NULL, /* /dev/lp */ + rw_lp, /* /dev/lp */ NULL}; /* unnamed pipes */ int char_read(struct inode * inode, struct file * filp, char * buf, int count) diff --git a/fs/exec.c b/fs/exec.c index 2195ff99f7fd..f27b51f44b2e 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -216,6 +216,7 @@ int do_execve(unsigned long * eip,long tmp,char * filename, int retval; int sh_bang = 0; unsigned long p=PAGE_SIZE*MAX_ARG_PAGES-4; + int ch; if ((0xffff & eip[1]) != 0x000f) panic("execve called from supervisor mode"); @@ -348,6 +349,15 @@ restart_interp: } /* OK, This is the point of no return */ /* note that current->library stays unchanged by an exec */ + for (i=0; (ch = get_fs_byte(filename++)) != '\0';) + if (ch == '/') + i = 0; + else + if (i < 8) + current->comm[i++] = ch; + if (i < 8) + current->comm[i] = '\0'; + if (current->executable) iput(current->executable); current->executable = inode; @@ -374,6 +384,7 @@ restart_interp: (current->end_data = ex.a_data + (current->end_code = ex.a_text)); current->start_stack = p; + current->rss = (LIBRARY_OFFSET - p + PAGE_SIZE-1) / PAGE_SIZE; current->suid = current->euid = e_uid; current->sgid = current->egid = e_gid; eip[0] = ex.a_entry; /* eip, magic happens :-) */ diff --git a/fs/fasterdisk.pat b/fs/fasterdisk.pat deleted file mode 100644 index 2e4b1fd39c49..000000000000 --- a/fs/fasterdisk.pat +++ /dev/null @@ -1,153 +0,0 @@ -From kwhite@csi.uottawa.ca Sun Mar 15 20:01:06 1992 -Received: from klaava.Helsinki.FI by kruuna.helsinki.fi with SMTP id AA04345 - (5.65c/IDA-1.4.4 for ); Sun, 15 Mar 1992 20:00:45 +0200 -Received: from csi.UOttawa.CA (csi0.csi.uottawa.ca) by klaava.Helsinki.FI (4.1/SMI-4.1) - id AA21712; Sun, 15 Mar 92 20:00:40 +0200 -Received: by csi.UOttawa.CA id AA00608 - (5.65+/IDA-1.3.5 for torvalds@klaava.helsinki.fi); Sun, 15 Mar 92 12:57:47 -0500 -From: Keith White -Message-Id: <9203151757.AA00608@csi.UOttawa.CA> -Subject: reset-floppy fixed, double your disk speed (linux 0.95) -To: torvalds@cc.helsinki.fi (Linus Torvalds) -Date: Sun, 15 Mar 92 12:57:46 EST -X-Mailer: ELM [version 2.3 PL11] -Status: OR - -A couple of things. - -1) I must be one of those lucky few who's been able to use linux0.95. -However I was surprised to see that hard disk speed was slower. This -was until I remembered that I had patched fs/block_dev.c and -include/asm/segment.h to support block moves to and from the fs -segment. These patches (very minimal it must be admitted) give a -reasonable increase in speed for 'fsck': - original: 42.62 elapsed - patched: 22.06 elapsed -These patches have no effect on sequential disk access (dd if=/dev/hda -...) since most time is spent waiting for those small 2 sector -transfers anyway. The patches are included below. - -2) I don't run DOS so a floppy disk format program is sort of -essential. Lawrence Foard's (sp?) formatting routines have a few -problems (nits). - a) The inter-sector gap should be larger for a format than it -is for a read or write. - b) An interleave is not required (at least on my machine, a -bottom of the line 386SX-16). - -3) I seem to have fixed the dreaded "reset-floppy called" problem -- -at least it works for me. The posted fix does not work in my case. -I'd send you these patches as well, but I only have diffs that include -all the mods I did for the floppy format stuff. The key point (I -think) was to only reset twice during an error loop. If a track was -bad, the recalibrate would fail and call reset which would call -recalibrate ... If you're interested, I could try to separate the -formatting stuff and all my debugging "printks" from the reset fix -stuff and send the diffs. - -...keith (kwhite@csi.uottawa.ca) - ----cut here--- -*** 1.1 1992/03/14 16:33:21 ---- include/asm/segment.h 1992/03/15 17:10:14 -*************** -*** 63,65 **** ---- 63,109 ---- - __asm__("mov %0,%%fs"::"r" ((unsigned short) val)); - } - -+ /* -+ * these routines are added to use the movs instruction with data -+ * in the fs segment. No optimizations are done with regards to using -+ * movsw or movsd -+ * -+ * kwhite@csi.uottawa.ca -+ */ -+ -+ #define memcpy_fromfs(dest,src,n) __asm__ (\ -+ "mov %%fs,%%ax; movl %%ax,%%ds\n\ -+ cld; rep; movsb\n\ -+ mov %%es,%%ax; mov %%ax,%%ds" \ -+ ::"D" ((long)(dest)), "S" ((long)(src)), "c" ((long) (n)) \ -+ :"di", "si", "cx", "ax"); -+ #define memcpy_fromfs_w(dest,src,n) __asm__ (\ -+ "mov %%fs,%%ax; movl %%ax,%%ds\n\ -+ cld; rep; movsw\n\ -+ mov %%es,%%ax; mov %%ax,%%ds" \ -+ ::"D" ((long)(dest)), "S" ((long)(src)), "c" ((long) (n)) \ -+ :"di", "si", "cx", "ax"); -+ #define memcpy_fromfs_l(dest,src,n) __asm__ (\ -+ "mov %%fs,%%ax; movl %%ax,%%ds\n\ -+ cld; rep; movsl\n\ -+ mov %%es,%%ax; mov %%ax,%%ds" \ -+ ::"D" ((long)(dest)), "S" ((long)(src)), "c" ((long) (n)) \ -+ :"di", "si", "cx", "ax"); -+ #define memcpy_tofs(dest,src,n) __asm__ (\ -+ "mov %%fs,%%ax; mov %%ax,%%es\n\ -+ cld; rep; movsb\n\ -+ mov %%ds,%%ax; mov %%ax,%%es" \ -+ ::"D" ((long)(dest)), "S" ((long)(src)), "c" ((long) (n)) \ -+ :"di", "si", "cx", "ax"); -+ #define memcpy_tofs_w(dest,src,n) __asm__ (\ -+ "mov %%fs,%%ax; mov %%ax,%%es\n\ -+ cld; rep; movsw\n\ -+ mov %%ds,%%ax; mov %%ax,%%es" \ -+ ::"D" ((long)(dest)), "S" ((long)(src)), "c" ((long) (n)) \ -+ :"di", "si", "cx", "ax"); -+ #define memcpy_tofs_l(dest,src,n) __asm__ (\ -+ "mov %%fs,%%ax; mov %%ax,%%es\n\ -+ cld; rep; movsl\n\ -+ mov %%ds,%%ax; mov %%ax,%%es"\ -+ ::"D" ((long)(dest)), "S" ((long)(src)), "c" ((long) (n)) \ -+ :"di", "si", "cx", "ax"); -*** 1.1 1992/03/14 16:37:10 ---- fs/block_dev.c 1992/03/14 16:38:26 -*************** -*** 47,54 **** ---- 47,64 ---- - filp->f_pos += chars; - written += chars; - count -= chars; -+ #ifdef notdef - while (chars-->0) - *(p++) = get_fs_byte(buf++); -+ #else -+ if ((chars&1) || ((long)p&1) || ((long)buf&1)) { -+ memcpy_fromfs(p, buf, chars); -+ } -+ else { -+ memcpy_fromfs_w(p, buf, chars>>1); -+ } -+ p += chars; buf += chars; chars = 0; -+ #endif - bh->b_dirt = 1; - brelse(bh); - } -*************** -*** 85,92 **** ---- 95,112 ---- - filp->f_pos += chars; - read += chars; - count -= chars; -+ #ifdef notdef - while (chars-->0) - put_fs_byte(*(p++),buf++); -+ #else -+ if ((chars&1) || ((long)buf&1) || ((long)p&1)) { -+ memcpy_tofs(buf, p, chars); -+ } -+ else { -+ memcpy_tofs_w(buf, p, chars>>1); -+ } -+ p += chars; buf += chars; chars = 0; -+ #endif - brelse(bh); - } - return read; ----cut here--- - --- -BITNET: kwhite@uotcsi2.bitnet (being phased out) -UUCP: {...,nrcaer,cunews}!uotcsi2!kwhite -INTERNET: kwhite@csi.uottawa.ca - diff --git a/fs/inode.c b/fs/inode.c index 7173e2371d10..c1634d87bcfd 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -8,16 +8,12 @@ #include #include -#include #include #include #include struct inode inode_table[NR_INODE]={{0,},}; -extern void minix_read_inode(struct inode * inode); -extern void minix_write_inode(struct inode * inode); - static inline void wait_on_inode(struct inode * inode) { cli(); @@ -48,20 +44,34 @@ static void write_inode(struct inode * inode) unlock_inode(inode); return; } - minix_write_inode(inode); + if (inode->i_op && inode->i_op->write_inode) + inode->i_op->write_inode(inode); unlock_inode(inode); } static void read_inode(struct inode * inode) { lock_inode(inode); - minix_read_inode(inode); + if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->read_inode) + inode->i_sb->s_op->read_inode(inode); unlock_inode(inode); } +/* + * bmap is needed for demand-loading and paging: if this function + * doesn't exist for a filesystem, then those things are impossible: + * executables cannot be run from the filesystem etc... + * + * This isn't as bad as it sounds: the read-routines might still work, + * so the filesystem would be otherwise ok (for example, you might have + * a DOS filesystem, which doesn't lend itself to bmap very well, but + * you could still transfer files to/from the filesystem) + */ int bmap(struct inode * inode, int block) { - return minix_bmap(inode,block); + if (inode->i_op && inode->i_op->bmap) + return inode->i_op->bmap(inode,block); + return 0; } void invalidate_inodes(int dev) @@ -127,8 +137,8 @@ repeat: return; } if (!inode->i_nlink) { - minix_truncate(inode); - minix_free_inode(inode); + if (inode->i_op && inode->i_op->put_inode) + inode->i_op->put_inode(inode); return; } if (inode->i_dirt) { diff --git a/fs/ioctl.c b/fs/ioctl.c index d293a929fd47..284a0dc0c8c4 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -10,6 +10,7 @@ #include +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 967bda58f589..fd1a331e2af6 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 d9d1fb907e57..91995d9ff69b 100644 --- a/fs/minix/file_dev.c +++ b/fs/minix/file_dev.c @@ -6,6 +6,8 @@ #include #include +#include +#include #include #include @@ -15,6 +17,49 @@ #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); + brelse(bh); + 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 +73,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 +143,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 a4dab0533df2..75ec7a2b2770 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -13,15 +13,100 @@ #include #include -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;is_imap[i]); + for(i=0;is_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 a85e3a89104d..7fd55591cbb0 100644 --- a/fs/minix/minix_op.c +++ b/fs/minix/minix_op.c @@ -7,6 +7,12 @@ #include #include +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 d3c0224ca5ce..ba891cba9929 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c @@ -15,10 +15,6 @@ #include #include -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= (void *) (bh->b_data+BLOCK_SIZE)) { brelse(bh); - block=bmap(inode,nr/MINIX_DIR_ENTRIES_PER_BLOCK); + block = minix_bmap(inode,nr/MINIX_DIR_ENTRIES_PER_BLOCK); if (!block) { nr += MINIX_DIR_ENTRIES_PER_BLOCK; continue; diff --git a/fs/namei.c b/fs/namei.c index f1a0e8f6a0fb..6833d622a70e 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -9,7 +9,6 @@ */ #include -#include #include #include @@ -249,7 +248,8 @@ int open_namei(const char * pathname, int flag, int mode, } inode->i_atime = CURRENT_TIME; if (flag & O_TRUNC) - minix_truncate(inode); + if (inode->i_op && inode->i_op->truncate) + inode->i_op->truncate(inode); *res_inode = inode; return 0; } @@ -270,7 +270,7 @@ int sys_mknod(const char * filename, int mode, int dev) } if (!permission(dir,MAY_WRITE)) { iput(dir); - return -EPERM; + return -EACCES; } if (!dir->i_op || !dir->i_op->mknod) { iput(dir); @@ -293,7 +293,7 @@ int sys_mkdir(const char * pathname, int mode) } if (!permission(dir,MAY_WRITE)) { iput(dir); - return -EPERM; + return -EACCES; } if (!dir->i_op || !dir->i_op->mkdir) { iput(dir); @@ -316,7 +316,7 @@ int sys_rmdir(const char * name) } if (!permission(dir,MAY_WRITE)) { iput(dir); - return -EPERM; + return -EACCES; } if (!dir->i_op || !dir->i_op->rmdir) { iput(dir); @@ -335,11 +335,11 @@ int sys_unlink(const char * name) return -ENOENT; if (!namelen) { iput(dir); - return -ENOENT; + return -EPERM; } if (!permission(dir,MAY_WRITE)) { iput(dir); - return -EPERM; + return -EACCES; } if (!dir->i_op || !dir->i_op->unlink) { iput(dir); @@ -356,14 +356,14 @@ int sys_symlink(const char * oldname, const char * newname) dir = dir_namei(newname,&namelen,&basename, NULL); if (!dir) - return -EACCES; + return -ENOENT; if (!namelen) { iput(dir); - return -EPERM; + return -ENOENT; } if (!permission(dir,MAY_WRITE)) { iput(dir); - return -EPERM; + return -EACCES; } if (!dir->i_op || !dir->i_op->symlink) { iput(dir); diff --git a/fs/open.c b/fs/open.c index 9653b8345919..fe0fb5b5db9d 100644 --- a/fs/open.c +++ b/fs/open.c @@ -29,6 +29,11 @@ int sys_utime(char * filename, struct utimbuf * times) if (!(inode=namei(filename))) return -ENOENT; if (times) { + if (current->euid != inode->i_uid && + !permission(inode,MAY_WRITE)) { + iput(inode); + return -EPERM; + } actime = get_fs_long((unsigned long *) ×->actime); modtime = get_fs_long((unsigned long *) ×->modtime); } else diff --git a/fs/pipe.c b/fs/pipe.c index d1b6e7c7819d..5f773d9c155c 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -41,7 +41,7 @@ int pipe_read(struct inode * inode, struct file * filp, char * buf, int count) put_fs_byte(((char *)inode->i_size)[size++],buf++); } wake_up(& PIPE_WRITE_WAIT(*inode)); - return read; + return read?read:-EAGAIN; } int pipe_write(struct inode * inode, struct file * filp, char * buf, int count) diff --git a/fs/read_write.c b/fs/read_write.c index da81a6fb2533..1a9b20a4a066 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -4,18 +4,39 @@ * (C) 1991 Linus Torvalds */ -#include #include #include +#include +#include #include #include +#include #include -int sys_lseek(unsigned int fd,off_t offset, unsigned int origin) +/* + * Count is not yet used: but we'll probably support reading several entries + * at once in the future. Use count=1 in the library for future expansions. + */ +int sys_readdir(unsigned int fd, struct dirent * dirent, unsigned int count) +{ + struct file * file; + 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) { + verify_area(dirent, sizeof (*dirent)); + 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; + int tmp, mem_dev; if (fd >= NR_OPEN || !(file=current->filp[fd]) || !(file->f_inode)) return -EBADF; @@ -25,21 +46,25 @@ int sys_lseek(unsigned int fd,off_t offset, unsigned int origin) return -ESPIPE; if (file->f_op && file->f_op->lseek) return file->f_op->lseek(file->f_inode,file,offset,origin); + mem_dev = S_ISCHR(file->f_inode->i_mode); + /* this is the default handler if no lseek handler is present */ switch (origin) { case 0: - if (offset<0) return -EINVAL; + if (offset<0 && !mem_dev) return -EINVAL; file->f_pos=offset; break; case 1: - if (file->f_pos+offset<0) return -EINVAL; + if (file->f_pos+offset<0 && !mem_dev) return -EINVAL; file->f_pos += offset; break; case 2: - if ((tmp=file->f_inode->i_size+offset) < 0) + if ((tmp=file->f_inode->i_size+offset)<0 && !mem_dev) return -EINVAL; file->f_pos = tmp; } + if (mem_dev && file->f_pos < 0) + return 0; return file->f_pos; } diff --git a/fs/super.c b/fs/super.c index eedff32e1368..b4c95e0315ff 100644 --- a/fs/super.c +++ b/fs/super.c @@ -29,7 +29,26 @@ struct super_block super_block[NR_SUPER]; /* this is initialized in init/main.c */ int ROOT_DEV = 0; -static void lock_super(struct super_block * sb) +/* Move into include file later */ + +static struct file_system_type file_systems[] = { + {minix_read_super,"minix"}, + {NULL,NULL} +}; + +/* end of include file */ + +struct file_system_type *get_fs_type(char *name) +{ + int a; + + for(a = 0 ; file_systems[a].read_super ; a++) + if (!strcmp(name,file_systems[a].name)) + return(&file_systems[a]); + return(NULL); +} + +void lock_super(struct super_block * sb) { cli(); while (sb->s_lock) @@ -38,7 +57,7 @@ static void lock_super(struct super_block * sb) sti(); } -static void free_super(struct super_block * sb) +void free_super(struct super_block * sb) { cli(); sb->s_lock = 0; @@ -46,7 +65,7 @@ static void free_super(struct super_block * sb) sti(); } -static void wait_on_super(struct super_block * sb) +void wait_on_super(struct super_block * sb) { cli(); while (sb->s_lock) @@ -75,7 +94,6 @@ struct super_block * get_super(int dev) void put_super(int dev) { struct super_block * sb; - int i; if (dev == ROOT_DEV) { printk("root diskette changed: prepare for armageddon\n\r"); @@ -87,27 +105,24 @@ void put_super(int dev) printk("Mounted disk changed - tssk, tssk\n\r"); return; } - lock_super(sb); - sb->s_dev = 0; - for(i=0;is_imap[i]); - for(i=0;is_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;is_imap[i]); - for(i=0;is_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 ; inodei_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 3e67974c6994..5468aa41ec3e 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 9886d7bda81b..226f3439bf60 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 000000000000..1303adfd2cc3 --- /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/config.h b/include/linux/config.h index fc2ce17daf95..8c79f935c375 100644 --- a/include/linux/config.h +++ b/include/linux/config.h @@ -1,22 +1,23 @@ #ifndef _CONFIG_H #define _CONFIG_H -/* - * Define this if you want the math-emulation code: if this is undefined, - * the kernel will be smaller, but you'll get FPU exceptions if you don't - * have a 387 and are trying to use math. - */ - -#define KERNEL_MATH_EMULATION - - /* * Defines for what uname() should return */ +#ifndef UTS_SYSNAME #define UTS_SYSNAME "Linux" +#endif +#ifndef UTS_NODENAME #define UTS_NODENAME "(none)" /* set by sethostname() */ -#define UTS_RELEASE "0" /* patchlevel */ -#define UTS_VERSION "0.95a" +#endif +#include +#ifndef UTS_RELEASE +#define UTS_RELEASE "0.95c-0" +#endif +#include +#ifndef UTS_VERSION +#define UTS_VERSION "mm/dd/yy" +#endif #define UTS_MACHINE "i386" /* hardware type */ /* Don't touch these, unless you really know what your doing. */ diff --git a/include/linux/config_rel.h b/include/linux/config_rel.h new file mode 100644 index 000000000000..0e26529824ec --- /dev/null +++ b/include/linux/config_rel.h @@ -0,0 +1 @@ +#define UTS_RELEASE "0.95c-18" diff --git a/include/linux/config_ver.h b/include/linux/config_ver.h new file mode 100644 index 000000000000..102462450c5f --- /dev/null +++ b/include/linux/config_ver.h @@ -0,0 +1 @@ +#define UTS_VERSION "04/09/92" diff --git a/include/linux/fs.h b/include/linux/fs.h index 885164658c5c..d75dd80f4910 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -7,6 +7,7 @@ #define _FS_H #include +#include /* 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 883c7ae70ee7..e7e134762d4a 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/lp.h b/include/linux/lp.h new file mode 100644 index 000000000000..69049a73880e --- /dev/null +++ b/include/linux/lp.h @@ -0,0 +1,114 @@ +/* +$Header: /usr/src/linux/include/linux/lp.h,v 1.2 1992/01/21 23:59:24 james_r_wiegand Exp james_r_wiegand $ +*/ + +#include +#include +#include +#include +#include + +/* + * usr/include/linux/lp.h c.1991-1992 James Wiegand + */ + +/* + * caveat: my machine only has 1 printer @ lpt2 so lpt1 & lpt3 are + * implemented but UNTESTED + */ + +/* + * Per POSIX guidelines, this module reserves the LP and lp prefixes + */ +#define LP_EXIST 0x0001 +#define LP_SELEC 0x0002 +#define LP_BUSY 0x0004 +#define LP_OFFL 0x0008 +#define LP_NOPA 0x0010 +#define LP_ERR 0x0020 + +#define LP_TIMEOUT 200000 + +#define LP_B(minor) lp_table[(minor)].base +#define LP_F(minor) lp_table[(minor)].flags +#define LP_T(minor) lp_table[(minor)].lp_task +#define LP_S(minor) inb(LP_B((minor)) + 1) +#define LP_R(minor) lp_table[(minor)].remainder + +/* +since we are dealing with a horribly slow device +I don't see the need for a queue +*/ +#ifndef __LP_C__ + extern +#endif +struct lp_struct { + int base; + int flags; + /* number of characters yet to be printed in current block */ + int remainder; + /* needed for busy determination */ + int lp_task; +}; + +/* + * the BIOS manuals say there can be up to 4 lpt devices + * but I have not seen a board where the 4th address is listed + * if you have different hardware change the table below + * please let me know if you have different equipment + * if you have more than 3 printers, remember to increase LP_NO + */ +#ifndef __LP_C__ + extern +#endif +struct lp_struct lp_table[] = { + { 0x3bc, 0, }, + { 0x378, 0, }, + { 0x278, 0, } +}; + +#define LP_NO 3 + +/* + * bit defines for 8255 status port + * base + 1 + */ +#define LP_PBUSY 0x80 /* active low */ +#define LP_PACK 0x40 /* active low */ +#define LP_POUTPA 0x20 +#define LP_PSELECD 0x10 +#define LP_PERRORP 0x08 /*Ã¥ active low*/ +#define LP_PIRQ 0x04 /* active low */ + +/* + * defines for 8255 control port + * base + 2 + */ +#define LP_PIRQEN 0x10 +#define LP_PSELECP 0x08 +#define LP_PINITP 0x04 /* active low */ +#define LP_PAUTOLF 0x02 +#define LP_PSTROBE 0x01 + +/* + * the value written to ports to test existence. PC-style ports will + * return the value written. AT-style ports will return 0. so why not + * make them the same ? + */ +#define LP_DUMMY 0x00 + +/* + * this is the port delay time. your mileage may vary + */ +#define LP_DELAY 150000 + +/* + * function prototypes + */ + +extern void lp_init(void); + +extern int lp_reset(int minor); +extern int lp_char(char lpchar, int minor); +extern int lp_write(unsigned minor, char *buf, int count); + diff --git a/include/linux/minix_fs.h b/include/linux/minix_fs.h index 4ccb8458361e..189f438f190f 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 99f919b64416..e1fac8244033 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 1e6f2c3daf5b..e7218655e433 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 805894dedca2..d185dd661355 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 000000000000..d0873a9ba823 --- /dev/null +++ b/include/sys/dirent.h @@ -0,0 +1,13 @@ +#ifndef _SYS_DIRENT_H +#define _SYS_DIRENT_H + +#include + +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 622aa6f19aa5..f297df97d980 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 - illegally already. + * The rest of these includes are also illegal (too much pollution). + */ +#include +#endif #include #include #include @@ -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 5a5444f060ba..a822e41bc0fc 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 ee05aaab1e19..516ab48771fd 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 c159025d558e..746f5f024f05 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< + #include #include #include @@ -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 ; ierrors >= 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 777dcc3f5a83..7b17306c71dc 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 4c28f9c1b036..0246fc78d500 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) \ @@ -28,14 +26,14 @@ CPP =gcc -E -nostdinc -I../../include -c -o $*.o $< OBJS = tty_io.o console.o keyboard.o serial.o rs_io.o \ - tty_ioctl.o pty.o + tty_ioctl.o pty.o lp.o chr_drv.a: $(OBJS) $(AR) rcs 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,39 @@ 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/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/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \ ../../include/linux/mm.h ../../include/linux/kernel.h \ ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h \ ../../include/time.h ../../include/sys/resource.h \ - ../../include/asm/system.h ../../include/asm/io.h -serial.s serial.o : serial.c ../../include/linux/tty.h ../../include/termios.h \ + ../../include/linux/timer.h ../../include/linux/tty.h \ + ../../include/termios.h ../../include/linux/config.h \ + ../../include/linux/config_rel.h ../../include/linux/config_ver.h \ + ../../include/asm/io.h ../../include/asm/system.h \ + ../../include/asm/segment.h ../../include/string.h ../../include/errno.h +lp.s lp.o : lp.c ../../include/linux/lp.h ../../include/errno.h \ + ../../include/linux/kernel.h ../../include/linux/sched.h \ + ../../include/linux/head.h ../../include/linux/fs.h \ + ../../include/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \ + ../../include/linux/mm.h ../../include/signal.h ../../include/sys/param.h \ + ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h \ + ../../include/asm/io.h ../../include/asm/segment.h \ + ../../include/checkpoint.h +pty.s pty.o : pty.c ../../include/linux/tty.h ../../include/termios.h \ ../../include/sys/types.h ../../include/linux/sched.h \ ../../include/linux/head.h ../../include/linux/fs.h \ - ../../include/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/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/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 +88,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 f506c4c63070..2d62be345b5b 100644 --- a/kernel/chr_drv/console.c +++ b/kernel/chr_drv/console.c @@ -167,20 +167,35 @@ static void sysbeep(void); #define RESPONSE "\033[?1;2c" static char * translations[] = { -/* normal 7-bit ascii */ +/* 8-bit Latin-1 mapped to the PC charater set: '\0' means non-printable */ + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" " !\"#$%&'()*+,-./0123456789:;<=>?" "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" - "`abcdefghijklmnopqrstuvwxyz{|}~ ", + "`abcdefghijklmnopqrstuvwxyz{|}~\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\040\255\233\234\376\235\174\025\376\376\246\256\252\055\376\376" + "\370\361\375\376\376\346\024\371\376\376\247\257\254\253\376\250" + "\376\376\376\376\216\217\222\200\376\220\376\376\376\376\376\376" + "\376\245\376\376\376\376\231\376\376\376\376\376\232\376\376\341" + "\205\240\203\376\204\206\221\207\212\202\210\211\215\241\214\213" + "\376\244\225\242\223\376\224\366\376\227\243\226\201\376\376\230", /* vt100 graphics */ - " !\"#$%&'()*+,-./\333123456789:;<=>?" - "@ABCDEFGH\017JKLMNOPQRSTUVWXYZ[\\]^ " - /* ' a b c d e f g h i j k l m n o */ - "\004\261\007\007\007\007\370\361\040\007\331\277\332\300\305\007" - /* p q r s t u v w x y z { | } ~ */ - "\007\304\007\007\303\264\301\302\263\007\007\007\007\007\234 " - - /*"\004\261\007\007\007\007\370\361\007\007\275\267\326\323\327\304" - "\304\304\304\304\307\266\320\322\272\363\362\343\\007\234\007 " */ + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + " !\"#$%&'()*+,-./0123456789:;<=>?" + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ " + "\004\261\007\007\007\007\370\361\007\007\275\267\326\323\327\304" + "\304\304\304\304\307\266\320\322\272\363\362\343\007\234\007\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\040\255\233\234\376\235\174\025\376\376\246\256\252\055\376\376" + "\370\361\375\376\376\346\024\371\376\376\247\257\254\253\376\250" + "\376\376\376\376\216\217\222\200\376\220\376\376\376\376\376\376" + "\376\245\376\376\376\376\231\376\376\376\376\376\232\376\376\341" + "\205\240\203\376\204\206\221\207\212\202\210\211\215\241\214\213" + "\376\244\225\242\223\376\224\366\376\227\243\226\201\376\376\230" }; #define NORM_TRANS (translations[0]) @@ -394,10 +409,10 @@ static void csi_m(int currcons ) else { /* check if forground == background */ if (vc_cons[currcons].vc_bold_attr != -1) - attr = (vc_cons[currcons].vc_bold_attr&0x0f)|(0xf0&(attr)); + attr = (vc_cons[currcons].vc_bold_attr&0x0f)|(0xf0&(attr)); else { short newattr = (attr&0xf0)|(0xf&(~attr)); - attr = ((newattr&0xf)==((attr>>4)&0xf)? + attr = ((newattr&0xf)==((attr>>4)&0xf)? (attr&0xf0)|(((attr&0xf)+1)%0xf): newattr); } @@ -456,7 +471,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) @@ -571,13 +586,14 @@ void con_write(struct tty_struct * tty) state = ESnormal; switch(state) { case ESnormal: - if (c > 31 && c < 127) { + if (translate[c]) { + c = translate[c]; while (x >= video_num_columns) { x -= video_num_columns; pos -= video_size_row; lf(currcons); } - *(char *) pos = translate[c-32]; + *(char *) pos = c; *(char *) (pos+1) = attr; pos += 2; x++; @@ -823,7 +839,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< + +#include + +int lp_reset(int minor) +{ + int testvalue; + + /* reset value */ + outb(0, LP_B(minor)+2); + for (testvalue = 0 ; testvalue < LP_DELAY ; testvalue++) + ; + outb(LP_PSELECP | LP_PINITP, LP_B(minor)+2); + return LP_S(minor); +} + +void lp_init(void) +{ + int offset = 0; + unsigned int testvalue = 0; + int count = 0; + + /* take on all known port values */ + for (offset = 0; offset < LP_NO; offset++) { + /* write to port & read back to check */ + outb( LP_DUMMY, LP_B(offset)); + for (testvalue = 0 ; testvalue < LP_DELAY ; testvalue++) + ; + testvalue = inb(LP_B(offset)); + if (testvalue != 255) { + LP_F(offset) |= LP_EXIST; + lp_reset(offset); + printk("lp_init: lp%d exists (%d)\n", offset, testvalue); + count++; + } + } + if (count == 0) + printk("lp_init: no lp devices found\n"); +} + +int lp_char(char lpchar, int minor) +{ + int retval = 0; + unsigned long count = 0; + + outb(lpchar, LP_B(minor)); + do { + retval = LP_S(minor); + schedule(); + count ++; + } while(!(retval & LP_PBUSY) && count < LP_TIMEOUT); + if (count == LP_TIMEOUT) { + printk("lp%d timeout\n\r", minor); + return 0; + } + /* control port pr_table[0]+2 take strobe high */ + outb(( LP_PSELECP | LP_PINITP | LP_PSTROBE ), ( LP_B( minor ) + 2 )); + /* take strobe low */ + outb(( LP_PSELECP | LP_PINITP ), ( LP_B( minor ) + 2 )); + /* get something meaningful for return value */ + return LP_S(minor); +} + +int lp_write(unsigned minor, char *buf, int count) +{ + int retval; + int loop; + int tcount; + char c, *temp = buf; + + if (minor > LP_NO - 1) + return -ENODEV; + if ((LP_F(minor) & LP_EXIST) == 0) + return -ENODEV; + +/* if we aren't the "owner task", check if the old owner has died... */ + if (LP_T(minor) != current->pid && (LP_F(minor) & LP_BUSY)) { + for(tcount = 0; tcount < NR_TASKS; tcount++) { + if (!task[tcount]) + continue; + if (task[tcount]->state == TASK_ZOMBIE) + continue; + if (task[tcount]->pid == LP_T(minor)) { + tcount = -1; + break; + } + } + if (tcount == -1) + return -EBUSY; + } + + LP_T(minor) = current->pid; + LP_F(minor) |= LP_BUSY; + LP_R(minor) = count; + temp = buf; + + for (loop = 0 ; loop < count ; loop++, temp++) { + c = get_fs_byte(temp); + retval = lp_char(c, minor); + LP_R(minor)--; + if (retval & LP_POUTPA) { + LP_F(minor) |= LP_NOPA; + return loop?loop:-ENOSPC; + } else + LP_F(minor) &= ~LP_NOPA; + + if (!(retval & LP_PSELECD)) { + LP_F(minor) &= ~LP_SELEC; + return loop?loop:-EFAULT; + } else + LP_F(minor) &= ~LP_SELEC; + + /* not offline or out of paper. on fire? */ + if (!(retval & LP_PERRORP)) { + LP_F(minor) |= LP_ERR; + return loop?loop:-EIO; + } else + LP_F(minor) &= ~LP_SELEC; + } + return count; +} diff --git a/kernel/chr_drv/pty.c b/kernel/chr_drv/pty.c index 43407dc75d0e..aed5b6e169b8 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 741cc435f863..bd55ec1caf13 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 12c64799f65e..511860ae79cc 100644 --- a/kernel/chr_drv/tty_io.c +++ b/kernel/chr_drv/tty_io.c @@ -26,6 +26,8 @@ int kill_pg(int pgrp, int sig, int priv); int is_orphaned_pgrp(int pgrp); + +extern void lp_init(void); #define _L_FLAG(tty,f) ((tty)->termios.c_lflag & f) #define _I_FLAG(tty,f) ((tty)->termios.c_iflag & f) @@ -46,6 +48,7 @@ int is_orphaned_pgrp(int pgrp); #define I_CRNL(tty) _I_FLAG((tty),ICRNL) #define I_NOCR(tty) _I_FLAG((tty),IGNCR) #define I_IXON(tty) _I_FLAG((tty),IXON) +#define I_STRP(tty) _I_FLAG((tty),ISTRIP) #define O_POST(tty) _O_FLAG((tty),OPOST) #define O_NLCR(tty) _O_FLAG((tty),ONLCR) @@ -129,13 +132,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; @@ -146,6 +142,8 @@ void copy_to_cooked(struct tty_struct * tty) break; } GETCH(tty->read_q,c); + if (I_STRP(tty)) + c &= 0x7f; if (c==13) { if (I_CRNL(tty)) c=10; @@ -160,13 +158,14 @@ void copy_to_cooked(struct tty_struct * tty) (c==KILL_CHAR(tty))) { /* deal with killing the input line */ while(!(EMPTY(tty->secondary) || - (c=LAST(tty->secondary))==10 || - ((EOF_CHAR(tty) != _POSIX_VDISABLE) && + (c=LAST(tty->secondary))==10 || + ((EOF_CHAR(tty) != _POSIX_VDISABLE) && (c==EOF_CHAR(tty))))) { if (L_ECHO(tty)) { if (c<32) PUTCH(127,tty->write_q); PUTCH(127,tty->write_q); + TTY_WRITE_FLUSH(tty); } DEC(tty->secondary->head); } @@ -183,6 +182,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 +197,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; } } @@ -219,7 +220,7 @@ void copy_to_cooked(struct tty_struct * tty) } } if (c==10 || (EOF_CHAR(tty) != _POSIX_VDISABLE && - c==EOF_CHAR(tty))) + c==EOF_CHAR(tty))) tty->secondary->data++; if ((L_ECHO(tty) || L_ECHONL(tty)) && (c==10)) { PUTCH(10,tty->write_q); @@ -232,11 +233,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 +308,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 +323,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 +401,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(); } @@ -504,4 +507,5 @@ void tty_init(void) rs_init(); printk("%d virtual consoles\n\r",NR_CONSOLES); printk("%d pty's\n\r",NR_PTYS); + lp_init(); } diff --git a/kernel/chr_drv/tty_ioctl.c b/kernel/chr_drv/tty_ioctl.c index eabfbed1b2ca..a8594f0f5f8d 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 be284bd3543e..50f61464b47d 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; } @@ -66,8 +63,8 @@ void release(struct task_struct * p) return; } for (i=1 ; ip_osptr) p->p_osptr->p_ysptr = p->p_ysptr; @@ -75,8 +72,7 @@ void release(struct task_struct * p) p->p_ysptr->p_osptr = p->p_osptr; else p->p_pptr->p_cptr = p->p_osptr; - free_page((long)p); - schedule(); + free_page((long) p); return; } panic("trying to release non-existent task"); @@ -218,15 +214,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 +291,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 @@ -319,38 +319,28 @@ volatile void do_exit(long code) * as a result of our exiting, and if they have any stopped * jons, send them a SIGUP and then a SIGCONT. (POSIX 3.2.2.2) */ - if (p = current->p_cptr) { - while (1) { - p->flags &= ~PF_PTRACED; - p->p_pptr = task[1]; - if (p->state == TASK_ZOMBIE) - task[1]->signal |= (1<<(SIGCHLD-1)); - /* - * process group orphan check - * Case ii: Our child is in a different pgrp - * than we are, and it was the only connection - * outside, so the child pgrp is now orphaned. - */ - if ((p->pgrp != current->pgrp) && - (p->session == current->session) && - is_orphaned_pgrp(p->pgrp) && - has_stopped_jobs(p->pgrp)) { - kill_pg(p->pgrp,SIGHUP,1); - kill_pg(p->pgrp,SIGCONT,1); - } - if (p->p_osptr) { - p = p->p_osptr; - continue; - } - /* - * This is it; link everything into init's children - * and leave - */ - p->p_osptr = task[1]->p_cptr; - task[1]->p_cptr->p_ysptr = p; - task[1]->p_cptr = current->p_cptr; - current->p_cptr = 0; - break; + while (p = current->p_cptr) { + current->p_cptr = p->p_osptr; + p->p_ysptr = NULL; + p->flags &= ~PF_PTRACED; + p->p_pptr = task[1]; + p->p_osptr = task[1]->p_cptr; + task[1]->p_cptr->p_ysptr = p; + task[1]->p_cptr = p; + if (p->state == TASK_ZOMBIE) + task[1]->signal |= (1<<(SIGCHLD-1)); + /* + * process group orphan check + * Case ii: Our child is in a different pgrp + * than we are, and it was the only connection + * outside, so the child pgrp is now orphaned. + */ + if ((p->pgrp != current->pgrp) && + (p->session == current->session) && + is_orphaned_pgrp(p->pgrp) && + has_stopped_jobs(p->pgrp)) { + kill_pg(p->pgrp,SIGHUP,1); + kill_pg(p->pgrp,SIGCONT,1); } } if (current->leader) { @@ -413,8 +403,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 e3e1e67dcdd6..ad65fb1229be 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 d136ef5dd5e1..3c061837aab6 100644 --- a/kernel/math/Makefile +++ b/kernel/math/Makefile @@ -10,21 +10,19 @@ 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 \ +OBJS = emulate.o error.o convert.o ea.o get_put.o \ add.o mul.o div.o compare.o math.a: $(OBJS) @@ -83,7 +81,7 @@ get_put.s get_put.o : get_put.c ../../include/signal.h ../../include/sys/types.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 -math_emulate.s math_emulate.o : math_emulate.c ../../include/linux/config.h +emulate.s emulate.o : emulate.c ../../include/linux/config.h mul.s mul.o : mul.c ../../include/linux/math_emu.h ../../include/linux/sched.h \ ../../include/linux/head.h ../../include/linux/fs.h \ ../../include/sys/types.h ../../include/linux/mm.h \ diff --git a/kernel/math/math_emulate.c b/kernel/math/emulate.c similarity index 98% rename from kernel/math/math_emulate.c rename to kernel/math/emulate.c index 6fb6e6f0067f..b8e3ac2089ef 100644 --- a/kernel/math/math_emulate.c +++ b/kernel/math/emulate.c @@ -1,5 +1,5 @@ /* - * linux/kernel/math/math_emulate.c + * linux/kernel/math/emulate.c * * (C) 1991 Linus Torvalds */ @@ -30,8 +30,6 @@ * hide most of the 387-specific things here. */ -#include - #ifdef KERNEL_MATH_EMULATION #include @@ -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 6722ef7233ad..051241dfb336 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 #include @@ -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 2c8a845efee6..3c274e64ab70 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;iutime); 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 9f678c8fab0a..83a543fa1ed8 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/makever.sh b/makever.sh new file mode 100644 index 000000000000..1b230e222b39 --- /dev/null +++ b/makever.sh @@ -0,0 +1,13 @@ +#! /bin/sh + +if [ ! -f .version ] +then + echo 0 > .version +fi +cycle=`cat .version` +cycle=`expr $cycle + 1` +if [ $cycle -gt 99 ] +then + cycle=0 +fi +echo $cycle > .version diff --git a/mm/Makefile b/mm/Makefile index cc6e20965fe6..27b2f4ec397c 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 574f28152b07..8e93a1b8bbe2 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> 4]) + printk("swapping out page from non-existent task\n\r"); + else + task[dir_entry >> 4]->rss--; return 1; + } goto check_table; no_swap: printk("Out of swap-memory\n\r"); -- 2.39.5