Commit 6891759b authored by Linus Torvalds's avatar Linus Torvalds

[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
parent e4f54503
#
# 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
......@@ -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:
......@@ -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
......
This diff is collapsed.
......@@ -27,8 +27,8 @@
#include <asm/io.h>
extern int end;
struct buffer_head * start_buffer = (struct buffer_head *) &end;
struct buffer_head * hash_table[NR_HASH];
static struct buffer_head * start_buffer = (struct buffer_head *) &end;
static struct buffer_head * hash_table[NR_HASH];
static struct buffer_head * free_list;
static struct task_struct * buffer_wait = NULL;
int NR_BUFFERS = 0;
......@@ -406,6 +406,10 @@ void buffer_init(long buffer_end)
else
b = (void *) buffer_end;
while ( (b -= BLOCK_SIZE) >= ((void *) (h+1)) ) {
if (((unsigned long) (h+1)) > 0xA0000) {
printk("buffer-list doesn't fit in low meg - contact Linus\n");
break;
}
h->b_dev = 0;
h->b_dirt = 0;
h->b_count = 0;
......
......@@ -10,11 +10,13 @@
#include <linux/sched.h>
#include <linux/kernel.h>
#include <checkpoint.h>
#include <asm/segment.h>
#include <asm/io.h>
extern int tty_read(unsigned minor,char * buf,int count,unsigned short flags);
extern int tty_write(unsigned minor,char * buf,int count);
extern int lp_write(unsigned minor,char *buf, int count);
typedef (*crw_ptr)(int,unsigned,char *,int,off_t *,unsigned short);
......@@ -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 <LOW_MEM) ) {
if (rw==READ)
put_fs_byte( *(char *)i ,buf++);
else
return (-EIO);
i++;
char *p=(char *) *pos;
if ((unsigned long) *pos > HIGH_MEMORY)
return 0;
if ((unsigned long) *pos + count > HIGH_MEMORY)
count = HIGH_MEMORY - *pos;
switch (rw) {
case READ:
while ((count -= 4) >= 0)
put_fs_long(*((unsigned long *) p)++,
((unsigned long *) buf)++);
count += 4;
while (--count >= 0)
put_fs_byte(*p++, buf++);
break;
case WRITE:
while (--count >= 0)
*p++ = get_fs_byte(buf++);
break;
default:
return -EINVAL;
}
i -= *pos; /* Count how many read or write */
*pos += i; /* Update position */
return (i); /* Return number read */
p -= *pos;
*pos += (int) p;
return (int) p;
}
static int rw_port(int rw,char * buf, int count, off_t * pos)
......@@ -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)
......
......@@ -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 @@ int do_execve(unsigned long * eip,long tmp,char * filename,
}
/* 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 @@ int do_execve(unsigned long * eip,long tmp,char * filename,
(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 :-) */
......
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 <torvalds@klaava.Helsinki.FI>); 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 <kwhite@csi.uottawa.ca>
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
......@@ -8,16 +8,12 @@
#include <sys/stat.h>
#include <linux/sched.h>
#include <linux/minix_fs.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <asm/system.h>
struct inode inode_table[NR_INODE]={{0,},};
extern void minix_read_inode(struct inode * inode);
extern void minix_write_inode(struct inode * inode);
static inline void wait_on_inode(struct inode * inode)
{
cli();
......@@ -48,20 +44,34 @@ static void write_inode(struct inode * inode)
unlock_inode(inode);
return;
}
minix_write_inode(inode);
if (inode->i_op && inode->i_op->write_inode)
inode->i_op->write_inode(inode);
unlock_inode(inode);
}
static void read_inode(struct inode * inode)
{
lock_inode(inode);
minix_read_inode(inode);
if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->read_inode)
inode->i_sb->s_op->read_inode(inode);
unlock_inode(inode);
}
/*
* bmap is needed for demand-loading and paging: if this function
* doesn't exist for a filesystem, then those things are impossible:
* executables cannot be run from the filesystem etc...
*
* This isn't as bad as it sounds: the read-routines might still work,
* so the filesystem would be otherwise ok (for example, you might have
* a DOS filesystem, which doesn't lend itself to bmap very well, but
* you could still transfer files to/from the filesystem)
*/
int bmap(struct inode * inode, int block)
{
return minix_bmap(inode,block);
if (inode->i_op && inode->i_op->bmap)
return inode->i_op->bmap(inode,block);
return 0;
}
void invalidate_inodes(int dev)
......@@ -127,8 +137,8 @@ void iput(struct inode * inode)
return;
}
if (!inode->i_nlink) {
minix_truncate(inode);
minix_free_inode(inode);
if (inode->i_op && inode->i_op->put_inode)
inode->i_op->put_inode(inode);
return;
}
if (inode->i_dirt) {
......
......@@ -10,6 +10,7 @@
#include <linux/sched.h>
extern int hd_ioctl(int dev, int cmd, int arg);
extern int tty_ioctl(int dev, int cmd, int arg);
extern int pipe_ioctl(struct inode *pino, int cmd, int arg);
......@@ -21,7 +22,7 @@ static ioctl_ptr ioctl_table[]={
NULL, /* nodev */
NULL, /* /dev/mem */
NULL, /* /dev/fd */
NULL, /* /dev/hd */
hd_ioctl, /* /dev/hd */
tty_ioctl, /* /dev/ttyx */
tty_ioctl, /* /dev/tty */
NULL, /* /dev/lp */
......
#
# 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
......@@ -6,6 +6,8 @@
#include <errno.h>
#include <fcntl.h>
#include <sys/dirent.h>
#include <sys/stat.h>
#include <linux/sched.h>
#include <linux/minix_fs.h>
......@@ -15,6 +17,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;
}
......@@ -13,15 +13,100 @@
#include <linux/mm.h>
#include <asm/system.h>
static int _bmap(struct inode * inode,int block,int create)
int sync_dev(int dev);
void minix_put_super(struct super_block *sb)
{
int i;
lock_super(sb);
sb->s_dev = 0;
for(i = 0 ; i < MINIX_I_MAP_SLOTS ; i++)
brelse(sb->s_imap[i]);
for(i = 0 ; i < MINIX_Z_MAP_SLOTS ; i++)
brelse(sb->s_zmap[i]);
free_super(sb);
return;
}
static struct super_operations minix_sops = {
minix_read_inode,
minix_put_super
};
struct super_block *minix_read_super(struct super_block *s,void *data)
{
struct buffer_head *bh;
int i,dev=s->s_dev,block;
lock_super(s);
if (!(bh = bread(dev,1))) {
s->s_dev=0;
free_super(s);
printk("bread failed\n");
return NULL;
}
*((struct minix_super_block *) s) =
*((struct minix_super_block *) bh->b_data);
brelse(bh);
if (s->s_magic != MINIX_SUPER_MAGIC) {
s->s_dev = 0;
free_super(s);
printk("magic match failed\n");
return NULL;
}
for (i=0;i < MINIX_I_MAP_SLOTS;i++)
s->s_imap[i] = NULL;
for (i=0;i < MINIX_Z_MAP_SLOTS;i++)
s->s_zmap[i] = NULL;
block=2;
for (i=0 ; i < s->s_imap_blocks ; i++)
if (s->s_imap[i]=bread(dev,block))
block++;
else
break;
for (i=0 ; i < s->s_zmap_blocks ; i++)
if (s->s_zmap[i]=bread(dev,block))
block++;
else
break;
if (block != 2+s->s_imap_blocks+s->s_zmap_blocks) {
for(i=0;i<MINIX_I_MAP_SLOTS;i++)
brelse(s->s_imap[i]);
for(i=0;i<MINIX_Z_MAP_SLOTS;i++)
brelse(s->s_zmap[i]);
s->s_dev=0;
free_super(s);
printk("block failed\n");
return NULL;
}
s->s_imap[0]->b_data[0] |= 1;
s->s_zmap[0]->b_data[0] |= 1;
free_super(s);
/* set up enough so that it can read an inode */
s->s_dev = dev;
s->s_op = &minix_sops;
if (!(s->s_mounted = iget(dev,MINIX_ROOT_INO))) {
s->s_dev=0;
printk("get root inode failed\n");
return NULL;
}
return s;
}
static int _minix_bmap(struct inode * inode,int block,int create)
{
struct buffer_head * bh;
int i;
if (block<0)
panic("_bmap: block<0");
if (block >= 7+512+512*512)
panic("_bmap: block>big");
if (block<0) {
printk("_minix_bmap: block<0");
return 0;
}
if (block >= 7+512+512*512) {
printk("_minix_bmap: block>big");
return 0;
}
if (block<7) {
if (create && !inode->i_data[block])
if (inode->i_data[block]=minix_new_block(inode->i_dev)) {
......@@ -83,12 +168,12 @@ static int _bmap(struct inode * inode,int block,int create)
int minix_bmap(struct inode * inode,int block)
{
return _bmap(inode,block,0);
return _minix_bmap(inode,block,0);
}
int minix_create_block(struct inode * inode, int block)
{
return _bmap(inode,block,1);
return _minix_bmap(inode,block,1);
}
void minix_read_inode(struct inode * inode)
......
......@@ -7,6 +7,12 @@
#include <linux/fs.h>
#include <linux/minix_fs.h>
void minix_put_inode(struct inode *inode)
{
minix_truncate(inode);
minix_free_inode(inode);
}
/*
* These are the low-level inode operations for minix filesystem inodes.
*/
......@@ -23,16 +29,21 @@ struct inode_operations minix_inode_operations = {
minix_readlink,
minix_open,
minix_release,
minix_follow_link
minix_follow_link,
minix_bmap,
minix_truncate,
minix_write_inode,
minix_put_inode
};
/*
* We have just NULL's here: the current defaults are ok for
* We have mostly NULL's here: the current defaults are ok for
* the minix filesystem.
*/
struct file_operations minix_file_operations = {
NULL, /* lseek */
NULL, /* read */
NULL /* write */
NULL, /* write */
minix_readdir
};
......@@ -15,10 +15,6 @@
#include <const.h>
#include <sys/stat.h>
extern int permission(struct inode * inode,int mask);
extern struct inode * _namei(const char * filename, struct inode * base,
int follow_links);
/*
* comment out this line if you want names > MINIX_NAME_LEN chars to be
* truncated. Else they will be disallowed.
......@@ -89,7 +85,7 @@ static struct buffer_head * minix_find_entry(struct inode * dir,
if ((char *)de >= BLOCK_SIZE+bh->b_data) {
brelse(bh);
bh = NULL;
if (!(block = bmap(dir,i/MINIX_DIR_ENTRIES_PER_BLOCK)) ||
if (!(block = minix_bmap(dir,i/MINIX_DIR_ENTRIES_PER_BLOCK)) ||
!(bh = bread(dir->i_dev,block))) {
i += MINIX_DIR_ENTRIES_PER_BLOCK;
continue;
......@@ -398,7 +394,7 @@ static int empty_dir(struct inode * inode)
while (nr<len) {
if ((void *) de >= (void *) (bh->b_data+BLOCK_SIZE)) {
brelse(bh);
block=bmap(inode,nr/MINIX_DIR_ENTRIES_PER_BLOCK);
block = minix_bmap(inode,nr/MINIX_DIR_ENTRIES_PER_BLOCK);
if (!block) {
nr += MINIX_DIR_ENTRIES_PER_BLOCK;
continue;
......
......@@ -9,7 +9,6 @@
*/
#include <linux/sched.h>
#include <linux/minix_fs.h>
#include <linux/kernel.h>
#include <asm/segment.h>
......@@ -249,7 +248,8 @@ int open_namei(const char * pathname, int flag, int mode,
}
inode->i_atime = CURRENT_TIME;
if (flag & O_TRUNC)
minix_truncate(inode);
if (inode->i_op && inode->i_op->truncate)
inode->i_op->truncate(inode);
*res_inode = inode;
return 0;
}
......@@ -270,7 +270,7 @@ int sys_mknod(const char * filename, int mode, int dev)
}
if (!permission(dir,MAY_WRITE)) {
iput(dir);
return -EPERM;
return -EACCES;
}
if (!dir->i_op || !dir->i_op->mknod) {
iput(dir);
......@@ -293,7 +293,7 @@ int sys_mkdir(const char * pathname, int mode)
}
if (!permission(dir,MAY_WRITE)) {
iput(dir);
return -EPERM;
return -EACCES;
}
if (!dir->i_op || !dir->i_op->mkdir) {
iput(dir);
......@@ -316,7 +316,7 @@ int sys_rmdir(const char * name)
}
if (!permission(dir,MAY_WRITE)) {
iput(dir);
return -EPERM;
return -EACCES;
}
if (!dir->i_op || !dir->i_op->rmdir) {
iput(dir);
......@@ -335,11 +335,11 @@ int sys_unlink(const char * name)
return -ENOENT;
if (!namelen) {
iput(dir);
return -ENOENT;
return -EPERM;
}
if (!permission(dir,MAY_WRITE)) {
iput(dir);
return -EPERM;
return -EACCES;
}
if (!dir->i_op || !dir->i_op->unlink) {
iput(dir);
......@@ -356,14 +356,14 @@ int sys_symlink(const char * oldname, const char * newname)
dir = dir_namei(newname,&namelen,&basename, NULL);
if (!dir)
return -EACCES;
return -ENOENT;
if (!namelen) {
iput(dir);
return -EPERM;
return -ENOENT;
}
if (!permission(dir,MAY_WRITE)) {
iput(dir);
return -EPERM;
return -EACCES;
}
if (!dir->i_op || !dir->i_op->symlink) {
iput(dir);
......
......@@ -29,6 +29,11 @@ int sys_utime(char * filename, struct utimbuf * times)
if (!(inode=namei(filename)))
return -ENOENT;
if (times) {
if (current->euid != inode->i_uid &&
!permission(inode,MAY_WRITE)) {
iput(inode);
return -EPERM;
}
actime = get_fs_long((unsigned long *) &times->actime);
modtime = get_fs_long((unsigned long *) &times->modtime);
} else
......
......@@ -41,7 +41,7 @@ int pipe_read(struct inode * inode, struct file * filp, char * buf, int count)
put_fs_byte(((char *)inode->i_size)[size++],buf++);
}
wake_up(& PIPE_WRITE_WAIT(*inode));
return read;
return read?read:-EAGAIN;
}
int pipe_write(struct inode * inode, struct file * filp, char * buf, int count)
......
......@@ -4,18 +4,39 @@
* (C) 1991 Linus Torvalds
*/
#include <sys/stat.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/dirent.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/minix_fs.h>
#include <asm/segment.h>
int sys_lseek(unsigned int fd,off_t offset, unsigned int origin)
/*
* 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;
}
......
......@@ -29,7 +29,26 @@ struct super_block super_block[NR_SUPER];
/* this is initialized in init/main.c */
int ROOT_DEV = 0;
static void lock_super(struct super_block * sb)
/* Move into include file later */
static struct file_system_type file_systems[] = {
{minix_read_super,"minix"},
{NULL,NULL}
};
/* end of include file */
struct file_system_type *get_fs_type(char *name)
{
int a;
for(a = 0 ; file_systems[a].read_super ; a++)
if (!strcmp(name,file_systems[a].name))
return(&file_systems[a]);
return(NULL);
}
void lock_super(struct super_block * sb)
{
cli();
while (sb->s_lock)
......@@ -38,7 +57,7 @@ static void lock_super(struct super_block * sb)
sti();
}
static void free_super(struct super_block * sb)
void free_super(struct super_block * sb)
{
cli();
sb->s_lock = 0;
......@@ -46,7 +65,7 @@ static void free_super(struct super_block * sb)
sti();
}
static void wait_on_super(struct super_block * sb)
void wait_on_super(struct super_block * sb)
{
cli();
while (sb->s_lock)
......@@ -75,7 +94,6 @@ struct super_block * get_super(int dev)
void put_super(int dev)
{
struct super_block * sb;
int i;
if (dev == ROOT_DEV) {
printk("root diskette changed: prepare for armageddon\n\r");
......@@ -87,27 +105,24 @@ void put_super(int dev)
printk("Mounted disk changed - tssk, tssk\n\r");
return;
}
lock_super(sb);
sb->s_dev = 0;
for(i=0;i<MINIX_I_MAP_SLOTS;i++)
brelse(sb->s_imap[i]);
for(i=0;i<MINIX_Z_MAP_SLOTS;i++)
brelse(sb->s_zmap[i]);
free_super(sb);
return;
if (sb->s_op && sb->s_op->put_super)
sb->s_op->put_super(sb);
}
static struct super_block * read_super(int dev)
static struct super_block * read_super(int dev,char *name,void *data)
{
struct super_block * s;
struct buffer_head * bh;
int i,block;
struct file_system_type *type;
if (!dev)
return NULL;
check_disk_change(dev);
if (s = get_super(dev))
return s;
if (!(type=get_fs_type(name))) {
printk("get fs type failed %s\n",name);
return NULL;
}
for (s = 0+super_block ;; s++) {
if (s >= NR_SUPER+super_block)
return NULL;
......@@ -115,53 +130,14 @@ static struct super_block * read_super(int dev)
break;
}
s->s_dev = dev;
s->s_mounted = NULL;
if (!type->read_super(s,data))
return(NULL);
s->s_dev = dev;
s->s_covered = NULL;
s->s_time = 0;
s->s_rd_only = 0;
s->s_dirt = 0;
lock_super(s);
if (!(bh = bread(dev,1))) {
s->s_dev=0;
free_super(s);
return NULL;
}
*((struct minix_super_block *) s) =
*((struct minix_super_block *) bh->b_data);
brelse(bh);
if (s->s_magic != MINIX_SUPER_MAGIC) {
s->s_dev = 0;
free_super(s);
return NULL;
}
for (i=0;i < MINIX_I_MAP_SLOTS;i++)
s->s_imap[i] = NULL;
for (i=0;i < MINIX_Z_MAP_SLOTS;i++)
s->s_zmap[i] = NULL;
block=2;
for (i=0 ; i < s->s_imap_blocks ; i++)
if (s->s_imap[i]=bread(dev,block))
block++;
else
break;
for (i=0 ; i < s->s_zmap_blocks ; i++)
if (s->s_zmap[i]=bread(dev,block))
block++;
else
break;
if (block != 2+s->s_imap_blocks+s->s_zmap_blocks) {
for(i=0;i<MINIX_I_MAP_SLOTS;i++)
brelse(s->s_imap[i]);
for(i=0;i<MINIX_Z_MAP_SLOTS;i++)
brelse(s->s_zmap[i]);
s->s_dev=0;
free_super(s);
return NULL;
}
s->s_imap[0]->b_data[0] |= 1;
s->s_zmap[0]->b_data[0] |= 1;
free_super(s);
return s;
return(s);
}
int sys_umount(char * dev_name)
......@@ -184,7 +160,7 @@ int sys_umount(char * dev_name)
return -ENOENT;
if (!sb->s_covered->i_mount)
printk("Mounted inode has i_mount=0\n");
for (inode=inode_table+0 ; inode<inode_table+NR_INODE ; inode++)
for (inode = inode_table+0 ; inode < inode_table+NR_INODE ; inode++)
if (inode->i_dev==dev && inode->i_count)
if (inode == sb->s_mounted && inode->i_count == 1)
continue;
......@@ -195,8 +171,8 @@ int sys_umount(char * dev_name)
sb->s_covered = NULL;
iput(sb->s_mounted);
sb->s_mounted = NULL;
put_super(dev);
sync_dev(dev);
put_super(dev);
sync_dev(dev);
return 0;
}
......@@ -224,25 +200,21 @@ int sys_mount(char * dev_name, char * dir_name, int rw_flag)
iput(dir_i);
return -EPERM;
}
if (!(sb=read_super(dev))) {
if (dir_i->i_mount) {
iput(dir_i);
return -EBUSY;
return -EPERM;
}
if (sb->s_covered) {
if (!(sb=read_super(dev,"minix",NULL))) {
iput(dir_i);
return -EBUSY;
}
if (dir_i->i_mount) {
iput(dir_i);
return -EPERM;
}
if (!(sb->s_mounted = iget(dev,MINIX_ROOT_INO))) {
if (sb->s_covered) {
iput(dir_i);
return -EPERM;
return -EBUSY;
}
sb->s_covered=dir_i;
dir_i->i_mount=1;
dir_i->i_dirt=1; /* NOTE! we don't iput(dir_i) */
sb->s_covered = dir_i;
dir_i->i_mount = 1;
dir_i->i_dirt = 1; /* NOTE! we don't iput(dir_i) */
return 0; /* we do that in umount */
}
......@@ -265,10 +237,13 @@ void mount_root(void)
p->s_lock = 0;
p->s_wait = NULL;
}
if (!(p=read_super(ROOT_DEV)))
if (!(p=read_super(ROOT_DEV,"minix",NULL)))
panic("Unable to mount root");
/*wait_for_keypress();
if (!(mi=iget(ROOT_DEV,MINIX_ROOT_INO)))
panic("Unable to read root i-node");
wait_for_keypress();*/
mi=p->s_mounted;
mi->i_count += 3 ; /* NOTE! it is logically used 4 times, not 1 */
p->s_mounted = p->s_covered = mi;
current->pwd = mi;
......
#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. */
......
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
#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
#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 <linux/config_rel.h>
#ifndef UTS_RELEASE
#define UTS_RELEASE "0.95c-0"
#endif
#include <linux/config_ver.h>
#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. */
......
#define UTS_RELEASE "0.95c-18"
#define UTS_VERSION "04/09/92"
......@@ -7,6 +7,7 @@
#define _FS_H
#include <sys/types.h>
#include <sys/dirent.h>
/* devices are as follows: (same as minix, so we can use the minix
* file system. These are major numbers.)
......@@ -134,12 +135,15 @@ struct super_block {
unsigned char s_lock;
unsigned char s_rd_only;
unsigned char s_dirt;
/* TUBE */
struct super_operations *s_op;
};
struct file_operations {
int (*lseek) (struct inode *, struct file *, off_t, int);
int (*read) (struct inode *, struct file *, char *, int);
int (*write) (struct inode *, struct file *, char *, int);
int (*readdir) (struct inode *, struct file *, struct dirent *);
};
struct inode_operations {
......@@ -156,8 +160,25 @@ struct inode_operations {
int (*open) (struct inode *, struct file *);
void (*release) (struct inode *, struct file *);
struct inode * (*follow_link) (struct inode *, struct inode *);
int (*bmap) (struct inode *,int);
void (*truncate) (struct inode *);
/* added by entropy */
void (*write_inode)(struct inode *inode);
void (*put_inode)(struct inode *inode);
};
struct super_operations {
void (*read_inode)(struct inode *inode);
void (*put_super)(struct super_block *sb);
};
struct file_system_type {
struct super_block *(*read_super)(struct super_block *sb,void *mode);
char *name;
};
extern struct file_system_type *get_fs_type(char *name);
extern struct inode inode_table[NR_INODE];
extern struct file file_table[NR_FILE];
extern struct super_block super_block[NR_SUPER];
......@@ -175,6 +196,9 @@ extern void wait_on(struct inode * inode);
extern int bmap(struct inode * inode,int block);
extern struct inode * namei(const char * pathname);
extern struct inode * lnamei(const char * pathname);
extern int permission(struct inode * inode,int mask);
extern struct inode * _namei(const char * filename, struct inode * base,
int follow_links);
extern int open_namei(const char * pathname, int flag, int mode,
struct inode ** res_inode);
extern void iput(struct inode * inode);
......@@ -195,13 +219,13 @@ extern struct super_block * get_super(int dev);
extern int ROOT_DEV;
extern void mount_root(void);
extern void lock_super(struct super_block * sb);
extern void free_super(struct super_block * sb);
extern int minix_file_read(struct inode *, struct file *, char *, int);
extern int pipe_read(struct inode *, struct file *, char *, int);
extern int char_read(struct inode *, struct file *, char *, int);
extern int block_read(struct inode *, struct file *, char *, int);
extern int minix_file_write(struct inode *, struct file *, char *, int);
extern int pipe_write(struct inode *, struct file *, char *, int);
extern int char_write(struct inode *, struct file *, char *, int);
extern int block_write(struct inode *, struct file *, char *, int);
......
......@@ -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
/*
$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 <errno.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <asm/io.h>
#include <asm/segment.h>
/*
* 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);
......@@ -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;
......
......@@ -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,}, \
{ \
......
......@@ -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);
......@@ -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[];
......
#ifndef _SYS_DIRENT_H
#define _SYS_DIRENT_H
#include <limits.h>
struct dirent {
long d_ino;
off_t d_off;
unsigned short d_reclen;
char d_name[NAME_MAX+1];
};
#endif
......@@ -50,6 +50,12 @@
#define _PC_VDISABLE 8
#define _PC_CHOWN_RESTRICTED 9
#if 0
/* XXX - <sys/stat.h> illegally <sys/types.h> already.
* The rest of these includes are also illegal (too much pollution).
*/
#include <sys/types.h>
#endif
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/times.h>
......@@ -148,7 +154,9 @@
#define __NR_uselib 86
#define __NR_swapon 87
#define __NR_reboot 88
#define __NR_readdir 89
/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
#define _syscall0(type,name) \
type name(void) \
{ \
......@@ -206,19 +214,26 @@ return -1; \
#endif /* __LIBRARY__ */
/* XXX - illegal. */
extern int errno;
int access(const char * filename, mode_t mode);
/* XXX - several non-POSIX functions here, and POSIX functions that are
* supposed to be declared elsewhere. Non-promotion of short types in
* prototypes may cause trouble. Arg names should be prefixed by
* underscores.
*/
int access(const char * filename, mode_t mode); /* XXX - short type */
int acct(const char * filename);
int alarm(int sec);
int brk(void * end_data_segment);
/* XXX - POSIX says unsigned alarm(unsigned sec) */
int alarm(int sec);
void * sbrk(ptrdiff_t increment);
int chdir(const char * filename);
int chmod(const char * filename, mode_t mode);
int chown(const char * filename, uid_t owner, gid_t group);
int chmod(const char * filename, mode_t mode); /* XXX - short type */
int chown(const char * filename, uid_t owner, gid_t group); /* XXX - shorts */
int chroot(const char * filename);
int close(int fildes);
int creat(const char * filename, mode_t mode);
int creat(const char * filename, mode_t mode); /* XXX - short type */
int dup(int fildes);
int execve(const char * filename, char ** argv, char ** envp);
int execv(const char * pathname, char ** argv);
......@@ -229,27 +244,28 @@ int execle(const char * pathname, char * arg0, ...);
volatile void exit(int status);
volatile void _exit(int status);
int fcntl(int fildes, int cmd, ...);
int fork(void);
int getpid(void);
int getuid(void);
int geteuid(void);
int getgid(void);
int getegid(void);
pid_t fork(void);
pid_t getpid(void);
uid_t getuid(void);
uid_t geteuid(void);
gid_t getgid(void);
gid_t getegid(void);
int ioctl(int fildes, int cmd, ...);
int kill(pid_t pid, int signal);
int link(const char * filename1, const char * filename2);
int lseek(int fildes, off_t offset, int origin);
int mknod(const char * filename, mode_t mode, dev_t dev);
off_t lseek(int fildes, off_t offset, int origin);
int mknod(const char * filename, mode_t mode, dev_t dev); /* XXX - shorts */
int mount(const char * specialfile, const char * dir, int rwflag);
int nice(int val);
int open(const char * filename, int flag, ...);
int pause(void);
int pipe(int * fildes);
/* XXX**2 - POSIX says unsigned count */
int read(int fildes, char * buf, off_t count);
int setpgrp(void);
int setpgid(pid_t pid,pid_t pgid);
int setuid(uid_t uid);
int setgid(gid_t gid);
int setpgid(pid_t pid,pid_t pgid); /* XXX - short types */
int setuid(uid_t uid); /* XXX - short type */
int setgid(gid_t gid); /* XXX - short type */
void (*signal(int sig, void (*fn)(int)))(int);
int stat(const char * filename, struct stat * stat_buf);
int fstat(int fildes, struct stat * stat_buf);
......@@ -266,6 +282,7 @@ int ustat(dev_t dev, struct ustat * ubuf);
int utime(const char * filename, struct utimbuf * times);
pid_t waitpid(pid_t pid,int * wait_stat,int options);
pid_t wait(int * wait_stat);
/* XXX**2 - POSIX says unsigned count */
int write(int fildes, const char * buf, off_t count);
int dup2(int oldfd, int newfd);
int getppid(void);
......
......@@ -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
......@@ -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 \
......
......@@ -78,10 +78,11 @@ extern int * blk_size[NR_BLK_DEV];
#define DEVICE_OFF(device) floppy_off(DEVICE_NR(device))
#elif (MAJOR_NR == 3)
/* harddisk */
/* harddisk: timeout is 6 seconds.. */
#define DEVICE_NAME "harddisk"
#define DEVICE_INTR do_hd
#define DEVICE_TIMEOUT HD_TIMER
#define TIMEOUT_VALUE 600
#define DEVICE_REQUEST do_hd_request
#define DEVICE_NR(device) (MINOR(device)>>6)
#define DEVICE_ON(device)
......@@ -101,10 +102,18 @@ void (*DEVICE_INTR)(void) = NULL;
#endif
#ifdef DEVICE_TIMEOUT
#define SET_INTR(x) if (DEVICE_INTR = (x)) { \
timer_table[DEVICE_TIMEOUT].expires = jiffies + 200; \
timer_active |= 1<<DEVICE_TIMEOUT; \
} else timer_active &= ~(1<<DEVICE_TIMEOUT)
#define SET_TIMER \
((timer_table[DEVICE_TIMEOUT].expires = jiffies + TIMEOUT_VALUE), \
(timer_active |= 1<<DEVICE_TIMEOUT))
#define CLEAR_TIMER \
timer_active &= ~(1<<DEVICE_TIMEOUT)
#define SET_INTR(x) \
if (DEVICE_INTR = (x)) \
SET_TIMER; \
else \
CLEAR_TIMER;
#else
......
......@@ -484,6 +484,8 @@ static void floppy_on_interrupt(void)
/* We cannot do a floppy-select, as that might sleep. We just force it */
selected = 1;
if (current_drive != (current_DOR & 3)) {
seek = 1;
current_track = NO_TRACK;
current_DOR &= 0xFC;
current_DOR |= current_drive;
outb(current_DOR,FD_DOR);
......
......@@ -16,6 +16,8 @@
* in the early extended-partition checks and added DM partitions
*/
#include <errno.h>
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/timer.h>
......@@ -43,7 +45,7 @@ static void recal_intr(void);
static void bad_rw_intr(void);
static int recalibrate = 0;
static int reset = 1;
static int reset = 0;
/*
* This struct defines the HD's and their types.
......@@ -77,28 +79,103 @@ extern void rd_load(void);
static unsigned int current_minor;
/*
* Create devices for each logical partition in an extended partition.
* The logical partitions form a linked list, with each entry being
* a partition table with two entries. The first entry
* is the real data partition (with a start relative to the partition
* table start). The second is a pointer to the next logical partition
* (with a start relative to the entire extended partition).
* We do not create a Linux partition for the partition tables, but
* only for the actual data partitions.
*/
static void extended_partition(unsigned int dev)
{
struct buffer_head *bh;
struct partition *p;
unsigned long first_sector, this_sector;
first_sector = hd[MINOR(dev)].start_sect;
this_sector = first_sector;
while (1) {
if ((current_minor & 0x3f) >= 60)
return;
if (!(bh = bread(dev,0))) {
printk("Unable to read partition table of device %04x\n",dev);
return;
}
/*
* This block is from a device that we're about to stomp on.
* So make sure nobody thinks this block is usable.
*/
bh->b_dirt=0;
bh->b_uptodate=0;
if (*(unsigned short *) (bh->b_data+510) == 0xAA55) {
p = 0x1BE + (void *)bh->b_data;
/*
* Process the first entry, which should be the real
* data partition.
*/
if (p->sys_ind == EXTENDED_PARTITION ||
!(hd[current_minor].nr_sects = p->nr_sects))
goto done; /* shouldn't happen */
hd[current_minor].start_sect = this_sector + p->start_sect;
printk(" Logical part %d start %d size %d end %d\n\r",
current_minor, hd[current_minor].start_sect,
hd[current_minor].nr_sects,
hd[current_minor].start_sect +
hd[current_minor].nr_sects);
current_minor++;
p++;
/*
* Process the second entry, which should be a link
* to the next logical partition. Create a minor
* for this just long enough to get the next partition
* table. The minor will be reused for the real
* data partition.
*/
if (p->sys_ind != EXTENDED_PARTITION ||
!(hd[current_minor].nr_sects = p->nr_sects))
goto done; /* no more logicals in this partition */
hd[current_minor].start_sect = first_sector + p->start_sect;
this_sector = first_sector + p->start_sect;
dev = 0x0300 | current_minor;
brelse(bh);
} else
goto done;
}
done:
brelse(bh);
}
static void check_partition(unsigned int dev)
{
int minor, i;
int i, minor = current_minor;
struct buffer_head *bh;
struct partition *p;
unsigned long first_sector;
first_sector = hd[MINOR(dev)].start_sect;
if (!(bh = bread(dev,0))) {
printk("Unable to read partition table of device %04x\n",dev);
return;
}
minor = current_minor;
printk("Drive %d:\n\r",minor >> 6);
current_minor += 4; /* first "extra" minor */
if (*(unsigned short *) (bh->b_data+510) == 0xAA55) {
p = 0x1BE + (void *)bh->b_data;
for (i=0 ; i<4 ; i++,p++) {
if (!(hd[i+minor].nr_sects = p->nr_sects))
for (i=1 ; i<=4 ; minor++,i++,p++) {
if (!(hd[minor].nr_sects = p->nr_sects))
continue;
hd[i+minor].start_sect = p->start_sect;
hd[minor].start_sect = first_sector + p->start_sect;
printk(" part %d start %d size %d end %d \n\r", i,
hd[minor].start_sect, hd[minor].nr_sects,
hd[minor].start_sect + hd[minor].nr_sects);
if ((current_minor & 0x3f) >= 60)
continue;
if (p->sys_ind == EXTENDED_PARTITION) {
current_minor += 4;
check_partition(0x0300 | (i+minor));
extended_partition(0x0300 | minor);
}
}
/*
......@@ -106,14 +183,20 @@ static void check_partition(unsigned int dev)
*/
if (*(unsigned short *) (bh->b_data+0xfc) == 0x55AA) {
p = 0x1BE + (void *)bh->b_data;
for (i=4; i<16; i++) {
for (i = 4 ; i < 16 ; i++, current_minor++) {
p--;
if ((current_minor & 0x3f) >= 60)
break;
if (!(hd[current_minor+4].start_sect = p->start_sect))
if (!(p->start_sect && p->nr_sects))
continue;
hd[current_minor+4].nr_sects = p->nr_sects;
current_minor++;
hd[current_minor].start_sect = p->start_sect;
hd[current_minor].nr_sects = p->nr_sects;
printk(" DM part %d start %d size %d end %d\n\r",
current_minor,
hd[current_minor].start_sect,
hd[current_minor].nr_sects,
hd[current_minor].start_sect +
hd[current_minor].nr_sects);
}
}
} else
......@@ -141,16 +224,6 @@ int sys_setup(void * BIOS)
hd_info[drive].sect = *(unsigned char *) (14+BIOS);
BIOS += 16;
}
if (hd_info[1].cyl)
NR_HD=2;
else
NR_HD=1;
#endif
for (i=0 ; i<NR_HD ; i++) {
hd[i<<6].start_sect = 0;
hd[i<<6].nr_sects = hd_info[i].head*
hd_info[i].sect*hd_info[i].cyl;
}
/*
We querry CMOS about hard disks : it could be that
......@@ -181,10 +254,14 @@ int sys_setup(void * BIOS)
NR_HD = 1;
else
NR_HD = 0;
for (i = NR_HD ; i < 2 ; i++) {
hd[i<<6].start_sect = 0;
hd[i<<6].nr_sects = 0;
#endif
for (i = 0 ; i < (MAX_HD<<6) ; i++) {
hd[i].start_sect = 0;
hd[i].nr_sects = 0;
}
for (i = 0 ; i < NR_HD ; i++)
hd[i<<6].nr_sects = hd_info[i].head*
hd_info[i].sect*hd_info[i].cyl;
for (drive=0 ; drive<NR_HD ; drive++) {
current_minor = 1+(drive<<6);
check_partition(0x0300+(drive<<6));
......@@ -252,7 +329,7 @@ static int drive_busy(void)
unsigned int i;
unsigned char c;
for (i = 0; i < 50000; i++) {
for (i = 0; i < 500000 ; i++) {
c = inb_p(HD_STATUS);
c &= (BUSY_STAT | READY_STAT | SEEK_STAT);
if (c == (READY_STAT | SEEK_STAT))
......@@ -299,15 +376,25 @@ static void reset_hd(void)
do_hd_request();
}
/*
* Ok, don't know what to do with the unexpected interrupts: on some machines
* doing a reset and a retry seems to result in an eternal loop. Right now I
* ignore it, and just set the timeout.
*/
void unexpected_hd_interrupt(void)
{
printk("Unexpected HD interrupt\n\r");
SET_TIMER;
#if 0
reset = 1;
do_hd_request();
#endif
}
static void bad_rw_intr(void)
{
if (!CURRENT)
return;
if (++CURRENT->errors >= MAX_ERRORS)
end_request(0);
if (CURRENT->errors > MAX_ERRORS/2)
......@@ -361,19 +448,24 @@ static void recal_intr(void)
do_hd_request();
}
/*
* This is another of the error-routines I don't know what to do with. The
* best idea seems to just set reset, and start all over again.
*/
static void hd_times_out(void)
{
do_hd = NULL;
reset = 1;
if (!CURRENT)
return;
printk("HD timeout");
printk("HD timeout\n\r");
cli();
if (++CURRENT->errors >= MAX_ERRORS)
end_request(0);
do_hd_request();
}
void do_hd_request(void)
static void do_hd_request(void)
{
int i,r;
unsigned int block,dev;
......@@ -435,3 +527,27 @@ void hd_init(void)
outb(inb_p(0xA1)&0xbf,0xA1);
timer_table[HD_TIMER].fn = hd_times_out;
}
int hd_ioctl(int dev, int cmd, int arg)
{
struct hd_geometry *loc = (void *) arg;
if (!loc)
return -EINVAL;
dev = MINOR(dev) >> 6;
if (dev >= NR_HD)
return -EINVAL;
switch (cmd) {
case HDIO_REQ:
put_fs_byte(hd_info[dev].head,
(char *) &loc->heads);
put_fs_byte(hd_info[dev].sect,
(char *) &loc->sectors);
put_fs_word(hd_info[dev].cyl,
(short *) &loc->cylinders);
return 0;
default:
return -EINVAL;
}
}
......@@ -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) {
......
......@@ -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
......@@ -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<<BLANK_TIMER);
if (console_blanked) {
timer_table[BLANK_TIMER].expires = 0;
......
......@@ -19,7 +19,6 @@
* KBD_UK for British extended keyboard
* KBD_DK for Danish keyboard
*/
#define KBD_FINNISH
.text
.globl _hard_reset_now
......
/*
$Header: /usr/src/linux/kernel/chr_drv/lp.c,v 1.9 1992/01/06 16:11:19
james_r_wiegand Exp james_r_wiegand $
*/
#define __LP_C__
#include <linux/lp.h>
#include <checkpoint.h>
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;
}
......@@ -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);
}
......
......@@ -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)
......
......@@ -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();
}
......@@ -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))
......
......@@ -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 ; i<NR_TASKS ; i++)
if (task[i]==p) {
task[i]=NULL;
if (task[i] == p) {
task[i] = NULL;
/* Update links */
if (p->p_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 @@ int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options)
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);
......
......@@ -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;
......
......@@ -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 \
......
/*
* 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 <linux/config.h>
#ifdef KERNEL_MATH_EMULATION
#include <signal.h>
......@@ -172,12 +170,10 @@ static void do_emu(struct info * info)
real_to_real(&tmp,&ST(0));
return;
case 0x1a:
fcom(PST(code & 7),&tmp);
real_to_real(&tmp,&ST(0));
fcom(PST(code & 7),PST(0));
return;
case 0x1b:
fcom(PST(code & 7),&tmp);
real_to_real(&tmp,&ST(0));
fcom(PST(code & 7),PST(0));
fpop();
return;
case 0x1c:
......@@ -201,7 +197,7 @@ static void do_emu(struct info * info)
return;
case 0x38:
fpush();
ST(0) = ST((code & 7)+1);
ST(0) = ST((code+1) & 7);
return;
case 0x39:
fxchg(&ST(0),&ST(code & 7));
......
/* ptrace.c */
/* By Ross Biro 1/23/92 */
/* edited by Linus Torvalds */
#include <linux/head.h>
#include <linux/kernel.h>
......@@ -22,9 +23,6 @@
/* set's the trap flag. */
#define TRAP_FLAG 0x100
/* check's for granularity. */
#define GRANULARITY 0x00800000
/*
* this is the number to subtract from the top of the stack. To find
* the local frame.
......@@ -51,8 +49,7 @@ static inline int get_task(int pid)
* the offset is how far from the base addr as stored in the TSS.
* this routine assumes that all the priviledged stacks are in our
* data space.
*/
*/
static inline int get_stack_long(struct task_struct *task, int offset)
{
unsigned char *stack;
......@@ -69,144 +66,158 @@ static inline int get_stack_long(struct task_struct *task, int offset)
* data space.
*/
static inline int put_stack_long(struct task_struct *task, int offset,
unsigned short data)
unsigned long data)
{
unsigned char * stack;
stack = (unsigned char *) task->tss.esp0;
stack += offset;
*(int *) stack = data;
*(unsigned long *) stack = data;
return 0;
}
/*
* this routine will get a word out of an arbitrary
* tasks data space. It likes to have the task number
* rather than the task pointer. Perhaps the number
* should be included in the pointer.
* This routine gets a long from any process space by following the page
* tables. NOTE! You should check that the long isn't on a page boundary,
* and that it is in the task area before calling this: this routine does
* no checking.
*
* NOTE2! This uses "tsk->tss.cr3" even though we know it's currently always
* zero. This routine shouldn't have to change when we make a better mm.
*/
/* seg = 0 if I space */
static inline int get_long(int tsk, long addr, unsigned seg, int *data)
static unsigned long get_long(struct task_struct * tsk,
unsigned long addr)
{
int i;
int limit;
int cur;
unsigned long address;
unsigned long page;
unsigned oldfs;
/* find the task number of the current task. */
for (i = 0; i < NR_TASKS ; i ++) {
if (task[i] == current) break;
addr += tsk->start_code;
repeat:
page = tsk->tss.cr3 + ((addr >> 20) & 0xffc);
page = *(unsigned long *) page;
if (page & PAGE_PRESENT) {
page &= 0xfffff000;
page += (addr >> 10) & 0xffc;
page = *((unsigned long *) page);
}
if (i == NR_TASKS) {
printk("PTRACE: Can't find current task\n");
do_exit(SIGSEGV);
}
cur = i;
/* we will need to check the readability of the segment
and then the byte in order to avoid segment violations. */
seg++;
limit = (task[tsk]->ldt[seg].a) & 0xffff;
/* this should be constant amound all of our segments, but we
had better check anyway. */
if (task[tsk]->ldt[seg].b & GRANULARITY)
limit = limit << 12;
if (limit <= addr+4)
return -EIO;
/* Now compute the address, and make sure that it is present. */
address = task[tsk]->start_code + addr;
page = *((unsigned long*) ((address >> 20) & 0xffc));
/* see if it is present. */
if (!(page & PAGE_PRESENT)) {
do_no_page(0, address, task[tsk]);
do_no_page(0,addr,tsk);
goto repeat;
}
oldfs = get_fs();
/* now convert seg to the right format. */
seg = (seg << 3) | 0x4;
cli(); /* we are about to change our ldt, we better do it
with interrupts off. Perhaps we should call schedule
first so that we won't be taking too much extra time. */
lldt(tsk);
set_fs(seg);
*data = get_fs_long((void *)addr); /* we are assuming kernel space
is in the gdt here. */
lldt(cur);
set_fs(oldfs);
sti();
return 0;
page &= 0xfffff000;
page += addr & 0xfff;
return *(unsigned long *) page;
}
/*
* this routine will get a word out of an arbitrary
* tasks data space. It likes to have the task number
* rather than the task pointer. Perhaps the number
* should be included in the pointer.
* This routine puts a long into any process space by following the page
* tables. NOTE! You should check that the long isn't on a page boundary,
* and that it is in the task area before calling this: this routine does
* no checking.
*/
/* seg = 0 if I space */
static inline int put_long(int tsk, long addr, int data, unsigned seg)
static void put_long(struct task_struct * tsk, unsigned long addr,
unsigned long data)
{
int i;
int limit;
unsigned oldfs;
unsigned long address;
unsigned long page;
int cur;
/* find the task number of the current task. */
for (i = 0; i < NR_TASKS ; i++) {
if (task[i] == current) break;
addr += tsk->start_code;
repeat:
page = tsk->tss.cr3 + ((addr >> 20) & 0xffc);
page = *(unsigned long *) page;
if (page & PAGE_PRESENT) {
page &= 0xfffff000;
page += (addr >> 10) & 0xffc;
page = *((unsigned long *) page);
}
if (!(page & PAGE_PRESENT)) {
do_no_page(0,addr,tsk);
goto repeat;
}
if (i == NR_TASKS) {
printk("PTRACE: Can't find current task\n");
do_exit(SIGSEGV);
if (!(page & PAGE_RW)) {
write_verify(addr);
goto repeat;
}
cur = i;
/* we will need to check the readability of the segment
and then the byte in order to avoid segment violations. */
seg++;
limit = (task[tsk]->ldt[seg].a) & 0xffff;
/* this should be constant amound all of our segments, but we
had better check anyway. */
if (task[tsk]->ldt[seg].b & GRANULARITY)
limit = limit << 12;
if (limit <= addr+4)
return -EIO;
page &= 0xfffff000;
page += addr & 0xfff;
*(unsigned long *) page = data;
}
/* Now compute the address, and make sure that it is present. */
address = task[tsk]->start_code + addr;
/*
* This routine checks the page boundaries, and that the offset is
* within the task area. It then calls get_long() to read a long.
*/
static int read_long(struct task_struct * tsk, unsigned long addr,
unsigned long * result)
{
unsigned long low,high;
page = *((unsigned long*) ((address >> 20) & 0xffc));
/* see if it is present. */
if (!(page & PAGE_PRESENT)) {
do_no_page(0, address, task[tsk]);
}
write_verify(address);
oldfs=get_fs();
/* now convert seg to the right format. */
seg = (seg << 3) | 0x4;
cli(); /* we are about to change our ldt, we better do it
with interrupts off. Perhaps we should call schedule
first so that we won't be taking too much extra time. */
lldt(tsk);
set_fs(seg);
put_fs_long(data,(void *)addr);
lldt(cur);
set_fs(oldfs);
sti();
if (addr > TASK_SIZE-4)
return -EIO;
if ((addr & 0xfff) > PAGE_SIZE-4) {
low = get_long(tsk,addr & 0xfffffffc);
high = get_long(tsk,(addr+4) & 0xfffffffc);
switch (addr & 3) {
case 1:
low >>= 8;
low |= high << 24;
break;
case 2:
low >>= 16;
low |= high << 16;
break;
case 3:
low >>= 24;
low |= high << 8;
break;
}
*result = low;
} else
*result = get_long(tsk,addr);
return 0;
}
/*
* This routine checks the page boundaries, and that the offset is
* within the task area. It then calls put_long() to write a long.
*/
static int write_long(struct task_struct * tsk, unsigned long addr,
unsigned long data)
{
unsigned long low,high;
if (addr > TASK_SIZE-4)
return -EIO;
if ((addr & 0xfff) > PAGE_SIZE-4) {
low = get_long(tsk,addr & 0xfffffffc);
high = get_long(tsk,(addr+4) & 0xfffffffc);
switch (addr & 3) {
case 0: /* shouldn't happen, but safety first */
low = data;
break;
case 1:
low &= 0x000000ff;
low |= data << 8;
high &= 0xffffff00;
high |= data >> 24;
break;
case 2:
low &= 0x0000ffff;
low |= data << 16;
high &= 0xffff0000;
high |= data >> 16;
break;
case 3:
low &= 0x00ffffff;
low |= data << 24;
high &= 0xff000000;
high |= data >> 8;
break;
}
put_long(tsk,addr & 0xfffffffc,low);
put_long(tsk,(addr+4) & 0xfffffffc,high);
} else
put_long(tsk,addr,data);
return 0;
}
/* Perform ptrace(request, pid, addr, data) syscall */
int sys_ptrace(unsigned long *buffer)
......@@ -244,7 +255,7 @@ int sys_ptrace(unsigned long *buffer)
case 2: {
int tmp,res;
res = get_long(childno, addr, 1, &tmp);
res = read_long(task[childno], addr, &tmp);
if (res < 0)
return res;
verify_area((void *) data, 4);
......@@ -267,21 +278,18 @@ int sys_ptrace(unsigned long *buffer)
/* when I and D space are seperate, this will have to be fixed. */
case 4: /* write the word at location addr. */
case 5:
if (put_long(childno, addr, data, 1))
return -EIO;
return 0;
return write_long(task[childno],addr,data);
case 6: /* write the word at location addr in the USER area */
addr = addr >> 2; /* temproary hack. */
if (addr < 0 || addr >= 17)
return -EIO;
return -EIO;
if (addr == ORIG_EAX)
return -EIO;
if (addr == EFL) { /* flags. */
data &= FLAG_MASK;
data |= get_stack_long(child, EFL*4-MAGICNUMBER) & ~FLAG_MASK;
}
if (put_stack_long(child, 4*addr-MAGICNUMBER, data))
return -EIO;
return 0;
......
......@@ -46,12 +46,21 @@ void show_task(int nr,struct task_struct * p)
void show_state(void)
{
static int lock = 0;
int i;
cli();
if (lock) {
sti();
return;
}
lock = 1;
sti();
printk("\rTask-info:\n\r");
for (i=0;i<NR_TASKS;i++)
for (i=0 ; i<NR_TASKS ; i++)
if (task[i])
show_task(i,task[i]);
lock = 0;
}
#define LATCH (1193180/HZ)
......@@ -296,7 +305,9 @@ static struct timer_list {
long jiffies;
void (*fn)();
struct timer_list * next;
} timer_list[TIME_REQUESTS], * next_timer = NULL;
} timer_list[TIME_REQUESTS] = { { 0, NULL, NULL }, };
static struct timer_list * next_timer = NULL;
void add_timer(long jiffies, void (*fn)(void))
{
......
......@@ -457,11 +457,15 @@ int sys_getrusage(int who, struct rusage *ru)
r.ru_utime.tv_usec = CT_TO_USECS(current->utime);
r.ru_stime.tv_sec = CT_TO_SECS(current->stime);
r.ru_stime.tv_usec = CT_TO_USECS(current->stime);
r.ru_minflt = current->min_flt;
r.ru_majflt = current->maj_flt;
} else {
r.ru_utime.tv_sec = CT_TO_SECS(current->cutime);
r.ru_utime.tv_usec = CT_TO_USECS(current->cutime);
r.ru_stime.tv_sec = CT_TO_SECS(current->cstime);
r.ru_stime.tv_usec = CT_TO_USECS(current->cstime);
r.ru_minflt = current->cmin_flt;
r.ru_majflt = current->cmaj_flt;
}
lp = (unsigned long *) &r;
lpend = (unsigned long *) (&r+1);
......
......@@ -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) \
......
#! /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
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
......@@ -165,6 +165,7 @@ int copy_page_tables(unsigned long from,unsigned long to,long size)
if (!(1 & this_page)) {
if (!(new_page = get_free_page()))
return -1;
++current->rss;
read_swap_page(this_page>>1, (char *) new_page);
*to_page_table = this_page;
*from_page_table = new_page | (PAGE_DIRTY | 7);
......@@ -316,6 +317,7 @@ void do_wp_page(unsigned long error_code,unsigned long address)
printk("Bad things happen: page error in do_wp_page\n\r");
do_exit(SIGSEGV);
}
++current->min_flt;
un_wp_page((unsigned long *)
(((address>>10) & 0xffc) + (0xfffff000 &
*((unsigned long *) ((address>>20) &0xffc)))));
......@@ -429,8 +431,8 @@ static int share_page(struct inode * inode, unsigned long address)
return 0;
}
void do_no_page(unsigned long error_code,
unsigned long address, struct task_struct *tsk)
void do_no_page(unsigned long error_code, unsigned long address,
struct task_struct *tsk)
{
static unsigned int last_checked = 0;
int nr[4];
......@@ -439,7 +441,7 @@ void do_no_page(unsigned long error_code,
int block,i;
struct inode * inode;
/* Trashing ? Make it interruptible, but don't penalize otherwise */
/* Thrashing ? Make it interruptible, but don't penalize otherwise */
for (i = 0; i < CHECK_LAST_NR; i++)
if ((address & 0xfffff000) == last_pages[i]) {
current->counter = 0;
......@@ -457,6 +459,7 @@ void do_no_page(unsigned long error_code,
printk("Bad things happen: nonexistent page error in do_no_page\n\r");
do_exit(SIGSEGV);
}
++tsk->rss;
page = *(unsigned long *) ((address >> 20) & 0xffc);
/* check the page directory: make a page dir entry if no such exists */
if (page & 1) {
......@@ -464,6 +467,7 @@ void do_no_page(unsigned long error_code,
page += (address >> 10) & 0xffc;
tmp = *(unsigned long *) page;
if (tmp && !(1 & tmp)) {
++tsk->maj_flt;
swap_in((unsigned long *) page);
return;
}
......@@ -488,12 +492,19 @@ void do_no_page(unsigned long error_code,
block = 0;
}
if (!inode) {
++tsk->min_flt;
if (tmp > tsk->brk && tsk == current &&
LIBRARY_OFFSET - tmp > tsk->rlim[RLIMIT_STACK].rlim_max)
do_exit(SIGSEGV);
get_empty_page(address);
return;
}
if (tsk == current)
if (share_page(inode,tmp))
return;
if (share_page(inode,tmp)) {
++tsk->min_flt;
return;
}
++tsk->maj_flt;
if (!(page = get_free_page()))
oom();
/* remember that 1 block is used for header */
......@@ -533,9 +544,17 @@ void mem_init(long start_mem, long end_mem)
void show_mem(void)
{
int i,j,k,free=0,total=0;
int shared=0;
int shared = 0;
unsigned long * pg_tbl;
static int lock = 0;
cli();
if (lock) {
sti();
return;
}
lock = 1;
sti();
printk("Mem-info:\n\r");
for(i=0 ; i<PAGING_PAGES ; i++) {
if (mem_map[i] == USED)
......@@ -576,6 +595,7 @@ void show_mem(void)
}
}
printk("Memory found: %d (%d)\n\r",free-shared,total);
lock = 0;
}
......
......@@ -183,8 +183,13 @@ int swap_out(void)
dir_entry++;
goto check_dir;
}
if (try_to_swap_out(page_entry + (unsigned long *) pg_table))
if (try_to_swap_out(page_entry + (unsigned long *) pg_table)) {
if (! task[dir_entry >> 4])
printk("swapping out page from non-existent task\n\r");
else
task[dir_entry >> 4]->rss--;
return 1;
}
goto check_table;
no_swap:
printk("Out of swap-memory\n\r");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment