Commit 57dabd37 authored by Linus Torvalds's avatar Linus Torvalds

Import 1.1.34

parent 5079f36d
VERSION = 1 VERSION = 1
PATCHLEVEL = 1 PATCHLEVEL = 1
SUBLEVEL = 33 SUBLEVEL = 34
all: Version zImage all: Version zImage
...@@ -79,9 +79,21 @@ endif ...@@ -79,9 +79,21 @@ endif
AS86 =as86 -0 -a AS86 =as86 -0 -a
LD86 =ld86 -0 LD86 =ld86 -0
#
# Set these to indicate how to link it..
#
# -zmagic:
#
#LOWLDFLAGS = -Ttext 0x1000
#HIGHLDFLAGS = -Ttext 0x100000
#
# -qmagic (we need to remove the 32 byte header for bootup purposes)
#
LOWLDFLAGS =-qmagic -Ttext 0xfe0
HIGHLDFLAGS =-qmagic -Ttext 0xfffe0
AS =as AS =as
LD =ld LD =ld
LDFLAGS =#-qmagic
HOSTCC =gcc HOSTCC =gcc
CC =gcc -D__KERNEL__ -I$(TOPDIR)/include CC =gcc -D__KERNEL__ -I$(TOPDIR)/include
MAKE =make MAKE =make
...@@ -156,7 +168,7 @@ init/main.o: $(CONFIGURE) init/main.c ...@@ -156,7 +168,7 @@ init/main.o: $(CONFIGURE) init/main.c
$(CC) $(CFLAGS) $(PROFILING) -c -o $*.o $< $(CC) $(CFLAGS) $(PROFILING) -c -o $*.o $<
tools/system: boot/head.o init/main.o tools/version.o linuxsubdirs tools/system: boot/head.o init/main.o tools/version.o linuxsubdirs
$(LD) $(LDFLAGS) -Ttext 1000 boot/head.o init/main.o tools/version.o \ $(LD) $(LOWLDFLAGS) boot/head.o init/main.o tools/version.o \
$(ARCHIVES) \ $(ARCHIVES) \
$(FILESYSTEMS) \ $(FILESYSTEMS) \
$(DRIVERS) \ $(DRIVERS) \
...@@ -201,7 +213,7 @@ zlilo: $(CONFIGURE) zImage ...@@ -201,7 +213,7 @@ zlilo: $(CONFIGURE) zImage
if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
tools/zSystem: boot/head.o init/main.o tools/version.o linuxsubdirs tools/zSystem: boot/head.o init/main.o tools/version.o linuxsubdirs
$(LD) $(LDFLAGS) -Ttext 100000 boot/head.o init/main.o tools/version.o \ $(LD) $(HIGHLDFLAGS) boot/head.o init/main.o tools/version.o \
$(ARCHIVES) \ $(ARCHIVES) \
$(FILESYSTEMS) \ $(FILESYSTEMS) \
$(DRIVERS) \ $(DRIVERS) \
......
...@@ -14,8 +14,8 @@ ...@@ -14,8 +14,8 @@
! Move PS/2 aux init code to psaux.c ! Move PS/2 aux init code to psaux.c
! (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92 ! (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92
! !
! some changes and additional features by Christoph Niemann, March 1993 ! some changes and additional features by Christoph Niemann,
! (niemann@rubdv15.ETDV.Ruhr-Uni-Bochum.De) ! March 1993/June 1994 (Christoph.Niemann@linux.org)
! !
! NOTE! These had better be the same as in bootsect.s! ! NOTE! These had better be the same as in bootsect.s!
...@@ -97,9 +97,11 @@ novga: mov [14],ax ...@@ -97,9 +97,11 @@ novga: mov [14],ax
mov ds,ax mov ds,ax
lds si,[4*0x41] lds si,[4*0x41]
mov ax,#INITSEG mov ax,#INITSEG
push ax
mov es,ax mov es,ax
mov di,#0x0080 mov di,#0x0080
mov cx,#0x10 mov cx,#0x10
push cx
cld cld
rep rep
movsb movsb
...@@ -109,11 +111,9 @@ novga: mov [14],ax ...@@ -109,11 +111,9 @@ novga: mov [14],ax
xor ax,ax ! clear ax xor ax,ax ! clear ax
mov ds,ax mov ds,ax
lds si,[4*0x46] lds si,[4*0x46]
mov ax,#INITSEG pop cx
mov es,ax pop es
mov di,#0x0090 mov di,#0x0090
mov cx,#0x10
cld
rep rep
movsb movsb
...@@ -159,7 +159,7 @@ no_psmouse: ...@@ -159,7 +159,7 @@ no_psmouse:
cld ! 'direction'=0, movs moves forward cld ! 'direction'=0, movs moves forward
do_move: do_move:
mov es,ax ! destination segment mov es,ax ! destination segment
add ax,#0x100 inc ah ! instead of add ax,#0x100
cmp ax,#0x9000 cmp ax,#0x9000
jz end_move jz end_move
mov ds,bx ! source segment mov ds,bx ! source segment
...@@ -246,7 +246,8 @@ end_move: ...@@ -246,7 +246,8 @@ end_move:
! Note that the short jump isn't strictly needed, althought there are ! Note that the short jump isn't strictly needed, althought there are
! reasons why it might be a good idea. It won't hurt in any case. ! reasons why it might be a good idea. It won't hurt in any case.
! !
mov ax,#0x0001 ! protected mode (PE) bit xor ax,ax
inc ax ! protected mode (PE) bit
lmsw ax ! This is it! lmsw ax ! This is it!
jmp flush_instr jmp flush_instr
flush_instr: flush_instr:
...@@ -394,33 +395,89 @@ vga28: ...@@ -394,33 +395,89 @@ vga28:
mov ax,#0x501c ! return 80x28 mov ax,#0x501c ! return 80x28
ret ret
/* svga modes */ /* svga modes */
!
! test for presence of an S3 VGA chip. The algorithm was taken
! from the SuperProbe package of XFree86 1.2.1
! report bugs to Christoph.Niemann@linux.org
!
svga: cld svga: cld
lea si,id9GXE ! Check for the #9GXE (jyanowit@orixa.mtholyoke.edu,thanks dlm40629@uxa.cso.uiuc.edu) mov cx,#0x0f35 ! we store some constants in cl/ch
mov di,#0x49 ! id string is at c000:049 mov dx,#0x03d4
mov cx,#0x11 ! length of "Graphics Power By" movb al,#0x38
repe call inidx
cmpsb mov bh,al ! store current value of CRT-register 0x38
jne of1280 mov ax,#0x0038
is9GXE: lea si,dsc9GXE ! table of descriptions of video modes for BIOS call outidx ! disable writing to special regs
lea di,mo9GXE ! table of sizes of video modes for my BIOS movb al,cl ! check wether we can write special reg 0x35
call inidx
movb bl,al ! save the current value of CRT reg 0x35
andb al,#0xf0 ! clear bits 0-3
movb ah,al
movb al,cl ! and write it to CRT reg 0x35
call outidx
call inidx ! now read it back
andb al,ch ! clear the upper 4 bits
jz s3_2 ! the first test failed. But we have a
movb ah,bl ! second chance
mov al,cl
call outidx
jmp s3_1 ! do the other tests
s3_2: mov ax,cx ! load ah with 0xf and al with 0x35
orb ah,bl ! set the upper 4 bits of ah with the orig value
call outidx ! write ...
call inidx ! ... and reread
andb al,cl ! turn off the upper 4 bits
push ax
movb ah,bl ! restore old value in register 0x35
movb al,cl
call outidx
pop ax
cmp al,ch ! setting lower 4 bits was successful => bad
je no_s3 ! writing is allowed => this is not an S3
s3_1: mov ax,#0x4838 ! allow writing to special regs by putting
call outidx ! magic number into CRT-register 0x38
movb al,cl ! check wether we can write special reg 0x35
call inidx
movb bl,al
andb al,#0xf0
movb ah,al
movb al,cl
call outidx
call inidx
andb al,ch
jnz no_s3 ! no, we can't write => no S3
mov ax,cx
orb ah,bl
call outidx
call inidx
andb al,ch
push ax
movb ah,bl ! restore old value in register 0x35
movb al,cl
call outidx
pop ax
cmp al,ch
jne no_s31 ! writing not possible => no S3
movb al,#0x30
call inidx ! now get the S3 id ...
lea di,idS3
mov cx,#0x10
repne
scasb
je no_s31
lea si,dsc_S3 ! table of descriptions of video modes for BIOS
lea di,mo_S3 ! table of sizes of video modes for my BIOS
movb ah,bh
movb al,#0x38
call outidx ! restore old value of CRT register 0x38
br selmod ! go ask for video mode br selmod ! go ask for video mode
of1280: cld no_s3: movb al,#0x35 ! restore CRT register 0x35
lea si,idf1280 ! Check for Orchid F1280 (dingbat@diku.dk) movb ah,bl
mov di,#0x10a ! id string is at c000:010a call outidx
mov cx,#0x21 ! length no_s31: movb ah,bh
repe movb al,#0x38
cmpsb call outidx ! restore old value of CRT register 0x38
jne nf1280
isVRAM: lea si,dscf1280
lea di,mof1280
br selmod
nf1280: lea si,idVRAM
mov di,#0x10a
mov cx,#0x0c
repe
cmpsb
je isVRAM
cld
lea si,idati ! Check ATI 'clues' lea si,idati ! Check ATI 'clues'
mov di,#0x31 mov di,#0x31
mov cx,#0x09 mov cx,#0x09
...@@ -710,6 +767,29 @@ gotmode: xor ah,ah ...@@ -710,6 +767,29 @@ gotmode: xor ah,ah
pop ds pop ds
ret ret
! Routine to write al into a VGA-register that is
! accessed via an index register
!
! dx contains the address of the index register
! al contains the index
! ah contains the value to write to the data register (dx + 1)
!
! no registers are changed
outidx: out dx,al
push ax
mov al,ah
inc dx
out dx,al
dec dx
pop ax
ret
inidx: out dx,al
inc dx
in al,dx
dec dx
ret
! Routine to print asciiz-string at DS:SI ! Routine to print asciiz-string at DS:SI
prtstr: lodsb prtstr: lodsb
...@@ -817,9 +897,8 @@ idcandt: .byte 0xa5 ...@@ -817,9 +897,8 @@ idcandt: .byte 0xa5
idgenoa: .byte 0x77, 0x00, 0x99, 0x66 idgenoa: .byte 0x77, 0x00, 0x99, 0x66
idparadise: .ascii "VGA=" idparadise: .ascii "VGA="
idoakvga: .ascii "OAK VGA " idoakvga: .ascii "OAK VGA "
idf1280: .ascii "Orchid Technology Fahrenheit 1280" idS3: .byte 0x81, 0x82, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95
id9GXE: .ascii "Graphics Power By" .byte 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xb0
idVRAM: .ascii "Stealth VRAM"
! Manufacturer: Numofmodes+2: Mode: ! Manufacturer: Numofmodes+2: Mode:
! Number of modes is the number of chip-specific svga modes plus the extended ! Number of modes is the number of chip-specific svga modes plus the extended
...@@ -836,8 +915,7 @@ motrident: .byte 0x09, 0x50, 0x51, 0x52, 0x57, 0x58, 0x59, 0x5a ...@@ -836,8 +915,7 @@ motrident: .byte 0x09, 0x50, 0x51, 0x52, 0x57, 0x58, 0x59, 0x5a
motseng: .byte 0x07, 0x26, 0x2a, 0x23, 0x24, 0x22 motseng: .byte 0x07, 0x26, 0x2a, 0x23, 0x24, 0x22
movideo7: .byte 0x08, 0x40, 0x43, 0x44, 0x41, 0x42, 0x45 movideo7: .byte 0x08, 0x40, 0x43, 0x44, 0x41, 0x42, 0x45
mooakvga: .byte 0x08, 0x00, 0x07, 0x4e, 0x4f, 0x50, 0x51 mooakvga: .byte 0x08, 0x00, 0x07, 0x4e, 0x4f, 0x50, 0x51
mo9GXE: .byte 0x04, 0x54, 0x55 mo_S3: .byte 0x04, 0x54, 0x55
mof1280: .byte 0x04, 0x54, 0x55
mounknown: .byte 0x02 mounknown: .byte 0x02
! msb = Cols lsb = Rows: ! msb = Cols lsb = Rows:
...@@ -855,8 +933,7 @@ dsctrident: .word 0x5032, 0x501c, 0x501e, 0x502b, 0x503c, 0x8419, 0x841e, 0x842 ...@@ -855,8 +933,7 @@ dsctrident: .word 0x5032, 0x501c, 0x501e, 0x502b, 0x503c, 0x8419, 0x841e, 0x842
dsctseng: .word 0x5032, 0x501c, 0x503c, 0x6428, 0x8419, 0x841c, 0x842c dsctseng: .word 0x5032, 0x501c, 0x503c, 0x6428, 0x8419, 0x841c, 0x842c
dscvideo7: .word 0x5032, 0x501c, 0x502b, 0x503c, 0x643c, 0x8419, 0x842c, 0x841c dscvideo7: .word 0x5032, 0x501c, 0x502b, 0x503c, 0x643c, 0x8419, 0x842c, 0x841c
dscoakvga: .word 0x5032, 0x501c, 0x2819, 0x5019, 0x503c, 0x843c, 0x8419, 0x842b dscoakvga: .word 0x5032, 0x501c, 0x2819, 0x5019, 0x503c, 0x843c, 0x8419, 0x842b
dscf1280: .word 0x5032, 0x501c, 0x842b, 0x8419 dsc_S3: .word 0x5032, 0x501c, 0x842b, 0x8419
dsc9GXE: .word 0x5032, 0x501c, 0x842b, 0x8419
dsunknown: .word 0x5032, 0x501c dsunknown: .word 0x5032, 0x501c
modesave: .word SVGA_MODE modesave: .word SVGA_MODE
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* and for "no-sound" interfaces like Lasermate and the * and for "no-sound" interfaces like Lasermate and the
* Panasonic CI-101P. * Panasonic CI-101P.
* *
* NOTE: This is release 2.3. * NOTE: This is release 2.4.
* It works with my SbPro & drive CR-521 V2.11 from 2/92 * It works with my SbPro & drive CR-521 V2.11 from 2/92
* and with the new CR-562-B V0.75 on a "naked" Panasonic * and with the new CR-562-B V0.75 on a "naked" Panasonic
* CI-101P interface. And vice versa. * CI-101P interface. And vice versa.
...@@ -117,6 +117,9 @@ ...@@ -117,6 +117,9 @@
* 2.3 Let "door lock" and "eject" live together. * 2.3 Let "door lock" and "eject" live together.
* Implemented "close tray" (done automatically during open). * Implemented "close tray" (done automatically during open).
* *
* 2.4 Use different names for device registering.
*
*
* TODO * TODO
* *
* disk change detection * disk change detection
...@@ -192,7 +195,7 @@ ...@@ -192,7 +195,7 @@
#include "blk.h" #include "blk.h"
#define VERSION "2.3 Eberhard Moenkeberg <emoenke@gwdg.de>" #define VERSION "2.4 Eberhard Moenkeberg <emoenke@gwdg.de>"
#define SBPCD_DEBUG #define SBPCD_DEBUG
...@@ -397,6 +400,18 @@ static char *str_sb = "SoundBlaster"; ...@@ -397,6 +400,18 @@ static char *str_sb = "SoundBlaster";
static char *str_lm = "LaserMate"; static char *str_lm = "LaserMate";
static char *str_sp = "SPEA"; static char *str_sp = "SPEA";
char *type; char *type;
#if !(SBPCD_ISSUE-1)
static char *major_name="sbpcd";
#endif
#if !(SBPCD_ISSUE-2)
static char *major_name="sbpcd2";
#endif
#if !(SBPCD_ISSUE-3)
static char *major_name="sbpcd3";
#endif
#if !(SBPCD_ISSUE-4)
static char *major_name="sbpcd4";
#endif
/*==========================================================================*/ /*==========================================================================*/
...@@ -2840,7 +2855,6 @@ static int sbpcd_ioctl(struct inode *inode, struct file *file, u_int cmd, ...@@ -2840,7 +2855,6 @@ static int sbpcd_ioctl(struct inode *inode, struct file *file, u_int cmd,
/*==========================================================================*/ /*==========================================================================*/
/* /*
* Take care of the different block sizes between cdrom and Linux. * Take care of the different block sizes between cdrom and Linux.
* When Linux gets variable block sizes this will probably go away.
*/ */
static void sbp_transfer(void) static void sbp_transfer(void)
{ {
...@@ -3551,7 +3565,7 @@ unsigned long SBPCD_INIT(u_long mem_start, u_long mem_end) ...@@ -3551,7 +3565,7 @@ unsigned long SBPCD_INIT(u_long mem_start, u_long mem_end)
OUT(MIXER_data,0xCC); /* one nibble per channel */ OUT(MIXER_data,0xCC); /* one nibble per channel */
} }
if (register_blkdev(MAJOR_NR, "sbpcd", &sbpcd_fops) != 0) if (register_blkdev(MAJOR_NR, major_name, &sbpcd_fops) != 0)
{ {
printk("SBPCD: Can't get MAJOR %d for Matsushita CDROM\n", MAJOR_NR); printk("SBPCD: Can't get MAJOR %d for Matsushita CDROM\n", MAJOR_NR);
#if PRINTK_BUG #if PRINTK_BUG
......
...@@ -21,7 +21,7 @@ Space.o: Space.c ../../include/linux/autoconf.h ...@@ -21,7 +21,7 @@ Space.o: Space.c ../../include/linux/autoconf.h
net_init.o: ../../include/linux/autoconf.h net_init.o: ../../include/linux/autoconf.h
ifdef CONFIG_SK_G16 ifdef CONFIG_SK_G16
NETDRV_OBJS := $(NETDRV_OBJS) net.a(sk_g16.o) NETDRV_OBJS := $(NETDRV_OBJS) sk_g16.o
endif endif
ifdef CONFIG_WD80x3 ifdef CONFIG_WD80x3
...@@ -53,7 +53,7 @@ hp.o: hp.c CONFIG ...@@ -53,7 +53,7 @@ hp.o: hp.c CONFIG
endif endif
ifdef CONFIG_HPLAN_PLUS ifdef CONFIG_HPLAN_PLUS
NETDRV_OBJS := $(NETDRV_OBJS) net.a(hp-plus.o) NETDRV_OBJS := $(NETDRV_OBJS) hp-plus.o
CONFIG_8390 = CONFIG_8390 CONFIG_8390 = CONFIG_8390
endif endif
...@@ -104,7 +104,7 @@ de600.o: de600.c CONFIG ...@@ -104,7 +104,7 @@ de600.o: de600.c CONFIG
$(CC) $(CPPFLAGS) $(CFLAGS) $(DE600_OPTS) -c $< $(CC) $(CPPFLAGS) $(CFLAGS) $(DE600_OPTS) -c $<
ifdef CONFIG_DE620 ifdef CONFIG_DE620
NETDRV_OBJS := $(NETDRV_OBJS) net.a(de620.o) NETDRV_OBJS := $(NETDRV_OBJS) de620.o
endif endif
de620.o: de620.c CONFIG de620.o: de620.c CONFIG
$(CC) $(CPPFLAGS) $(CFLAGS) $(DE620_OPTS) -c $< $(CC) $(CPPFLAGS) $(CFLAGS) $(DE620_OPTS) -c $<
...@@ -155,7 +155,7 @@ NETDRV_OBJS := $(NETDRV_OBJS) ac3200.o ...@@ -155,7 +155,7 @@ NETDRV_OBJS := $(NETDRV_OBJS) ac3200.o
CONFIG_8390 = CONFIG_8390 CONFIG_8390 = CONFIG_8390
endif endif
ifdef CONFIG_APRICOT ifdef CONFIG_APRICOT
NETDRV_OBJS := $(NETDRV_OBJS) net.a(apricot.o) NETDRV_OBJS := $(NETDRV_OBJS) apricot.o
endif endif
ifdef CONFIG_8390 ifdef CONFIG_8390
......
This diff is collapsed.
...@@ -941,8 +941,8 @@ static int plip_config(struct device *dev, struct ifmap *map) ...@@ -941,8 +941,8 @@ static int plip_config(struct device *dev, struct ifmap *map)
static int plip_ioctl(struct device *dev, struct ifreq *rq) static int plip_ioctl(struct device *dev, struct ifreq *rq)
{ {
struct net_local *nl=(struct net_local *)dev->priv; struct net_local *nl = (struct net_local *) dev->priv;
struct plipconf *pc=(struct plipconf *)rq->ifr_data; struct plipconf *pc = (struct plipconf *) &rq->ifr_data;
switch(pc->pcmd) switch(pc->pcmd)
{ {
......
...@@ -1113,14 +1113,14 @@ __asm__ __volatile__("rep ; movsl": \ ...@@ -1113,14 +1113,14 @@ __asm__ __volatile__("rep ; movsl": \
* etc. This also allows us to optimize memory usage by sharing code pages * etc. This also allows us to optimize memory usage by sharing code pages
* and filesystem buffers.. * and filesystem buffers..
*/ */
unsigned long bread_page(unsigned long address, dev_t dev, int b[], int size, int share) unsigned long bread_page(unsigned long address, dev_t dev, int b[], int size, int no_share)
{ {
struct buffer_head * bh[8]; struct buffer_head * bh[8];
unsigned long where; unsigned long where;
int i, j; int i, j;
if (share) { if (!no_share) {
where = try_to_share_buffers(address,dev,b,size); where = try_to_share_buffers(address, dev, b, size);
if (where) if (where)
return where; return where;
} }
...@@ -1132,14 +1132,14 @@ unsigned long bread_page(unsigned long address, dev_t dev, int b[], int size, in ...@@ -1132,14 +1132,14 @@ unsigned long bread_page(unsigned long address, dev_t dev, int b[], int size, in
} }
read_buffers(bh,i); read_buffers(bh,i);
where = address; where = address;
for (i=0, j=0; j<PAGE_SIZE ; i++, j += size,address += size) { for (i=0, j=0; j<PAGE_SIZE ; i++, j += size, where += size) {
if (bh[i]) { if (bh[i]) {
if (bh[i]->b_uptodate) if (bh[i]->b_uptodate)
COPYBLK(size, (unsigned long) bh[i]->b_data,address); COPYBLK(size, (unsigned long) bh[i]->b_data, where);
brelse(bh[i]); brelse(bh[i]);
} }
} }
return where; return address;
} }
/* /*
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
* Fill in the supplied page for mmap * Fill in the supplied page for mmap
*/ */
static unsigned long nfs_file_mmap_nopage(struct vm_area_struct * area, static unsigned long nfs_file_mmap_nopage(struct vm_area_struct * area,
unsigned long address, unsigned long page, int error_code) unsigned long address, unsigned long page, int no_share)
{ {
struct inode * inode = area->vm_inode; struct inode * inode = area->vm_inode;
unsigned int clear; unsigned int clear;
......
...@@ -444,7 +444,7 @@ extern void ll_rw_swap_file(int rw, int dev, unsigned int *b, int nb, char *buff ...@@ -444,7 +444,7 @@ extern void ll_rw_swap_file(int rw, int dev, unsigned int *b, int nb, char *buff
extern void brelse(struct buffer_head * buf); extern void brelse(struct buffer_head * buf);
extern void set_blocksize(dev_t dev, int size); extern void set_blocksize(dev_t dev, int size);
extern struct buffer_head * bread(dev_t dev, int block, int size); extern struct buffer_head * bread(dev_t dev, int block, int size);
extern unsigned long bread_page(unsigned long addr,dev_t dev,int b[],int size,int share); extern unsigned long bread_page(unsigned long addr,dev_t dev,int b[],int size,int no_share);
extern struct buffer_head * breada(dev_t dev,int block, int size, extern struct buffer_head * breada(dev_t dev,int block, int size,
unsigned int pos, unsigned int filesize); unsigned int pos, unsigned int filesize);
extern void put_super(dev_t dev); extern void put_super(dev_t dev);
......
...@@ -228,9 +228,14 @@ extern void shm_no_page (ulong *); ...@@ -228,9 +228,14 @@ extern void shm_no_page (ulong *);
/* swap cache stuff (in swap.c) */ /* swap cache stuff (in swap.c) */
extern unsigned long * swap_cache; extern unsigned long * swap_cache;
extern inline unsigned long in_swap_cache (unsigned long addr) extern inline unsigned long in_swap_cache(unsigned long addr)
{ {
return swap_cache[addr >> PAGE_SHIFT]; return swap_cache[addr >> PAGE_SHIFT];
} }
extern inline void swap_cache_invalidate(unsigned long addr)
{
swap_cache[addr >> PAGE_SHIFT] = 0;
}
#endif #endif
...@@ -157,7 +157,7 @@ static struct vm_area_struct * find_vma(struct task_struct * tsk, unsigned long ...@@ -157,7 +157,7 @@ static struct vm_area_struct * find_vma(struct task_struct * tsk, unsigned long
struct vm_area_struct * vma; struct vm_area_struct * vma;
addr &= PAGE_MASK; addr &= PAGE_MASK;
for (vma = current->mm->mmap ; ; vma = vma->vm_next) { for (vma = tsk->mm->mmap ; ; vma = vma->vm_next) {
if (!vma) if (!vma)
return NULL; return NULL;
if (vma->vm_end > addr) if (vma->vm_end > addr)
......
...@@ -263,11 +263,17 @@ int copy_page_tables(struct task_struct * tsk) ...@@ -263,11 +263,17 @@ int copy_page_tables(struct task_struct * tsk)
*new_page_table = swap_duplicate(pg); *new_page_table = swap_duplicate(pg);
continue; continue;
} }
if ((pg & (PAGE_RW | PAGE_COW)) == (PAGE_RW | PAGE_COW)) if (pg > high_memory || (mem_map[MAP_NR(pg)] & MAP_PAGE_RESERVED)) {
*new_page_table = pg;
continue;
}
if (pg & PAGE_COW)
pg &= ~PAGE_RW; pg &= ~PAGE_RW;
if (in_swap_cache(pg)) {
swap_cache_invalidate(pg);
pg |= PAGE_DIRTY;
}
*new_page_table = pg; *new_page_table = pg;
if (mem_map[MAP_NR(pg)] & MAP_PAGE_RESERVED)
continue;
*old_page_table = pg; *old_page_table = pg;
mem_map[MAP_NR(pg)]++; mem_map[MAP_NR(pg)]++;
} }
...@@ -730,9 +736,6 @@ static int try_to_share(unsigned long to_address, struct vm_area_struct * to_are ...@@ -730,9 +736,6 @@ static int try_to_share(unsigned long to_address, struct vm_area_struct * to_are
/* if it is private, it must be clean to be shared */ /* if it is private, it must be clean to be shared */
if ((from_area->vm_page_prot & PAGE_COW) && (from & PAGE_DIRTY)) if ((from_area->vm_page_prot & PAGE_COW) && (from & PAGE_DIRTY))
return 0; return 0;
/* the swap caching doesn't really handle shared pages.. */
if (in_swap_cache(from))
return 0;
/* is the page reasonable at all? */ /* is the page reasonable at all? */
if (from >= high_memory) if (from >= high_memory)
return 0; return 0;
...@@ -748,14 +751,26 @@ static int try_to_share(unsigned long to_address, struct vm_area_struct * to_are ...@@ -748,14 +751,26 @@ static int try_to_share(unsigned long to_address, struct vm_area_struct * to_are
return 0; return 0;
/* do we copy? */ /* do we copy? */
if (newpage) { if (newpage) {
if (in_swap_cache(from)) { /* implies PAGE_DIRTY */
if (from_area->vm_page_prot & PAGE_COW)
return 0;
}
copy_page((from & PAGE_MASK), newpage); copy_page((from & PAGE_MASK), newpage);
*(unsigned long *) to_page = newpage | to_area->vm_page_prot; *(unsigned long *) to_page = newpage | to_area->vm_page_prot;
return 1; return 1;
} }
/* just share them.. */ /* do a final swap-cache test before sharing them.. */
if (in_swap_cache(from)) {
if (from_area->vm_page_prot & PAGE_COW)
return 0;
from |= PAGE_DIRTY;
*(unsigned long *) from_page = from;
swap_cache_invalidate(from);
invalidate();
}
mem_map[MAP_NR(from)]++; mem_map[MAP_NR(from)]++;
/* fill in the 'to' field, checking for COW-stuff */ /* fill in the 'to' field, checking for COW-stuff */
to = (from & PAGE_MASK) | to_area->vm_page_prot; to = (from & (PAGE_MASK | PAGE_DIRTY)) | to_area->vm_page_prot;
if (to & PAGE_COW) if (to & PAGE_COW)
to &= ~PAGE_RW; to &= ~PAGE_RW;
*(unsigned long *) to_page = to; *(unsigned long *) to_page = to;
...@@ -764,7 +779,7 @@ static int try_to_share(unsigned long to_address, struct vm_area_struct * to_are ...@@ -764,7 +779,7 @@ static int try_to_share(unsigned long to_address, struct vm_area_struct * to_are
return 1; return 1;
if (!(from_area->vm_page_prot & PAGE_COW)) if (!(from_area->vm_page_prot & PAGE_COW))
return 1; return 1;
/* ok, need to mark it read-only, so invalidate aany possible old TB entry */ /* ok, need to mark it read-only, so invalidate any possible old TB entry */
from &= ~PAGE_RW; from &= ~PAGE_RW;
*(unsigned long *) from_page = from; *(unsigned long *) from_page = from;
invalidate(); invalidate();
...@@ -923,13 +938,24 @@ void do_no_page(struct vm_area_struct * vma, unsigned long address, ...@@ -923,13 +938,24 @@ void do_no_page(struct vm_area_struct * vma, unsigned long address,
} }
++vma->vm_task->mm->maj_flt; ++vma->vm_task->mm->maj_flt;
++vma->vm_task->mm->rss; ++vma->vm_task->mm->rss;
page = vma->vm_ops->nopage(vma, address, page, error_code); prot = vma->vm_page_prot;
/*
* The fourth argument is "no_share", which tells the low-level code
* to copy, not share the page even if sharing is possible. It's
* essentially an early COW detection ("moo at 5 AM").
*/
page = vma->vm_ops->nopage(vma, address, page, (error_code & PAGE_RW) && (prot & PAGE_COW));
if (share_page(vma, address, error_code, 0)) { if (share_page(vma, address, error_code, 0)) {
free_page(page); free_page(page);
return; return;
} }
prot = vma->vm_page_prot; /*
if ((prot & PAGE_COW) && mem_map[MAP_NR(page)] > 1) * This silly early PAGE_DIRTY setting removes a race
* due to the bad i386 page protection.
*/
if (error_code & PAGE_RW) {
prot |= PAGE_DIRTY; /* can't be COW-shared: see "no_share" above */
} else if ((prot & PAGE_COW) && mem_map[MAP_NR(page)] > 1)
prot &= ~PAGE_RW; prot &= ~PAGE_RW;
if (put_page(vma->vm_task, page, address, prot)) if (put_page(vma->vm_task, page, address, prot))
return; return;
...@@ -1251,25 +1277,29 @@ void si_meminfo(struct sysinfo *val) ...@@ -1251,25 +1277,29 @@ void si_meminfo(struct sysinfo *val)
} }
/* This handles a generic mmap of a disk file */ /*
* This handles a generic mmap of a disk file.
*/
static unsigned long file_mmap_nopage(struct vm_area_struct * area, unsigned long address, static unsigned long file_mmap_nopage(struct vm_area_struct * area, unsigned long address,
unsigned long page, int error_code) unsigned long page, int no_share)
{ {
struct inode * inode = area->vm_inode; struct inode * inode = area->vm_inode;
unsigned int block; unsigned int block;
int nr[8]; int nr[8];
int i, j; int i, *p;
int prot = area->vm_page_prot;
address &= PAGE_MASK; address &= PAGE_MASK;
block = address - area->vm_start + area->vm_offset; block = address - area->vm_start + area->vm_offset;
block >>= inode->i_sb->s_blocksize_bits; block >>= inode->i_sb->s_blocksize_bits;
i = PAGE_SIZE >> inode->i_sb->s_blocksize_bits;
for (i=0, j=0; i< PAGE_SIZE ; j++, block++, i += inode->i_sb->s_blocksize) p = nr;
nr[j] = bmap(inode,block); do {
if (error_code & PAGE_RW) *p = bmap(inode,block);
prot |= PAGE_RW | PAGE_DIRTY; i--;
return bread_page(page, inode->i_dev, nr, inode->i_sb->s_blocksize, !(error_code & PAGE_RW)); block++;
p++;
} while (i > 0);
return bread_page(page, inode->i_dev, nr, inode->i_sb->s_blocksize, no_share);
} }
struct vm_operations_struct file_mmap = { struct vm_operations_struct file_mmap = {
......
...@@ -344,21 +344,13 @@ static inline int try_to_swap_out(unsigned long * table_ptr) ...@@ -344,21 +344,13 @@ static inline int try_to_swap_out(unsigned long * table_ptr)
} }
if ((entry = find_in_swap_cache(page))) { if ((entry = find_in_swap_cache(page))) {
*table_ptr |= PAGE_DIRTY;
if (mem_map[MAP_NR(page)] != 1) { if (mem_map[MAP_NR(page)] != 1) {
*table_ptr |= PAGE_DIRTY;
printk("Aiee.. duplicated cached swap-cache entry\n");
return 0; return 0;
} }
if (!entry) { *table_ptr = entry;
if (!(entry = get_swap_page())) { invalidate();
return 0;
}
*table_ptr = entry;
invalidate();
write_swap_page(entry, (char *) (page & PAGE_MASK));
} else {
*table_ptr = entry;
invalidate();
}
free_page(page & PAGE_MASK); free_page(page & PAGE_MASK);
return 1; return 1;
} }
...@@ -901,12 +893,14 @@ asmlinkage int sys_swapon(const char * specialfile) ...@@ -901,12 +893,14 @@ asmlinkage int sys_swapon(const char * specialfile)
error = namei(specialfile,&swap_inode); error = namei(specialfile,&swap_inode);
if (error) if (error)
goto bad_swap; goto bad_swap;
p->swap_file = swap_inode;
error = -EBUSY; error = -EBUSY;
if (swap_inode->i_count != 1) if (swap_inode->i_count != 1)
goto bad_swap; goto bad_swap;
error = -EINVAL; error = -EINVAL;
if (S_ISBLK(swap_inode->i_mode)) { if (S_ISBLK(swap_inode->i_mode)) {
p->swap_device = swap_inode->i_rdev; p->swap_device = swap_inode->i_rdev;
p->swap_file = NULL;
iput(swap_inode); iput(swap_inode);
error = -ENODEV; error = -ENODEV;
if (!p->swap_device) if (!p->swap_device)
...@@ -918,9 +912,7 @@ asmlinkage int sys_swapon(const char * specialfile) ...@@ -918,9 +912,7 @@ asmlinkage int sys_swapon(const char * specialfile)
if (p->swap_device == swap_info[i].swap_device) if (p->swap_device == swap_info[i].swap_device)
goto bad_swap; goto bad_swap;
} }
} else if (S_ISREG(swap_inode->i_mode)) } else if (!S_ISREG(swap_inode->i_mode))
p->swap_file = swap_inode;
else
goto bad_swap; goto bad_swap;
p->swap_lockmap = (unsigned char *) get_free_page(GFP_USER); p->swap_lockmap = (unsigned char *) get_free_page(GFP_USER);
if (!p->swap_lockmap) { if (!p->swap_lockmap) {
......
...@@ -32,7 +32,9 @@ ...@@ -32,7 +32,9 @@
#include <linux/a.out.h> #include <linux/a.out.h>
#define MINIX_HEADER 32 #define MINIX_HEADER 32
#define GCC_HEADER 1024
#define N_MAGIC_OFFSET 1024
static int GCC_HEADER = sizeof(struct exec);
#define SYS_SIZE DEF_SYSSIZE #define SYS_SIZE DEF_SYSSIZE
...@@ -188,7 +190,10 @@ int main(int argc, char ** argv) ...@@ -188,7 +190,10 @@ int main(int argc, char ** argv)
die("Unable to open 'system'"); die("Unable to open 'system'");
if (read(id,buf,GCC_HEADER) != GCC_HEADER) if (read(id,buf,GCC_HEADER) != GCC_HEADER)
die("Unable to read header of 'system'"); die("Unable to read header of 'system'");
if (N_MAGIC(*ex) != ZMAGIC) if (N_MAGIC(*ex) == ZMAGIC) {
GCC_HEADER = N_MAGIC_OFFSET;
lseek(id, GCC_HEADER, SEEK_SET);
} else if (N_MAGIC(*ex) != QMAGIC)
die("Non-GCC header of 'system'"); die("Non-GCC header of 'system'");
fprintf(stderr,"System is %d kB (%d kB code, %d kB data and %d kB bss)\n", fprintf(stderr,"System is %d kB (%d kB code, %d kB data and %d kB bss)\n",
(ex->a_text+ex->a_data+ex->a_bss)/1024, (ex->a_text+ex->a_data+ex->a_bss)/1024,
......
...@@ -11,14 +11,14 @@ CFLAGS = -O2 -DSTDC_HEADERS $(TEST) ...@@ -11,14 +11,14 @@ CFLAGS = -O2 -DSTDC_HEADERS $(TEST)
.c.s: .c.s:
$(CC) $(CFLAGS) -S -o $*.s $< $(CC) $(CFLAGS) -S -o $*.s $<
.s.o: .s.o:
$(AS) -c -o $*.o $< $(AS) -o $*.o $<
.c.o: .c.o:
$(CC) $(CFLAGS) -c -o $*.o $< $(CC) $(CFLAGS) -c -o $*.o $<
all: zSystem all: zSystem
zSystem: piggy.o $(zOBJECTS) zSystem: piggy.o $(zOBJECTS)
$(LD) $(LDFLAGS) -o zSystem -Ttext 1000 $(zOBJECTS) piggy.o $(LD) $(LOWLDFLAGS) -o zSystem $(zOBJECTS) piggy.o
head.o: head.s head.o: head.s
......
...@@ -18,7 +18,9 @@ ...@@ -18,7 +18,9 @@
#include <a.out.h> #include <a.out.h>
#include <linux/config.h> #include <linux/config.h>
#define GCC_HEADER 1024 #define N_MAGIC_OFFSET 1024
static int GCC_HEADER = sizeof(struct exec);
#define STRINGIFY(x) #x #define STRINGIFY(x) #x
...@@ -49,7 +51,10 @@ int main(int argc, char ** argv) ...@@ -49,7 +51,10 @@ int main(int argc, char ** argv)
die("Unable to open 'system'"); die("Unable to open 'system'");
if (read(id,buf,GCC_HEADER) != GCC_HEADER) if (read(id,buf,GCC_HEADER) != GCC_HEADER)
die("Unable to read header of 'system'"); die("Unable to read header of 'system'");
if (N_MAGIC(*ex) != ZMAGIC) if (N_MAGIC(*ex) == ZMAGIC) {
GCC_HEADER = N_MAGIC_OFFSET;
lseek(id, GCC_HEADER, SEEK_SET);
} else if (N_MAGIC(*ex) != QMAGIC)
die("Non-GCC header of 'system'"); die("Non-GCC header of 'system'");
sz = N_SYMOFF(*ex) - GCC_HEADER + 4; /* +4 to get the same result than tools/build */ sz = N_SYMOFF(*ex) - GCC_HEADER + 4; /* +4 to get the same result than tools/build */
......
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