Commit 64e05a91 authored by Linus Torvalds's avatar Linus Torvalds

[PATCH] Linux-0.99.6 (February 21, 1993)

Merge a lot of duplicated special file handling into fs/devices.c, and
make drivers register their major numbers properly.

VFS layer gets fsync virtual function.

Compressed image boot, with the kernel loaded into high memory..

[original announcement below]

I'm starting soon to run out of patchlevel numbers for 0.99, but I made
a new release anyway (and long-time linux hackers remember my less than
completely logical numbering: when I run out of numbers I'll start using
alphabetical characters and other fun characters to indicate new
versions :-)

0.99pl6 is mainly a syncronization release: it fixes a few bugs and
changes the behaviour of 'vhangup()' to be more standard.  The vhangup()
changes will break some init/login stuff that depended on the earlier
incorrect behaviour - not everybody may want to use pl6 until you are
sure your init/login will work happily with it.  Better do these things
before 1.0 than to break it later.

Patchlevel 6 also changes the vfs functions for special devices as well
as adding a 'fsync' field to the inode-operations structure.  Thus
ext2fs and xfs need updating.  Remy and Xia? The special file and fifo
handling code is no longer supposed to be in the fs-dependent layer, but
is handled by the vfs routines, as it's the same for all "normal"
filesystems.

Ok, here are the actual changes/features of pl6:
- the kernel can be loaded in gzipped format and de-compressed at
  startup beyond the 1MB mark.  Good for bootable rootdisks.  Patches
  mainly by Hannu Savolainen.
- I finally enabled NMI's everywhere (except at the bootup sequence),
  so if you have memory errors, they will hopefully now result in
  kernel messages ("NMI received..")
- the device registration code for special devices.  Special files are
  now registered with a special "register_[chr|blk]dev()" function.
- consolidated fifo/special dev handling
- vhangup patches.  Note that these may break init/login badly, at
  least if you are using poeigl-1.7.  Be careful that you don't get
  totally locked out of your machine.
- the procfs NULL-dereferencing bugfix (michaelkjohnson)
- literal next character handling (very losely based on a patch I
  received: I essentially rewrote it with final fixes by jrs).
- fpu-emu bugfixes by Bill Metzenthen - fixes the "internal error 112"
  bug as well as a sign bug with zero.
- fdomain driver fixes
- various other minor fixes (wrongly replying to bad ip messages etc)

I'm still not sure about the 387 error detection code: I have had a
couple of messages that would suggest that some early clone 387's have
problems with math exceptions in protected mode.  With the new (as of
99pl5) test at startup this can lead to problems at boot-time.  Please
mail me directly if you seem to have problems with this (it should be
obvious in pl6 due to debugging messages at startup).

            Linus
parent b5341f73
......@@ -147,17 +147,14 @@ tools/./version.h: tools/version.h
tools/version.h: $(CONFIGURE) Makefile
@./makever.sh
@echo \#define UTS_RELEASE \"0.99.pl5-`cat .version`\" > tools/version.h
@echo \#define UTS_RELEASE \"0.99.pl6-`cat .version`\" > tools/version.h
@echo \#define UTS_VERSION \"`date +%D`\" >> tools/version.h
@echo \#define LINUX_COMPILE_TIME \"`date +%T`\" >> tools/version.h
@echo \#define LINUX_COMPILE_BY \"`whoami`\" >> tools/version.h
@echo \#define LINUX_COMPILE_HOST \"`hostname`\" >> tools/version.h
Image: $(CONFIGURE) boot/bootsect boot/setup tools/system tools/build
cp tools/system system.tmp
$(STRIP) system.tmp
tools/build boot/bootsect boot/setup system.tmp $(ROOT_DEV) > Image
rm system.tmp
tools/build boot/bootsect boot/setup tools/system $(ROOT_DEV) > Image
sync
disk: Image
......@@ -200,6 +197,33 @@ boot/bootsect: boot/bootsect.s
$(AS86) -o boot/bootsect.o boot/bootsect.s
$(LD86) -s -o boot/bootsect boot/bootsect.o
zBoot/zSystem: zBoot/*.c zBoot/*.S tools/zSystem
cd zBoot;$(MAKE)
zImage: $(CONFIGURE) boot/bootsect boot/setup zBoot/zSystem tools/build
cp zBoot/zSystem system.tmp
$(STRIP) system.tmp
tools/build boot/bootsect boot/setup system.tmp $(ROOT_DEV) > zImage
rm system.tmp
sync
zdisk: zImage
dd bs=8192 if=zImage of=/dev/fd0
zlilo: $(CONFIGURE) zImage
cat zImage > /vmlinuz
/etc/lilo/install
tools/zSystem: boot/head.o init/main.o tools/version.o linuxsubdirs
$(LD) $(LDFLAGS) -T 100000 -M boot/head.o init/main.o tools/version.o \
$(ARCHIVES) \
$(FILESYSTEMS) \
$(DRIVERS) \
$(MATH) \
$(LIBS) \
-o tools/zSystem > zSystem.map
fs: dummy
$(MAKE) linuxsubdirs SUBDIRS=fs
......@@ -210,10 +234,11 @@ kernel: dummy
$(MAKE) linuxsubdirs SUBDIRS=kernel
clean:
rm -f zImage zSystem.map tools/zSystem
rm -f Image System.map core boot/bootsect boot/setup \
boot/bootsect.s boot/setup.s boot/head.s init/main.s
rm -f init/*.o tools/system tools/build boot/*.o tools/*.o
for i in $(SUBDIRS); do (cd $$i && $(MAKE) clean); done
for i in zBoot $(SUBDIRS); do (cd $$i && $(MAKE) clean); done
backup: clean
cd .. && tar cf - linux | compress - > backup.Z
......
......@@ -146,6 +146,8 @@ no_psmouse:
! now we want to move to protected mode ...
cli ! no interrupts allowed !
mov al,#0x80 ! disable NMI for the bootup sequence
out #0x70,al
! first we move the system to it's rightful place
......
......@@ -35,7 +35,7 @@ endif
.s.o:
$(AS) -o $*.o $<
OBJS= open.o read_write.o inode.o file_table.o buffer.o super.o \
OBJS= open.o read_write.o inode.o devices.o file_table.o buffer.o super.o \
block_dev.o stat.o exec.o pipe.o namei.o fcntl.o ioctl.o \
select.o fifo.o locks.o filesystems.o
......
/*
* linux/fs/ext/blkdev.c
*
* Copyright (C) 1992 Remy Card (card@masi.ibp.fr)
*
* from
*
* linux/fs/minix/blkdev.c
* linux/fs/devices.c
*
* (C) 1993 Matthias Urlichs -- collected common code and tables.
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/sched.h>
#include <linux/ext_fs.h>
#include <linux/tty.h>
......@@ -17,10 +15,38 @@
#include <linux/fcntl.h>
#include <linux/errno.h>
struct file_operations * chrdev_fops[MAX_CHRDEV] = {
NULL,
};
struct file_operations * blkdev_fops[MAX_BLKDEV] = {
NULL,
};
int register_chrdev(unsigned int major, const char * name, struct file_operations *fops)
{
if (major >= MAX_CHRDEV)
return -EINVAL;
if (chrdev_fops[major])
return -EBUSY;
chrdev_fops[major] = fops;
return 0;
}
int register_blkdev(unsigned int major, const char * name, struct file_operations *fops)
{
if (major >= MAX_BLKDEV)
return -EINVAL;
if (blkdev_fops[major])
return -EBUSY;
blkdev_fops[major] = fops;
return 0;
}
/*
* Called every time an ext block special file is opened
* Called every time a block special file is opened
*/
static int blkdev_open(struct inode * inode, struct file * filp)
int blkdev_open(struct inode * inode, struct file * filp)
{
int i;
......@@ -38,7 +64,7 @@ static int blkdev_open(struct inode * inode, struct file * filp)
* is contain the open that then fills in the correct operations
* depending on the special file...
*/
static struct file_operations def_blk_fops = {
struct file_operations def_blk_fops = {
NULL, /* lseek */
NULL, /* read */
NULL, /* write */
......@@ -50,7 +76,7 @@ static struct file_operations def_blk_fops = {
NULL, /* release */
};
struct inode_operations ext_blkdev_inode_operations = {
struct inode_operations blkdev_inode_operations = {
&def_blk_fops, /* default file operations */
NULL, /* create */
NULL, /* lookup */
......@@ -67,3 +93,54 @@ struct inode_operations ext_blkdev_inode_operations = {
NULL, /* truncate */
NULL /* permission */
};
/*
* Called every time a character special file is opened
*/
int chrdev_open(struct inode * inode, struct file * filp)
{
int i;
i = MAJOR(inode->i_rdev);
if (i >= MAX_CHRDEV || !chrdev_fops[i])
return -ENODEV;
filp->f_op = chrdev_fops[i];
if (filp->f_op->open)
return filp->f_op->open(inode,filp);
return 0;
}
/*
* Dummy default file-operations: the only thing this does
* is contain the open that then fills in the correct operations
* depending on the special file...
*/
struct file_operations def_chr_fops = {
NULL, /* lseek */
NULL, /* read */
NULL, /* write */
NULL, /* readdir */
NULL, /* select */
NULL, /* ioctl */
NULL, /* mmap */
chrdev_open, /* open */
NULL, /* release */
};
struct inode_operations chrdev_inode_operations = {
&def_chr_fops, /* default file operations */
NULL, /* create */
NULL, /* lookup */
NULL, /* link */
NULL, /* unlink */
NULL, /* symlink */
NULL, /* mkdir */
NULL, /* rmdir */
NULL, /* mknod */
NULL, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
NULL, /* truncate */
NULL /* permission */
};
......@@ -15,7 +15,7 @@
$(AS) -o $*.o $<
OBJS= freelists.o truncate.o namei.o inode.o \
file.o dir.o symlink.o blkdev.o chrdev.o fifo.o
file.o dir.o symlink.o
ext.o: $(OBJS)
$(LD) -r -o ext.o $(OBJS)
......
/*
* linux/fs/ext/chrdev.c
*
* Copyright (C) 1992 Remy Card (card@masi.ibp.fr)
*
* from
*
* linux/fs/minix/chrdev.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
#include <linux/sched.h>
#include <linux/ext_fs.h>
#include <linux/tty.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <linux/errno.h>
/*
* Called every time an ext character special file is opened
*/
static int chrdev_open(struct inode * inode, struct file * filp)
{
int i;
i = MAJOR(inode->i_rdev);
if (i >= MAX_CHRDEV || !chrdev_fops[i])
return -ENODEV;
filp->f_op = chrdev_fops[i];
if (filp->f_op->open)
return filp->f_op->open(inode,filp);
return 0;
}
/*
* Dummy default file-operations: the only thing this does
* is contain the open that then fills in the correct operations
* depending on the special file...
*/
static struct file_operations def_chr_fops = {
NULL, /* lseek */
NULL, /* read */
NULL, /* write */
NULL, /* readdir */
NULL, /* select */
NULL, /* ioctl */
NULL, /* mmap */
chrdev_open, /* open */
NULL, /* release */
};
struct inode_operations ext_chrdev_inode_operations = {
&def_chr_fops, /* default file operations */
NULL, /* create */
NULL, /* lookup */
NULL, /* link */
NULL, /* unlink */
NULL, /* symlink */
NULL, /* mkdir */
NULL, /* rmdir */
NULL, /* mknod */
NULL, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
NULL, /* truncate */
NULL /* permission */
};
......@@ -36,7 +36,8 @@ static struct file_operations ext_dir_operations = {
NULL, /* ioctl - default */
NULL, /* mmap */
NULL, /* no special open code */
NULL /* no special release code */
NULL, /* no special release code */
NULL /* fsync */
};
/*
......
/*
* linux/fs/fifo.c
*
* written by Paul H. Hargrove.
*/
#include <linux/sched.h>
#include <linux/ext_fs.h>
extern struct file_operations def_fifo_fops;
struct inode_operations ext_fifo_inode_operations = {
&def_fifo_fops, /* default file operations */
NULL, /* create */
NULL, /* lookup */
NULL, /* link */
NULL, /* unlink */
NULL, /* symlink */
NULL, /* mkdir */
NULL, /* rmdir */
NULL, /* mknod */
NULL, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
NULL, /* truncate */
NULL /* permission */
};
......@@ -47,7 +47,8 @@ static struct file_operations ext_file_operations = {
NULL, /* ioctl - default */
NULL, /* mmap */
NULL, /* no special open is needed */
NULL /* release */
NULL, /* release */
NULL /* fsync */
};
struct inode_operations ext_file_inode_operations = {
......
......@@ -372,11 +372,11 @@ void ext_read_inode(struct inode * inode)
else if (S_ISLNK(inode->i_mode))
inode->i_op = &ext_symlink_inode_operations;
else if (S_ISCHR(inode->i_mode))
inode->i_op = &ext_chrdev_inode_operations;
inode->i_op = &chrdev_inode_operations;
else if (S_ISBLK(inode->i_mode))
inode->i_op = &ext_blkdev_inode_operations;
inode->i_op = &blkdev_inode_operations;
else if (S_ISFIFO(inode->i_mode)) {
inode->i_op = &ext_fifo_inode_operations;
inode->i_op = &fifo_inode_operations;
inode->i_pipe = 1;
PIPE_BASE(*inode) = NULL;
PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
......
......@@ -369,11 +369,11 @@ int ext_mknod(struct inode * dir, const char * name, int len, int mode, int rdev
else if (S_ISLNK(inode->i_mode))
inode->i_op = &ext_symlink_inode_operations;
else if (S_ISCHR(inode->i_mode))
inode->i_op = &ext_chrdev_inode_operations;
inode->i_op = &chrdev_inode_operations;
else if (S_ISBLK(inode->i_mode))
inode->i_op = &ext_blkdev_inode_operations;
inode->i_op = &blkdev_inode_operations;
else if (S_ISFIFO(inode->i_mode)) {
inode->i_op = &ext_fifo_inode_operations;
inode->i_op = &fifo_inode_operations;
inode->i_pipe = 1;
PIPE_BASE(*inode) = NULL;
PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
......
......@@ -112,5 +112,24 @@ struct file_operations def_fifo_fops = {
NULL,
NULL,
fifo_open, /* will set read or write pipe_fops */
NULL,
NULL
};
struct inode_operations fifo_inode_operations = {
&def_fifo_fops, /* default file operations */
NULL, /* create */
NULL, /* lookup */
NULL, /* link */
NULL, /* unlink */
NULL, /* symlink */
NULL, /* mkdir */
NULL, /* rmdir */
NULL, /* mknod */
NULL, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
NULL, /* truncate */
NULL /* permission */
};
......@@ -177,6 +177,8 @@ void sync_inodes(dev_t dev)
struct inode * inode;
for(inode = 0+inode_table ; inode < NR_INODE+inode_table ; inode++) {
if (dev && inode->i_dev != dev)
continue;
wait_on_inode(inode);
if (inode->i_dirt)
write_inode(inode);
......
......@@ -14,8 +14,7 @@
.s.o:
$(AS) -o $*.o $<
OBJS= namei.o inode.o file.o dir.o util.o rock.o symlink.o \
fifo.o blkdev.o chrdev.o
OBJS= namei.o inode.o file.o dir.o util.o rock.o symlink.o
isofs.o: $(OBJS)
$(LD) -r -o isofs.o $(OBJS)
......
/*
* linux/fs/isofs/blkdev.c
*
* (C) 1992 Eric Youngdale Modified for ISO9660 filesystem.
*
* Copyright (C) 1991, 1992 Linus Torvalds
*
* isofs blkdev handling code. This is only used with the Rock Ridge
* extensions to iso9660
*/
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/iso_fs.h>
#include <linux/tty.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
/*
* Called every time a isofs block special file is opened
*/
static int blkdev_open(struct inode * inode, struct file * filp)
{
int i;
i = MAJOR(inode->i_rdev);
if (i >= MAX_BLKDEV || !blkdev_fops[i])
return -ENODEV;
filp->f_op = blkdev_fops[i];
if (filp->f_op->open)
return filp->f_op->open(inode,filp);
return 0;
}
/*
* Dummy default file-operations: the only thing this does
* is contain the open that then fills in the correct operations
* depending on the special file...
*/
static struct file_operations def_blk_fops = {
NULL, /* lseek */
NULL, /* read */
NULL, /* write */
NULL, /* readdir */
NULL, /* select */
NULL, /* ioctl */
NULL, /* mmap */
blkdev_open, /* open */
NULL, /* release */
};
struct inode_operations isofs_blkdev_inode_operations = {
&def_blk_fops, /* default file operations */
NULL, /* create */
NULL, /* lookup */
NULL, /* link */
NULL, /* unlink */
NULL, /* symlink */
NULL, /* mkdir */
NULL, /* rmdir */
NULL, /* mknod */
NULL, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
isofs_bmap, /* bmap */
NULL, /* truncate */
NULL /* permission */
};
/*
* linux/fs/isofs/chrdev.c
*
* (C) 1992 Eric Youngdale Modified for ISO9660 filesystem.
*
* Copyright (C) 1991, 1992 Linus Torvalds
*
* isofs chrdev handling code. This is only used with the Rock Ridge
* extensions to iso9660
*/
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/iso_fs.h>
#include <linux/tty.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
/*
* Called every time a isofs character special file is opened
*/
static int chrdev_open(struct inode * inode, struct file * filp)
{
int i;
i = MAJOR(inode->i_rdev);
if (i >= MAX_CHRDEV || !chrdev_fops[i])
return -ENODEV;
filp->f_op = chrdev_fops[i];
if (filp->f_op->open)
return filp->f_op->open(inode,filp);
return 0;
}
/*
* Dummy default file-operations: the only thing this does
* is contain the open that then fills in the correct operations
* depending on the special file...
*/
static struct file_operations def_chr_fops = {
NULL, /* lseek */
NULL, /* read */
NULL, /* write */
NULL, /* readdir */
NULL, /* select */
NULL, /* ioctl */
NULL, /* mmap */
chrdev_open, /* open */
NULL, /* release */
};
struct inode_operations isofs_chrdev_inode_operations = {
&def_chr_fops, /* default file operations */
NULL, /* create */
NULL, /* lookup */
NULL, /* link */
NULL, /* unlink */
NULL, /* symlink */
NULL, /* mkdir */
NULL, /* rmdir */
NULL, /* mknod */
NULL, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
isofs_bmap, /* bmap */
NULL, /* truncate */
NULL /* permission */
};
......@@ -29,7 +29,8 @@ static struct file_operations isofs_dir_operations = {
NULL, /* select - default */
NULL, /* ioctl - default */
NULL, /* no special open code */
NULL /* no special release code */
NULL, /* no special release code */
NULL /* fsync */
};
/*
......
/*
* linux/fs/fifo.c
*
* written by Paul H. Hargrove
*/
#include <linux/sched.h>
#include <linux/iso_fs.h>
extern struct file_operations def_fifo_fops;
struct inode_operations isofs_fifo_inode_operations = {
&def_fifo_fops, /* default file operations */
NULL, /* create */
NULL, /* lookup */
NULL, /* link */
NULL, /* unlink */
NULL, /* symlink */
NULL, /* mkdir */
NULL, /* rmdir */
NULL, /* mknod */
NULL, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
NULL, /* truncate */
NULL /* permission */
};
......@@ -43,7 +43,8 @@ static struct file_operations isofs_file_operations = {
NULL, /* select - default */
NULL, /* ioctl - default */
NULL, /* no special open is needed */
NULL /* release */
NULL, /* release */
NULL /* fsync */
};
struct inode_operations isofs_file_inode_operations = {
......
......@@ -412,11 +412,11 @@ void isofs_read_inode(struct inode * inode)
else if (S_ISLNK(inode->i_mode))
inode->i_op = &isofs_symlink_inode_operations;
else if (S_ISCHR(inode->i_mode))
inode->i_op = &isofs_chrdev_inode_operations;
inode->i_op = &chrdev_inode_operations;
else if (S_ISBLK(inode->i_mode))
inode->i_op = &isofs_blkdev_inode_operations;
inode->i_op = &blkdev_inode_operations;
else if (S_ISFIFO(inode->i_mode)) {
inode->i_op = &isofs_fifo_inode_operations;
inode->i_op = &fifo_inode_operations;
inode->i_pipe = 1;
PIPE_BASE(*inode) = NULL;
PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
......
......@@ -15,7 +15,7 @@
$(AS) -o $*.o $<
OBJS= bitmap.o truncate.o namei.o inode.o \
file.o dir.o symlink.o blkdev.o chrdev.o fifo.o
file.o dir.o symlink.o
minix.o: $(OBJS)
$(LD) -r -o minix.o $(OBJS)
......
/*
* linux/fs/minix/blkdev.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/minix_fs.h>
#include <linux/tty.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
/*
* Called every time a minix block special file is opened
*/
static int blkdev_open(struct inode * inode, struct file * filp)
{
int i;
i = MAJOR(inode->i_rdev);
if (i >= MAX_BLKDEV || !blkdev_fops[i])
return -ENODEV;
filp->f_op = blkdev_fops[i];
if (filp->f_op->open)
return filp->f_op->open(inode,filp);
return 0;
}
/*
* Dummy default file-operations: the only thing this does
* is contain the open that then fills in the correct operations
* depending on the special file...
*/
static struct file_operations def_blk_fops = {
NULL, /* lseek */
NULL, /* read */
NULL, /* write */
NULL, /* readdir */
NULL, /* select */
NULL, /* ioctl */
NULL, /* mmap */
blkdev_open, /* open */
NULL, /* release */
};
struct inode_operations minix_blkdev_inode_operations = {
&def_blk_fops, /* default file operations */
NULL, /* create */
NULL, /* lookup */
NULL, /* link */
NULL, /* unlink */
NULL, /* symlink */
NULL, /* mkdir */
NULL, /* rmdir */
NULL, /* mknod */
NULL, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
NULL, /* truncate */
NULL /* permission */
};
/*
* linux/fs/minix/chrdev.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/minix_fs.h>
#include <linux/tty.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
/*
* Called every time a minix character special file is opened
*/
static int chrdev_open(struct inode * inode, struct file * filp)
{
int i;
i = MAJOR(inode->i_rdev);
if (i >= MAX_CHRDEV || !chrdev_fops[i])
return -ENODEV;
filp->f_op = chrdev_fops[i];
if (filp->f_op->open)
return filp->f_op->open(inode,filp);
return 0;
}
/*
* Dummy default file-operations: the only thing this does
* is contain the open that then fills in the correct operations
* depending on the special file...
*/
static struct file_operations def_chr_fops = {
NULL, /* lseek */
NULL, /* read */
NULL, /* write */
NULL, /* readdir */
NULL, /* select */
NULL, /* ioctl */
NULL, /* mmap */
chrdev_open, /* open */
NULL, /* release */
};
struct inode_operations minix_chrdev_inode_operations = {
&def_chr_fops, /* default file operations */
NULL, /* create */
NULL, /* lookup */
NULL, /* link */
NULL, /* unlink */
NULL, /* symlink */
NULL, /* mkdir */
NULL, /* rmdir */
NULL, /* mknod */
NULL, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
NULL, /* truncate */
NULL /* permission */
};
......@@ -29,7 +29,8 @@ static struct file_operations minix_dir_operations = {
NULL, /* ioctl - default */
NULL, /* mmap */
NULL, /* no special open code */
NULL /* no special release code */
NULL, /* no special release code */
NULL /* default fsync */
};
/*
......
/*
* linux/fs/fifo.c
*
* written by Paul H. Hargrove
*/
#include <linux/sched.h>
#include <linux/minix_fs.h>
extern struct file_operations def_fifo_fops;
struct inode_operations minix_fifo_inode_operations = {
&def_fifo_fops, /* default file operations */
NULL, /* create */
NULL, /* lookup */
NULL, /* link */
NULL, /* unlink */
NULL, /* symlink */
NULL, /* mkdir */
NULL, /* rmdir */
NULL, /* mknod */
NULL, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
NULL, /* truncate */
NULL /* permission */
};
......@@ -41,7 +41,8 @@ static struct file_operations minix_file_operations = {
NULL, /* ioctl - default */
NULL, /* mmap */
NULL, /* no special open is needed */
NULL /* release */
NULL, /* release */
NULL /* fsync */
};
struct inode_operations minix_file_inode_operations = {
......
......@@ -345,11 +345,11 @@ void minix_read_inode(struct inode * inode)
else if (S_ISLNK(inode->i_mode))
inode->i_op = &minix_symlink_inode_operations;
else if (S_ISCHR(inode->i_mode))
inode->i_op = &minix_chrdev_inode_operations;
inode->i_op = &chrdev_inode_operations;
else if (S_ISBLK(inode->i_mode))
inode->i_op = &minix_blkdev_inode_operations;
inode->i_op = &blkdev_inode_operations;
else if (S_ISFIFO(inode->i_mode)) {
inode->i_op = &minix_fifo_inode_operations;
inode->i_op = &fifo_inode_operations;
inode->i_pipe = 1;
PIPE_BASE(*inode) = NULL;
PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
......@@ -373,8 +373,11 @@ void minix_write_inode(struct inode * inode)
}
block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks + inode->i_sb->u.minix_sb.s_zmap_blocks +
(ino-1)/MINIX_INODES_PER_BLOCK;
if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE)))
panic("unable to read i-node block");
if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE))) {
printk("unable to read i-node block\n");
inode->i_dirt = 0;
return;
}
raw_inode = ((struct minix_inode *)bh->b_data) +
(ino-1)%MINIX_INODES_PER_BLOCK;
raw_inode->i_mode = inode->i_mode;
......
......@@ -261,11 +261,11 @@ int minix_mknod(struct inode * dir, const char * name, int len, int mode, int rd
else if (S_ISLNK(inode->i_mode))
inode->i_op = &minix_symlink_inode_operations;
else if (S_ISCHR(inode->i_mode))
inode->i_op = &minix_chrdev_inode_operations;
inode->i_op = &chrdev_inode_operations;
else if (S_ISBLK(inode->i_mode))
inode->i_op = &minix_blkdev_inode_operations;
inode->i_op = &blkdev_inode_operations;
else if (S_ISFIFO(inode->i_mode)) {
inode->i_op = &minix_fifo_inode_operations;
inode->i_op = &fifo_inode_operations;
inode->i_pipe = 1;
PIPE_BASE(*inode) = NULL;
PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
......
......@@ -31,7 +31,8 @@ static struct file_operations msdos_dir_operations = {
NULL, /* ioctl - default */
NULL, /* mmap */
NULL, /* no special open code */
NULL /* no special release code */
NULL, /* no special release code */
NULL /* fsync */
};
struct inode_operations msdos_dir_inode_operations = {
......
......@@ -34,7 +34,8 @@ static struct file_operations msdos_file_operations = {
NULL, /* ioctl - default */
NULL, /* mmap */
NULL, /* no special open is needed */
NULL /* release */
NULL, /* release */
NULL /* fsync */
};
struct inode_operations msdos_file_inode_operations = {
......
......@@ -15,7 +15,7 @@
$(AS) -o $*.o $<
OBJS= proc.o sock.o inode.o file.o dir.o \
symlink.o blkdev.o chrdev.o fifo.o
symlink.o
nfs.o: $(OBJS)
$(LD) -r -o nfs.o $(OBJS)
......
/*
* linux/fs/nfs/blkdev.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/nfs_fs.h>
#include <linux/tty.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
/*
* Called every time a nfs block special file is opened
*/
static int blkdev_open(struct inode * inode, struct file * filp)
{
int i;
i = MAJOR(inode->i_rdev);
if (i >= MAX_BLKDEV || !blkdev_fops[i])
return -ENODEV;
filp->f_op = blkdev_fops[i];
if (filp->f_op->open)
return filp->f_op->open(inode,filp);
return 0;
}
/*
* Dummy default file-operations: the only thing this does
* is contain the open that then fills in the correct operations
* depending on the special file...
*/
static struct file_operations def_blk_fops = {
NULL, /* lseek */
NULL, /* read */
NULL, /* write */
NULL, /* readdir */
NULL, /* select */
NULL, /* ioctl */
NULL, /* mmap */
blkdev_open, /* open */
NULL, /* release */
};
struct inode_operations nfs_blkdev_inode_operations = {
&def_blk_fops, /* default file operations */
NULL, /* create */
NULL, /* lookup */
NULL, /* link */
NULL, /* unlink */
NULL, /* symlink */
NULL, /* mkdir */
NULL, /* rmdir */
NULL, /* mknod */
NULL, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
NULL, /* truncate */
NULL /* permission */
};
/*
* linux/fs/nfs/chrdev.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/nfs_fs.h>
#include <linux/tty.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
/*
* Called every time a nfs character special file is opened
*/
static int chrdev_open(struct inode * inode, struct file * filp)
{
int i;
i = MAJOR(inode->i_rdev);
if (i >= MAX_CHRDEV || !chrdev_fops[i])
return -ENODEV;
filp->f_op = chrdev_fops[i];
if (filp->f_op->open)
return filp->f_op->open(inode,filp);
return 0;
}
/*
* Dummy default file-operations: the only thing this does
* is contain the open that then fills in the correct operations
* depending on the special file...
*/
static struct file_operations def_chr_fops = {
NULL, /* lseek */
NULL, /* read */
NULL, /* write */
NULL, /* readdir */
NULL, /* select */
NULL, /* ioctl */
NULL, /* mmap */
chrdev_open, /* open */
NULL, /* release */
};
struct inode_operations nfs_chrdev_inode_operations = {
&def_chr_fops, /* default file operations */
NULL, /* create */
NULL, /* lookup */
NULL, /* link */
NULL, /* unlink */
NULL, /* symlink */
NULL, /* mkdir */
NULL, /* rmdir */
NULL, /* mknod */
NULL, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
NULL, /* truncate */
NULL /* permission */
};
......@@ -46,7 +46,8 @@ static struct file_operations nfs_dir_operations = {
NULL, /* ioctl - default */
NULL, /* mmap */
NULL, /* no special open code */
NULL /* no special release code */
NULL, /* no special release code */
NULL /* fsync */
};
struct inode_operations nfs_dir_inode_operations = {
......@@ -627,11 +628,11 @@ void nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
else if (S_ISLNK(inode->i_mode))
inode->i_op = &nfs_symlink_inode_operations;
else if (S_ISCHR(inode->i_mode))
inode->i_op = &nfs_chrdev_inode_operations;
inode->i_op = &chrdev_inode_operations;
else if (S_ISBLK(inode->i_mode))
inode->i_op = &nfs_blkdev_inode_operations;
inode->i_op = &blkdev_inode_operations;
else if (S_ISFIFO(inode->i_mode)) {
inode->i_op = &nfs_fifo_inode_operations;
inode->i_op = &fifo_inode_operations;
inode->i_pipe = 1;
PIPE_BASE(*inode) = NULL;
PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
......
/*
* linux/fs/fifo.c
*
* written by Paul H. Hargrove
*/
#include <linux/sched.h>
#include <linux/nfs_fs.h>
extern struct file_operations def_fifo_fops;
struct inode_operations nfs_fifo_inode_operations = {
&def_fifo_fops, /* default file operations */
NULL, /* create */
NULL, /* lookup */
NULL, /* link */
NULL, /* unlink */
NULL, /* symlink */
NULL, /* mkdir */
NULL, /* rmdir */
NULL, /* mknod */
NULL, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
NULL, /* truncate */
NULL /* permission */
};
......@@ -29,7 +29,8 @@ static struct file_operations nfs_file_operations = {
NULL, /* ioctl - default */
NULL, /* mmap */
NULL, /* no special open is needed */
NULL /* release */
NULL, /* release */
NULL /* fsync */
};
struct inode_operations nfs_file_inode_operations = {
......
......@@ -21,14 +21,6 @@
extern void fcntl_remove_locks(struct task_struct *, struct file *);
struct file_operations * chrdev_fops[MAX_CHRDEV] = {
NULL,
};
struct file_operations * blkdev_fops[MAX_BLKDEV] = {
NULL,
};
int sys_ustat(int dev, struct ustat * ubuf)
{
return -ENOSYS;
......@@ -452,102 +444,19 @@ int sys_close(unsigned int fd)
}
/*
* This routine is used by vhangup. It send's sigkill to everything
* waiting on a particular wait_queue. It assumes root privledges.
* We don't want to destroy the wait queue here, because the caller
* should call wake_up immediately after calling kill_wait.
*/
static void kill_wait(struct wait_queue **q, int sig)
{
struct wait_queue *next;
struct wait_queue *tmp;
struct task_struct *p;
if (!q || !(next = *q))
return;
do {
tmp = next;
next = tmp->next;
if ((p = tmp->task) != NULL)
send_sig (sig, p , 1);
} while (next && next != *q);
}
/*
* This routine looks through all the process's and closes any
* references to the current processes tty. To avoid problems with
* process sleeping on an inode which has already been iput, anyprocess
* which is sleeping on the tty is sent a sigkill (It's probably a rogue
* process.) Also no process should ever have /dev/console as it's
* controlling tty, or have it open for reading. So we don't have to
* worry about messing with all the daemons abilities to write messages
* to the console. (Besides they should be using syslog.)
* This routine simulates a hangup on the tty, to arrange that users
* are given clean terminals at login time.
*/
int sys_vhangup(void)
{
int j;
struct task_struct ** process;
struct file *filep;
struct inode *inode;
struct tty_struct *tty;
extern int kill_pg (int pgrp, int sig, int priv);
if (!suser())
return -EPERM;
/* See if there is a controlling tty. */
if (current->tty < 0)
return 0;
/* send the SIGHUP signal. */
tty = TTY_TABLE(current->tty);
if (tty && tty->pgrp > 0)
kill_pg(tty->pgrp, SIGHUP, 0);
for (process = task + 0; process < task + NR_TASKS; process++) {
for (j = 0; j < NR_OPEN; j++) {
if (!*process)
break;
if (!(filep = (*process)->filp[j]))
continue;
if (!(inode = filep->f_inode))
continue;
if (!S_ISCHR(inode->i_mode))
continue;
if ((MAJOR(inode->i_rdev) == 5 ||
MAJOR(inode->i_rdev) == 4 ) &&
(MAJOR(filep->f_rdev) == 4 &&
MINOR(filep->f_rdev) == MINOR (current->tty))) {
/* so now we have found something to close. We
need to kill every process waiting on the
inode. */
(*process)->filp[j] = NULL;
kill_wait (&inode->i_wait, SIGKILL);
/* now make sure they are awake before we close the
file. */
wake_up (&inode->i_wait);
/* finally close the file. */
FD_CLR(j, &(*process)->close_on_exec);
close_fp (filep);
}
}
/* can't let them keep a reference to it around.
But we can't touch current->tty until after the
loop is complete. */
if (*process && (*process)->tty == current->tty && *process != current) {
(*process)->tty = -1;
}
}
/* need to do tty->session = 0 */
tty = TTY_TABLE(MINOR(current->tty));
if (tty) {
tty->session = 0;
tty->pgrp = -1;
current->tty = -1;
}
tty_hangup(tty);
return 0;
}
......@@ -179,7 +179,8 @@ struct file_operations read_pipe_fops = {
pipe_ioctl,
NULL, /* no mmap on pipes.. surprise */
NULL, /* no special open code */
pipe_read_release
pipe_read_release,
NULL
};
struct file_operations write_pipe_fops = {
......@@ -191,7 +192,8 @@ struct file_operations write_pipe_fops = {
pipe_ioctl,
NULL, /* mmap */
NULL, /* no special open code */
pipe_write_release
pipe_write_release,
NULL
};
struct file_operations rdwr_pipe_fops = {
......@@ -203,7 +205,8 @@ struct file_operations rdwr_pipe_fops = {
pipe_ioctl,
NULL, /* mmap */
NULL, /* no special open code */
pipe_rdwr_release
pipe_rdwr_release,
NULL
};
int sys_pipe(unsigned long * fildes)
......
......@@ -181,7 +181,7 @@ static int get_stat(int pid, char * buffer)
{
struct task_struct ** p = get_task(pid);
unsigned long sigignore=0, sigcatch=0, bit=1, wchan;
int i;
int i,tty_pgrp;
char state;
if (!p || !*p)
......@@ -198,6 +198,11 @@ static int get_stat(int pid, char * buffer)
default: sigcatch |= bit;
} bit <<= 1;
}
tty_pgrp = (*p)->tty;
if (tty_pgrp > 0 && tty_table[tty_pgrp])
tty_pgrp = tty_table[tty_pgrp]->pgrp;
else
tty_pgrp = -1;
return sprintf(buffer,"%d (%s) %c %d %d %d %d %d %u %u \
%u %u %u %d %d %d %d %d %d %u %u %d %u %u %u %u %u %u %u %u %d \
%d %d %d %u\n",
......@@ -208,8 +213,7 @@ static int get_stat(int pid, char * buffer)
(*p)->pgrp,
(*p)->session,
(*p)->tty,
((*p)->tty == -1) ? -1 :
tty_table[(*p)->tty]->pgrp,
tty_pgrp,
(*p)->flags,
(*p)->min_flt,
(*p)->cmin_flt,
......@@ -354,7 +358,8 @@ static struct file_operations proc_array_operations = {
NULL, /* array_ioctl */
NULL, /* mmap */
NULL, /* no special open code */
NULL /* no special release code */
NULL, /* no special release code */
NULL /* can't fsync */
};
struct inode_operations proc_array_inode_operations = {
......
......@@ -25,7 +25,8 @@ static struct file_operations proc_base_operations = {
NULL, /* ioctl - default */
NULL, /* mmap */
NULL, /* no special open code */
NULL /* no special release code */
NULL, /* no special release code */
NULL /* can't fsync */
};
/*
......
......@@ -25,7 +25,8 @@ static struct file_operations proc_fd_operations = {
NULL, /* ioctl - default */
NULL, /* mmap */
NULL, /* no special open code */
NULL /* no special release code */
NULL, /* no special release code */
NULL /* can't fsync */
};
/*
......
......@@ -54,7 +54,8 @@ static struct file_operations proc_kmsg_operations = {
NULL, /* kmsg_ioctl */
NULL, /* mmap */
kmsg_open,
kmsg_release
kmsg_release,
NULL /* can't fsync */
};
struct inode_operations proc_kmsg_inode_operations = {
......
......@@ -149,7 +149,8 @@ static struct file_operations proc_mem_operations = {
NULL, /* mem_ioctl */
NULL, /* mmap */
NULL, /* no special open code */
NULL /* no special release code */
NULL, /* no special release code */
NULL /* can't fsync */
};
struct inode_operations proc_mem_inode_operations = {
......
......@@ -25,7 +25,8 @@ static struct file_operations proc_root_operations = {
NULL, /* ioctl - default */
NULL, /* mmap */
NULL, /* no special open code */
NULL /* no special release code */
NULL, /* no special release code */
NULL /* no fsync */
};
/*
......
......@@ -24,6 +24,7 @@
*/
extern struct file_system_type file_systems[];
extern struct file_operations * blkdev_fops[];
extern void wait_for_keypress(void);
extern void fcntl_init_locks(void);
......@@ -67,6 +68,8 @@ void sync_supers(dev_t dev)
for (sb = super_block + 0 ; sb < super_block + NR_SUPER ; sb++) {
if (!sb->s_dev)
continue;
if (dev && sb->s_dev != dev)
continue;
wait_on_super(sb);
if (!sb->s_dev || !sb->s_dirt)
continue;
......
#ifndef _LINUX_DIRENT_H
#define _LINUX_DIRENT_H
#include <linux/limits.h>
struct dirent {
long d_ino;
off_t d_off;
......
......@@ -11,6 +11,9 @@
#define FDFMTTRK 7 /* format the specified track */
#define FDFMTEND 8 /* end formatting a disk */
#define FDSETEMSGTRESH 10 /* set fdc error reporting treshold */
#define FDFLUSH 11 /* flush buffers for media; either for verifying media, or for
handling a media change without closing the file
descriptor */
#define FD_FILL_BYTE 0xF6 /* format fill byte */
......
......@@ -109,7 +109,7 @@ extern unsigned long inode_init(unsigned long start, unsigned long end);
*
* Exception: MS_RDONLY is always applied to the entire file system.
*/
#define IS_RDONLY(inode) ((inode)->i_sb->s_flags & MS_RDONLY)
#define IS_RDONLY(inode) (((inode)->i_sb) && ((inode)->i_sb->s_flags & MS_RDONLY))
#define IS_NOSUID(inode) ((inode)->i_flags & MS_NOSUID)
#define IS_NODEV(inode) ((inode)->i_flags & MS_NODEV)
#define IS_NOEXEC(inode) ((inode)->i_flags & MS_NOEXEC)
......@@ -260,6 +260,7 @@ struct file_operations {
int (*mmap) (void);
int (*open) (struct inode *, struct file *);
void (*release) (struct inode *, struct file *);
int (*fsync) (struct inode *, struct file *);
};
struct inode_operations {
......@@ -296,8 +297,17 @@ struct file_system_type {
int requires_dev;
};
extern struct file_operations * chrdev_fops[MAX_CHRDEV];
extern struct file_operations * blkdev_fops[MAX_BLKDEV];
extern int register_blkdev(unsigned int, const char *, struct file_operations *);
extern int blkdev_open(struct inode * inode, struct file * filp);
extern struct file_operations def_blk_fops;
extern struct inode_operations blkdev_inode_operations;
extern int register_chrdev(unsigned int, const char *, struct file_operations *);
extern int chrdev_open(struct inode * inode, struct file * filp);
extern struct file_operations def_chr_fops;
extern struct inode_operations chrdev_inode_operations;
extern struct inode_operations fifo_inode_operations;
extern struct file_system_type *get_fs_type(char *name);
......
......@@ -217,7 +217,7 @@ struct task_struct {
/*
* INIT_TASK is used to set up the first task table, touch at
* your own risk!. Base=0, limit=0x9ffff (=640kB)
* your own risk!. Base=0, limit=0x1fffff (=2MB)
*/
#define INIT_TASK \
/* state etc */ { 0,15,15, \
......@@ -244,8 +244,8 @@ struct task_struct {
/* cloe */ {{ 0, }}, \
{ \
{0,0}, \
/* ldt */ {0x9f,0xc0c0fa00}, \
{0x9f,0xc0c0f200}, \
/* ldt */ {0x1ff,0xc0c0fa00}, \
{0x1ff,0xc0c0f200}, \
}, \
/*tss*/ {0,sizeof(init_kernel_stack) + (long) &init_kernel_stack, \
0x10,0,0,0,0,(long) &swapper_pg_dir,\
......
......@@ -138,6 +138,7 @@ extern int get_tty_queue(struct tty_queue * queue);
#define START_CHAR(tty) ((tty)->termios->c_cc[VSTART])
#define STOP_CHAR(tty) ((tty)->termios->c_cc[VSTOP])
#define SUSPEND_CHAR(tty) ((tty)->termios->c_cc[VSUSP])
#define LNEXT_CHAR(tty) ((tty)->termios->c_cc[VLNEXT])
#define _L_FLAG(tty,f) ((tty)->termios->c_lflag & f)
#define _I_FLAG(tty,f) ((tty)->termios->c_iflag & f)
......@@ -188,7 +189,7 @@ struct tty_struct {
struct termios *termios;
int pgrp;
int session;
unsigned char stopped:1, status_changed:1, packet:1;
unsigned char stopped:1, status_changed:1, packet:1, lnext:1;
unsigned char ctrl_status;
short line;
int disc;
......
......@@ -220,8 +220,13 @@ void start_kernel(void)
if (memory_end > 16*1024*1024)
memory_end = 16*1024*1024;
#endif
memory_start = 1024*1024;
low_memory_start = (unsigned long) &end;
if ((unsigned long)&end >= (1024*1024)) {
memory_start = (unsigned long) &end;
low_memory_start = 4096;
} else {
memory_start = 1024*1024;
low_memory_start = (unsigned long) &end;
}
low_memory_start += 0xfff;
low_memory_start &= 0xfffff000;
memory_start = paging_init(memory_start,memory_end);
......@@ -260,11 +265,14 @@ void start_kernel(void)
*/
if (hard_math) {
unsigned short control_word;
printk("Checking for 387 error mechanism ...");
__asm__("fninit ; fnstcw %0 ; fwait":"=m" (*&control_word));
control_word &= 0xffc0;
__asm__("fldcw %0 ; fwait"::"m" (*&control_word));
outb_p(inb_p(0x21) | (1 << 2), 0x21);
__asm__("fldz ; fld1 ; fdiv %st,%st(1) ; fwait");
printk(" ok, using %s.\n",ignore_irq13?"exception 16":"irq13");
}
move_to_user_mode();
if (!fork()) /* we count on this going ok */
......
......@@ -37,7 +37,7 @@ math.a: $(OBJS)
sync
clean:
rm -f core *.o *.a *.s *~
rm -f core *.o *.a *.s
dep:
$(CPP) -M *.c *.S > .depend
......
......@@ -79,8 +79,10 @@ static void single_arg_error(void)
/* Convert to a QNaN */
FPU_st0_ptr->sigh |= 0x40000000;
}
break; /* return with a NaN in st(0) */
case TW_Empty:
stack_underflow();
stack_underflow(); /* Puts a QNaN in st(0) */
break;
#ifdef PARANOID
default:
EXCEPTION(EX_INTERNAL|0x0112);
......
......@@ -17,7 +17,8 @@
#include "exception.h"
#include "reg_constant.h"
#include "fpu_emu.h"
#include "control_w.h"
#include "fpu_system.h"
void reg_add(FPU_REG *a, FPU_REG *b, FPU_REG *dest)
......@@ -41,28 +42,55 @@ void reg_add(FPU_REG *a, FPU_REG *b, FPU_REG *dest)
{
diff = a->sigh - b->sigh; /* Works only if ms bits are identical */
if (!diff)
diff = a->sigl > b->sigl;
{
diff = a->sigl > b->sigl;
if (!diff)
diff = -(a->sigl < b->sigl);
}
}
if (diff > 0)
{
reg_u_sub(a, b, dest);
dest->sign = a->sign;
return;
}
else if ( diff == 0 )
{
reg_move(&CONST_Z, dest);
/* sign depends upon rounding mode */
dest->sign = ((control_word & CW_RC) != RC_DOWN)
? SIGN_POS : SIGN_NEG;
}
else
{
reg_u_sub(b, a, dest);
dest->sign = b->sign;
return;
}
return;
}
else
{
if ( (a->tag == TW_NaN) || (b->tag == TW_NaN) )
{ real_2op_NaN(a, b, dest); return; }
else if (a->tag == TW_Zero)
{ reg_move(b, dest); return; }
{
if (b->tag == TW_Zero)
{
char different_signs = a->sign ^ b->sign;
/* Both are zero, result will be zero. */
reg_move(a, dest);
if (different_signs)
{
/* Signs are different. */
/* Sign of answer depends upon rounding mode. */
dest->sign = ((control_word & CW_RC) != RC_DOWN)
? SIGN_POS : SIGN_NEG;
}
}
else
reg_move(b, dest);
return;
}
else if (b->tag == TW_Zero)
{ reg_move(a, dest); return; }
else if (a->tag == TW_Infinity)
......@@ -97,7 +125,11 @@ void reg_sub(FPU_REG *a, FPU_REG *b, FPU_REG *dest)
{
diff = a->sigh - b->sigh; /* Works only if ms bits are identical */
if (!diff)
diff = a->sigl > b->sigl;
{
diff = a->sigl > b->sigl;
if (!diff)
diff = -(a->sigl < b->sigl);
}
}
switch (a->sign*2 + b->sign)
......@@ -109,6 +141,13 @@ void reg_sub(FPU_REG *a, FPU_REG *b, FPU_REG *dest)
reg_u_sub(a, b, dest);
dest->sign = a->sign;
}
else if ( diff == 0 )
{
reg_move(&CONST_Z, dest);
/* sign depends upon rounding mode */
dest->sign = ((control_word & CW_RC) != RC_DOWN)
? SIGN_POS : SIGN_NEG;
}
else
{
reg_u_sub(b, a, dest);
......@@ -130,7 +169,23 @@ void reg_sub(FPU_REG *a, FPU_REG *b, FPU_REG *dest)
if ( (a->tag == TW_NaN) || (b->tag == TW_NaN) )
{ real_2op_NaN(a, b, dest); return; }
else if (b->tag == TW_Zero)
{ reg_move(a, dest); return; }
{
if (a->tag == TW_Zero)
{
char same_signs = !(a->sign ^ b->sign);
/* Both are zero, result will be zero. */
reg_move(a, dest); /* Answer for different signs. */
if (same_signs)
{
/* Sign depends upon rounding mode */
dest->sign = ((control_word & CW_RC) != RC_DOWN)
? SIGN_POS : SIGN_NEG;
}
}
else
reg_move(a, dest);
return;
}
else if (a->tag == TW_Zero)
{
reg_move(b, dest);
......
......@@ -8,5 +8,5 @@
| |
+---------------------------------------------------------------------------*/
#define FPU_VERSION "wm-FPU-emu version BETA 1.0"
#define FPU_VERSION "wm-FPU-emu version BETA 1.1"
#ifndef _BLK_H
#define _BLK_H
#define NR_BLK_DEV 12
#include <linux/fs.h>
/*
* NR_REQUEST is the number of entries in the request-queue.
* NOTE that writes may use only the low 2/3 of these: reads
......@@ -62,12 +63,12 @@ struct sec_size {
#define SECTOR_MASK ((1 << (BLOCK_SIZE_BITS - 9)) -1)
#define SUBSECTOR(block) ((block) & SECTOR_MASK)
extern struct sec_size * blk_sec[NR_BLK_DEV];
extern struct blk_dev_struct blk_dev[NR_BLK_DEV];
extern struct sec_size * blk_sec[MAX_BLKDEV];
extern struct blk_dev_struct blk_dev[MAX_BLKDEV];
extern struct request request[NR_REQUEST];
extern struct wait_queue * wait_for_request;
extern int * blk_size[NR_BLK_DEV];
extern int * blk_size[MAX_BLKDEV];
extern unsigned long hd_init(unsigned long mem_start, unsigned long mem_end);
extern int is_read_only(int dev);
......
......@@ -1091,6 +1091,14 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
format_status = FORMAT_NONE;
wake_up(&format_done);
return okay ? 0 : -EIO;
case FDFLUSH:
if (!permission(inode, 2))
return -EPERM;
cli();
fake_change |= 1 << (drive & 3);
sti();
check_disk_change(inode->i_rdev);
return 0;
}
if (!suser())
return -EPERM;
......@@ -1140,7 +1148,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
}
#define CMOS_READ(addr) ({ \
outb_p(0x80|addr,0x70); \
outb_p(addr,0x70); \
inb_p(0x71); \
})
......@@ -1258,9 +1266,12 @@ static struct sigaction floppy_sigaction = {
void floppy_init(void)
{
outb(current_DOR,FD_DOR);
if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
printk("Unable to get major %d for floppy\n",MAJOR_NR);
return;
}
blk_size[MAJOR_NR] = floppy_sizes;
blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
blkdev_fops[MAJOR_NR] = &floppy_fops;
timer_table[FLOPPY_TIMER].fn = floppy_shutdown;
timer_active &= ~(1 << FLOPPY_TIMER);
config_types();
......
......@@ -43,7 +43,7 @@ static int revalidate_hddisk(int, int);
static inline unsigned char CMOS_READ(unsigned char addr)
{
outb_p(0x80|addr,0x70);
outb_p(addr,0x70);
return inb_p(0x71);
}
......@@ -684,8 +684,11 @@ static struct file_operations hd_fops = {
unsigned long hd_init(unsigned long mem_start, unsigned long mem_end)
{
if (register_blkdev(MAJOR_NR,"hd",&hd_fops)) {
printk("Unable to get major %d for harddisk\n",MAJOR_NR);
return mem_start;
}
blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
blkdev_fops[MAJOR_NR] = &hd_fops;
read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read-ahead */
hd_gendisk.next = gendisk_head;
gendisk_head = &hd_gendisk;
......
......@@ -31,13 +31,13 @@ struct wait_queue * wait_for_request = NULL;
/* This specifies how many sectors to read ahead on the disk. */
int read_ahead[NR_BLK_DEV] = {0, };
int read_ahead[MAX_BLKDEV] = {0, };
/* blk_dev_struct is:
* do_request-address
* next-request
*/
struct blk_dev_struct blk_dev[NR_BLK_DEV] = {
struct blk_dev_struct blk_dev[MAX_BLKDEV] = {
{ NULL, NULL }, /* no_dev */
{ NULL, NULL }, /* dev mem */
{ NULL, NULL }, /* dev fd */
......@@ -57,11 +57,11 @@ struct blk_dev_struct blk_dev[NR_BLK_DEV] = {
*
* if (!blk_size[MAJOR]) then no minor size checking is done.
*/
int * blk_size[NR_BLK_DEV] = { NULL, NULL, };
int * blk_size[MAX_BLKDEV] = { NULL, NULL, };
/* RO fail safe mechanism */
static long ro_bits[NR_BLK_DEV][8];
static long ro_bits[MAX_BLKDEV][8];
int is_read_only(int dev)
{
......@@ -69,7 +69,7 @@ int is_read_only(int dev)
major = MAJOR(dev);
minor = MINOR(dev);
if (major < 0 || major >= NR_BLK_DEV) return 0;
if (major < 0 || major >= MAX_BLKDEV) return 0;
return ro_bits[major][minor >> 5] & (1 << (minor & 31));
}
......@@ -79,7 +79,7 @@ void set_device_ro(int dev,int flag)
major = MAJOR(dev);
minor = MINOR(dev);
if (major < 0 || major >= NR_BLK_DEV) return;
if (major < 0 || major >= MAX_BLKDEV) return;
if (flag) ro_bits[major][minor >> 5] |= 1 << (minor & 31);
else ro_bits[major][minor >> 5] &= ~(1 << (minor & 31));
}
......@@ -222,7 +222,7 @@ void ll_rw_page(int rw, int dev, int page, char * buffer)
struct request * req;
unsigned int major = MAJOR(dev);
if (major >= NR_BLK_DEV || !(blk_dev[major].request_fn)) {
if (major >= MAX_BLKDEV || !(blk_dev[major].request_fn)) {
printk("Trying to read nonexistent block-device %04x (%d)\n",dev,page*8);
return;
}
......@@ -289,7 +289,7 @@ void ll_rw_block(int rw, int nr, struct buffer_head * bh[])
}
};
if ((major=MAJOR(bh[0]->b_dev)) >= NR_BLK_DEV ||
if ((major=MAJOR(bh[0]->b_dev)) >= MAX_BLKDEV ||
!(blk_dev[major].request_fn)) {
printk("ll_rw_block: Trying to read nonexistent block-device %04x (%d)\n",bh[0]->b_dev,bh[0]->b_blocknr);
for (i=0;i<nr; i++)
......@@ -332,7 +332,7 @@ void ll_rw_swap_file(int rw, int dev, unsigned int *b, int nb, char *buf)
struct request * req;
unsigned int major = MAJOR(dev);
if (major >= NR_BLK_DEV || !(blk_dev[major].request_fn)) {
if (major >= MAX_BLKDEV || !(blk_dev[major].request_fn)) {
printk("ll_rw_swap_file: trying to swap nonexistent block-device\n\r");
return;
}
......
......@@ -67,8 +67,11 @@ long rd_init(long mem_start, int length)
int i;
char *cp;
if (register_blkdev(MAJOR_NR,"rd",&rd_fops)) {
printk("Unable to get major %d for ramdisk\n",MAJOR_NR);
return 0;
}
blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
blkdev_fops[MAJOR_NR] = &rd_fops;
rd_start = (char *) mem_start;
rd_length = length;
cp = rd_start;
......
/* fdomain.c -- Future Domain TMC-1660/TMC-1680 driver
* Created: Sun May 3 18:53:19 1992 by faith
* Revised: Sun Jan 10 01:23:29 1993 by root
* Revised: Thu Feb 18 21:02:12 1993 by faith@cs.unc.edu
* Author: Rickard E. Faith, faith@cs.unc.edu
* Copyright 1992, 1993 Rickard E. Faith
*
......@@ -108,7 +108,7 @@
#include <asm/system.h>
#include <linux/errno.h>
#define VERSION "3.3" /* Change with each revision */
#define VERSION "3.5" /* Change with each revision */
/* START OF USER DEFINABLE OPTIONS */
......@@ -169,7 +169,6 @@ static int this_host = 0;
static int can_queue = QUEUE;
static volatile int in_command = 0;
static volatile int in_interrupt_code = 0;
static Scsi_Cmnd *current_SC = NULL;
enum { non_queueing = 0x01,
......@@ -646,7 +645,6 @@ void my_done( int error )
{
if (in_command) {
in_command = 0;
in_interrupt_code = 0;
outb( 0x00, Interrupt_Cntl_port );
fdomain_make_bus_idle();
current_SC->result = error;
......@@ -664,14 +662,14 @@ void fdomain_16x0_intr( int unused )
unsigned data_count;
sti();
if (in_interrupt_code)
panic( "SCSI (Future Domain): fdomain_16x0_intr() NOT REENTRANT!\n" );
else
++in_interrupt_code;
outb( 0x00, Interrupt_Cntl_port );
/* We usually have one spurious interrupt after each command. Ignore it. */
if (!in_command || !current_SC) { /* Spurious interrupt */
return;
}
if (current_SC->SCp.phase & aborted) {
#if EVERY_ACCESS
if (current_SC->SCp.phase & (in_other || disconnect))
......@@ -693,12 +691,6 @@ void fdomain_16x0_intr( int unused )
return;
}
/* We usually have one spurious interrupt after each command. Ignore it. */
if (!in_command) { /* Spurious interrupt */
in_interrupt_code = 0;
return;
}
#if RESELECTION
if (current_SC->SCp.phase & disconnect) {
printk( " RECON %x ", inb( SCSI_Data_NoACK_port ) );
......@@ -735,7 +727,6 @@ void fdomain_16x0_intr( int unused )
/* Stop arbitration (also set FIFO for output and enable parity) */
outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
in_interrupt_code = 0;
return;
} else if (current_SC->SCp.phase & in_selection) {
status = inb( SCSI_Status_port );
......@@ -756,7 +747,6 @@ void fdomain_16x0_intr( int unused )
}
}
current_SC->SCp.phase = in_other;
in_interrupt_code = 0;
outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
#if RESELECTION
outb( 0x88, SCSI_Cntl_port );
......@@ -979,7 +969,6 @@ void fdomain_16x0_intr( int unused )
#endif
} else {
in_interrupt_code = 0;
if (current_SC->SCp.phase & disconnect) {
outb( 0xd0 | FIFO_COUNT, Interrupt_Cntl_port );
outb( 0x00, SCSI_Cntl_port );
......@@ -1239,9 +1228,8 @@ int fdomain_16x0_abort( Scsi_Cmnd *SCpnt, int code )
#endif
#if DEBUG_ABORT
printk( "Phase = %d, flag = %d, target = %d cmnd = 0x%02x pieces = %d size = %u\n",
printk( "Phase = %d, target = %d cmnd = 0x%02x pieces = %d size = %u\n",
current_SC->SCp.phase,
in_interrupt_code,
current_SC->target,
*(unsigned char *)current_SC->cmnd,
current_SC->use_sg,
......
......@@ -761,7 +761,10 @@ unsigned long sd_init(unsigned long memory_start, unsigned long memory_end)
{
int i;
blkdev_fops[MAJOR_NR] = &sd_fops; /* to get sd_open in table */
if (register_blkdev(MAJOR_NR,"sd",&sd_fops)) {
printk("Unable to get major %d for SCSI disk\n",MAJOR_NR);
return memory_start;
}
if (MAX_SD == 0) return memory_start;
sd_sizes = (int *) memory_start;
......
......@@ -601,7 +601,10 @@ unsigned long sr_init(unsigned long memory_start, unsigned long memory_end)
{
int i;
blkdev_fops[MAJOR_NR] = &sr_fops;
if (register_blkdev(MAJOR_NR,"sr",&sr_fops)) {
printk("Unable to get major %d for SCSI-CD\n",MAJOR_NR);
return memory_start;
}
if(MAX_SR == 0) return memory_start;
sr_sizes = (int *) memory_start;
......
......@@ -1224,7 +1224,10 @@ unsigned long st_init(unsigned long mem_start, unsigned long mem_end)
{
int i;
chrdev_fops[MAJOR_NR] = &st_fops;
if (register_chrdev(MAJOR_NR,"st",&st_fops)) {
printk("Unable to get major %d for SCSI tapes\n",MAJOR_NR);
return mem_start;
}
if (NR_ST == 0) return mem_start;
#ifdef DEBUG
......
......@@ -506,24 +506,7 @@ void wd7000_revision(void)
}
static const char *wd_bases[] = {
(char *)0xde000,
(char *)0xdc000,
(char *)0xda000,
(char *)0xd8000,
(char *)0xd6000,
(char *)0xd4000,
(char *)0xd2000,
(char *)0xd0000,
(char *)0xce000,
(char *)0xcc000,
(char *)0xca000,
(char *)0xc8000,
(char *)0xc6000,
(char *)0xc4000,
(char *)0xc2000,
(char *)0xc0000
};
static const char *wd_bases[] = {(char *)0xce000};
typedef struct {
char * signature;
unsigned offset;
......
......@@ -226,8 +226,8 @@ static char * translations[] = {
"\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",
/* IBM grapgics: minimal translations (CR, LF, LL and ESC) */
"\000\001\002\003\004\005\006\007\010\011\000\013\000\000\016\017"
/* IBM grapgics: minimal translations (CR, LF, LL, SO, SI and ESC) */
"\000\001\002\003\004\005\006\007\010\011\000\013\000\000\000\000"
"\020\021\022\023\024\025\026\027\030\031\032\000\034\035\036\037"
"\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057"
"\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077"
......
......@@ -154,7 +154,7 @@ static void put_queue(int ch)
struct tty_queue *qp;
unsigned long new_head;
wake_up_interruptible(&keypress_wait);
wake_up(&keypress_wait);
if (!tty)
return;
qp = &tty->read_q;
......
......@@ -233,7 +233,8 @@ long lp_init(long kmem_start)
unsigned int testvalue = 0;
int count = 0;
chrdev_fops[6] = &lp_fops;
if (register_chrdev(6,"lp",&lp_fops))
printk("unable to get major 6 for line printer\n");
/* take on all known port values */
for (offset = 0; offset < LP_NO; offset++) {
/* write to port & read back to check */
......
......@@ -336,7 +336,8 @@ static struct file_operations memory_fops = {
long chr_dev_init(long mem_start, long mem_end)
{
chrdev_fops[1] = &memory_fops;
if (register_chrdev(1,"mem",&memory_fops))
printk("unable to get major 1 for memory devs\n");
mem_start = tty_init(mem_start);
mem_start = lp_init(mem_start);
mem_start = mouse_init(mem_start);
......
......@@ -18,6 +18,7 @@
#include <linux/errno.h>
#include <linux/mouse.h>
#include <linux/config.h>
#include <linux/kernel.h>
/*
* note that you can remove any or all of the drivers by undefining
......@@ -90,6 +91,7 @@ unsigned long mouse_init(unsigned long kmem_start)
#ifdef CONFIG_ATIXL_BUSMOUSE
kmem_start = atixl_busmouse_init(kmem_start);
#endif
chrdev_fops[10] = &mouse_fops;
if (register_chrdev(10,"mouse",&mouse_fops))
printk("unable to get major 10 for mouse devices\n");
return kmem_start;
}
......@@ -524,7 +524,6 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
if (info->blocked_open) {
shutdown(info);
startup(info);
wake_up_interruptible(&info->open_wait);
return;
}
if (info->flags & ASYNC_INITIALIZED) {
......@@ -737,7 +736,8 @@ static int set_serial_info(struct async_struct * info,
}
info->baud_base = new.baud_base;
info->flags = new.flags & ASYNC_FLAGS;
info->flags = ((info->flags & ~ASYNC_FLAGS) |
(new.flags & ASYNC_FLAGS));
info->custom_divisor = new.custom_divisor;
info->type = new.type;
......@@ -1275,7 +1275,7 @@ long rs_init(long kmem_start)
init(info);
if (info->type == PORT_UNKNOWN)
continue;
printk("ttyS%d%s at 0x%04x (irq = %d)", info->line,
printk("tty%02d%s at 0x%04x (irq = %d)", info->line,
(info->flags & ASYNC_FOURPORT) ? " FourPort" : "",
info->port, info->irq);
switch (info->type) {
......
......@@ -213,6 +213,7 @@ static struct file_operations hung_up_tty_fops = {
void tty_hangup(struct tty_struct * tty)
{
struct file * filp;
struct task_struct **p;
int dev;
if (!tty)
......@@ -233,6 +234,12 @@ void tty_hangup(struct tty_struct * tty)
wake_up_interruptible(&tty->write_q.proc_list);
if (tty->session > 0)
kill_sl(tty->session,SIGHUP,1);
tty->session = 0;
tty->pgrp = -1;
for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
if ((*p) && (*p)->tty == tty->line)
(*p)->tty = -1;
}
}
void tty_unhangup(struct file *filp)
......@@ -463,9 +470,10 @@ void copy_to_cooked(struct tty_struct * tty)
c=13;
if (I_UCLC(tty))
c=tolower(c);
if (L_CANON(tty)) {
if ((KILL_CHAR(tty) != __DISABLED_CHAR) &&
(c==KILL_CHAR(tty))) {
if (c == __DISABLED_CHAR)
tty->lnext = 1;
if (L_CANON(tty) && !tty->lnext) {
if (c == KILL_CHAR(tty)) {
/* deal with killing the input line */
while(!(EMPTY(&tty->secondary) ||
(c=LAST(&tty->secondary))==10 ||
......@@ -485,8 +493,7 @@ void copy_to_cooked(struct tty_struct * tty)
}
continue;
}
if ((ERASE_CHAR(tty) != __DISABLED_CHAR) &&
(c==ERASE_CHAR(tty))) {
if (c == ERASE_CHAR(tty)) {
if (EMPTY(&tty->secondary) ||
(c=LAST(&tty->secondary))==10 ||
((EOF_CHAR(tty) != __DISABLED_CHAR) &&
......@@ -505,39 +512,42 @@ void copy_to_cooked(struct tty_struct * tty)
DEC(tty->secondary.head);
continue;
}
if (c == LNEXT_CHAR(tty)) {
tty->lnext = 1;
if (L_ECHO(tty)) {
put_tty_queue('^',&tty->write_q);
put_tty_queue(8,&tty->write_q);
}
continue;
}
}
if (I_IXON(tty)) {
if ((STOP_CHAR(tty) != __DISABLED_CHAR) &&
(c==STOP_CHAR(tty))) {
if (I_IXON(tty) && !tty->lnext) {
if (c == STOP_CHAR(tty)) {
tty->status_changed = 1;
tty->ctrl_status |= TIOCPKT_STOP;
tty->stopped=1;
continue;
}
if (((I_IXANY(tty)) && tty->stopped) ||
((START_CHAR(tty) != __DISABLED_CHAR) &&
(c==START_CHAR(tty)))) {
(c == START_CHAR(tty))) {
tty->status_changed = 1;
tty->ctrl_status |= TIOCPKT_START;
tty->stopped=0;
continue;
}
}
if (L_ISIG(tty)) {
if ((INTR_CHAR(tty) != __DISABLED_CHAR) &&
(c==INTR_CHAR(tty))) {
if (L_ISIG(tty) && !tty->lnext) {
if (c == INTR_CHAR(tty)) {
kill_pg(tty->pgrp, SIGINT, 1);
flush_input(tty);
continue;
}
if ((QUIT_CHAR(tty) != __DISABLED_CHAR) &&
(c==QUIT_CHAR(tty))) {
if (c == QUIT_CHAR(tty)) {
kill_pg(tty->pgrp, SIGQUIT, 1);
flush_input(tty);
continue;
}
if ((SUSPEND_CHAR(tty) != __DISABLED_CHAR) &&
(c==SUSPEND_CHAR(tty))) {
if (c == SUSPEND_CHAR(tty)) {
if (!is_orphaned_pgrp(tty->pgrp))
kill_pg(tty->pgrp, SIGTSTP, 1);
continue;
......@@ -553,9 +563,15 @@ void copy_to_cooked(struct tty_struct * tty)
if (c<32 && L_ECHOCTL(tty)) {
put_tty_queue('^',&tty->write_q);
put_tty_queue(c+64, &tty->write_q);
if (EOF_CHAR(tty) != __DISABLED_CHAR &&
c==EOF_CHAR(tty) && !tty->lnext) {
put_tty_queue(8,&tty->write_q);
put_tty_queue(8,&tty->write_q);
}
} else
put_tty_queue(c, &tty->write_q);
}
tty->lnext = 0;
put_tty_queue(c, &tty->secondary);
}
TTY_WRITE_FLUSH(tty);
......@@ -644,6 +660,10 @@ static int read_chan(struct tty_struct * tty, struct file * file, char * buf, in
}
add_wait_queue(&tty->secondary.proc_list, &wait);
while (nr>0) {
if (hung_up(file)) {
file->f_flags &= ~O_NONBLOCK;
break; /* force read() to return 0 */
}
TTY_READ_FLUSH(tty);
if (tty->link)
TTY_WRITE_FLUSH(tty->link);
......@@ -680,8 +700,6 @@ static int read_chan(struct tty_struct * tty, struct file * file, char * buf, in
TTY_WRITE_FLUSH(tty->link);
if (!EMPTY(&tty->secondary))
continue;
if (hung_up(file))
break;
current->state = TASK_INTERRUPTIBLE;
if (EMPTY(&tty->secondary))
schedule();
......@@ -819,7 +837,8 @@ static int tty_read(struct inode * inode, struct file * file, char * buf, int co
tty = TTY_TABLE(dev);
if (!tty || (tty->flags & (1 << TTY_IO_ERROR)))
return -EIO;
if (MINOR(inode->i_rdev) && (tty->pgrp > 0) &&
if ((inode->i_rdev != 0x0400) && /* don't stop on /dev/console */
(tty->pgrp > 0) &&
(current->tty == dev) &&
(tty->pgrp != current->pgrp))
if (is_ignored(SIGTTIN) || is_orphaned_pgrp(current->pgrp))
......@@ -1391,9 +1410,10 @@ long tty_init(long kmem_start)
if (sizeof(struct tty_struct) > 4096)
panic("size of tty structure > 4096!");
chrdev_fops[4] = &tty_fops;
chrdev_fops[5] = &tty_fops;
if (register_chrdev(4,"tty",&tty_fops))
panic("unable to get major 4 for tty device");
if (register_chrdev(5,"tty",&tty_fops))
panic("unable to get major 5 for tty device");
for (i=0 ; i< MAX_TTYS ; i++) {
tty_table[i] = 0;
tty_termios[i] = 0;
......
......@@ -917,6 +917,7 @@ void mem_init(unsigned long start_low_mem,
int datapages = 0;
unsigned long tmp;
unsigned short * p;
extern int etext;
cli();
end_mem &= 0xfffff000;
......@@ -946,10 +947,10 @@ void mem_init(unsigned long start_low_mem,
nr_free_pages = 0;
for (tmp = 0 ; tmp < end_mem ; tmp += 4096) {
if (mem_map[MAP_NR(tmp)]) {
if (tmp < 0xA0000)
codepages++;
else if (tmp < 0x100000)
if (tmp >= 0xA0000 && tmp < 0x100000)
reservedpages++;
else if (tmp < (unsigned long) &etext)
codepages++;
else
datapages++;
continue;
......@@ -959,7 +960,7 @@ void mem_init(unsigned long start_low_mem,
nr_free_pages++;
}
tmp = nr_free_pages << PAGE_SHIFT;
printk("Memory: %dk/%dk available (%dk kernel, %dk reserved, %dk data)\n",
printk("Memory: %dk/%dk available (%dk kernel code, %dk reserved, %dk data)\n",
tmp >> 10,
end_mem >> 10,
codepages << 2,
......
......@@ -481,6 +481,8 @@ dev_tint( struct device *dev)
sti();
/* this will send it through the process again. */
dev->queue_xmit (skb, dev, -i-1);
if (dev->tbusy)
return;
}
}
}
......@@ -834,7 +834,7 @@ ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
PRINTK(("\nIP: *** datagram routing not yet implemented ***\n"));
PRINTK((" SRC = %s ", in_ntoa(iph->saddr)));
PRINTK((" DST = %s (ignored)\n", in_ntoa(iph->daddr)));
icmp_reply (skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, dev);
/* icmp_reply (skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, dev); */
skb->sk = NULL;
kfree_skb(skb, 0);
......
......@@ -29,6 +29,7 @@
#include <unistd.h> /* contains read/write */
#include <fcntl.h>
#include <linux/config.h>
#include <linux/a.out.h>
#define MINIX_HEADER 32
#define GCC_HEADER 1024
......@@ -83,8 +84,9 @@ void usage(void)
int main(int argc, char ** argv)
{
int i,c,id;
int i,c,id, sz;
char buf[1024];
struct exec *ex = (struct exec *)buf;
char major_root, minor_root;
struct stat sb;
......@@ -116,9 +118,9 @@ int main(int argc, char ** argv)
die("Non-Minix header of 'boot'");
if (((long *) buf)[1]!=intel_long(MINIX_HEADER))
die("Non-Minix header of 'boot'");
if (((long *) buf)[3]!=0)
if (((long *) buf)[3] != 0)
die("Illegal data segment in 'boot'");
if (((long *) buf)[4]!=0)
if (((long *) buf)[4] != 0)
die("Illegal bss in 'boot'");
if (((long *) buf)[5] != 0)
die("Non-Minix header of 'boot'");
......@@ -145,9 +147,9 @@ int main(int argc, char ** argv)
die("Non-Minix header of 'setup'");
if (((long *) buf)[1]!=intel_long(MINIX_HEADER))
die("Non-Minix header of 'setup'");
if (((long *) buf)[3]!=0)
if (((long *) buf)[3] != 0)
die("Illegal data segment in 'setup'");
if (((long *) buf)[4]!=0)
if (((long *) buf)[4] != 0)
die("Illegal bss in 'setup'");
if (((long *) buf)[5] != 0)
die("Non-Minix header of 'setup'");
......@@ -156,6 +158,8 @@ int main(int argc, char ** argv)
for (i=0 ; (c=read(id,buf,sizeof buf))>0 ; i+=c )
if (write(1,buf,c)!=c)
die("Write call failed");
if (c != 0)
die("read-error on 'setup'");
close (id);
if (i > SETUP_SECTS*512)
die("Setup exceeds " STRINGIFY(SETUP_SECTS)
......@@ -176,14 +180,28 @@ int main(int argc, char ** argv)
die("Unable to open 'system'");
if (read(id,buf,GCC_HEADER) != GCC_HEADER)
die("Unable to read header of 'system'");
if (((long *) buf)[5] != 0)
if (N_MAGIC(*ex) != ZMAGIC)
die("Non-GCC header of 'system'");
for (i=0 ; (c=read(id,buf,sizeof buf))>0 ; i+=c )
if (write(1,buf,c)!=c)
die("Write call failed");
close(id);
fprintf(stderr,"System is %d bytes.\n",i);
if (i > SYS_SIZE*16)
sz = N_SYMOFF(*ex) - GCC_HEADER + 4;
fprintf(stderr,"System is %d bytes.\n", sz);
if (sz > SYS_SIZE*16)
die("System is too big");
while (sz > 0) {
int l, n;
l = sz;
if (l > sizeof(buf))
l = sizeof(buf);
if ((n=read(id, buf, l)) != l) {
if (n == -1)
perror(argv[1]);
else
fprintf(stderr, "Unexpected EOF\n");
die("Can't read 'system'");
}
write(1, buf, l);
sz -= l;
}
close(id);
return(0);
}
HEAD = head.o
SYSTEM = ../tools/zSystem
#LD = gcc
#TEST = -DTEST_DRIVER
zOBJECTS = $(HEAD) inflate.o unzip.o misc.o
CFLAGS = -O6 -DSTDC_HEADERS $(TEST)
.c.s:
$(CC) $(CFLAGS) -S -o $*.s $<
.s.o:
$(AS) -c -o $*.o $<
.c.o:
$(CC) $(CFLAGS) -c -o $*.o $<
all: zSystem
zSystem: piggy.o $(zOBJECTS)
$(LD) $(LDFLAGS) -o zSystem $(zOBJECTS) piggy.o
head.o: head.s
head.s: head.S ../include/linux/tasks.h
$(CPP) -traditional head.S -o head.s
piggy.s: $(SYSTEM) xtract piggyback
./xtract $(SYSTEM) | gzip -9 | ./piggyback > piggy.s
$(SYSTEM):
cd ..;make tools/zSystem
clean:
-rm -f *.o *.s zSystem core piggy.* xtract piggyback
/* crypt.h (dummy version) -- do not perform encrytion
* Hardly worth copyrighting :-)
*/
#ifdef CRYPT
# undef CRYPT /* dummy version */
#endif
#define RAND_HEAD_LEN 12 /* length of encryption random header */
#define zencode
#define zdecode
/* gzip.h -- common declarations for all gzip modules
* Copyright (C) 1992-1993 Jean-loup Gailly.
* This is free software; you can redistribute it and/or modify it under the
* terms of the GNU General Public License, see the file COPYING.
*/
#if defined(__STDC__) || defined(PROTO)
# define OF(args) args
#else
# define OF(args) ()
#endif
#ifdef __STDC__
typedef void *voidp;
#else
typedef char *voidp;
#endif
/* I don't like nested includes, but the string functions are used too often */
#if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
# include <string.h>
# define memzero(s, n) memset ((s), 0, (n))
#else
# include <strings.h>
# define strchr index
# define strrchr rindex
# define memcpy(d, s, n) bcopy((s), (d), (n))
# define memcmp(s1, s2, n) bcmp((s1), (s2), (n))
# define memzero(s, n) bzero((s), (n))
#endif
#if !defined(STDC_HEADERS) && defined(HAVE_MEMORY_H)
# include <memory.h>
#endif
#ifndef RETSIGTYPE
# define RETSIGTYPE void
#endif
#define local static
typedef unsigned char uch;
typedef unsigned short ush;
typedef unsigned long ulg;
/* Return codes from gzip */
#define OK 0
#define ERROR 1
#define WARNING 2
/* Compression methods (see algorithm.doc) */
#define STORED 0
#define COMPRESSED 1
#define PACKED 2
/* methods 3 to 7 reserved */
#define DEFLATED 8
extern int method; /* compression method */
/* To save memory for 16 bit systems, some arrays are overlayed between
* the various modules:
* deflate: prev+head window d_buf l_buf outbuf
* unlzw: tab_prefix tab_suffix stack inbuf outbuf
* inflate: window inbuf
* unpack: window inbuf
* For compression, input is done in window[]. For decompression, output
* is done in window except for unlzw.
*/
#ifndef INBUFSIZ
# define INBUFSIZ 0x8000 /* input buffer size */
#endif
#define INBUF_EXTRA 64 /* required by unlzw() */
#ifndef OUTBUFSIZ
# define OUTBUFSIZ 16384 /* output buffer size */
#endif
#define OUTBUF_EXTRA 2048 /* required by unlzw() */
#define DIST_BUFSIZE 0x8000 /* buffer for distances, see trees.c */
#ifdef DYN_ALLOC
# define EXTERN(type, array) extern type * near array
# define DECLARE(type, array, size) type * near array
# define ALLOC(type, array, size) { \
array = (type*)fcalloc((unsigned)(((size)+1L)/2), 2*sizeof(type)); \
if (array == NULL) error("insufficient memory"); \
}
# define FREE(array) {if (array != NULL) fcfree(array), array=NULL;}
#else
# define EXTERN(type, array) extern type array[]
# define DECLARE(type, array, size) type array[size]
# define ALLOC(type, array, size)
# define FREE(array)
#endif
EXTERN(uch, inbuf); /* input buffer */
EXTERN(uch, outbuf); /* output buffer */
EXTERN(ush, d_buf); /* buffer for distances, see trees.c */
EXTERN(uch, window); /* Sliding window and suffix table (unlzw) */
#define tab_suffix window
#ifndef MAXSEG_64K
# define tab_prefix prev /* hash link (see deflate.c) */
# define head (prev+WSIZE) /* hash head (see deflate.c) */
EXTERN(ush, tab_prefix); /* prefix code (see unlzw.c) */
#else
# define tab_prefix0 prev
# define head tab_prefix1
EXTERN(ush, tab_prefix0); /* prefix for even codes */
EXTERN(ush, tab_prefix1); /* prefix for odd codes */
#endif
extern unsigned insize; /* valid bytes in inbuf */
extern unsigned inptr; /* index of next byte to be processed in inbuf */
extern unsigned outcnt; /* bytes in output buffer */
extern long bytes_in; /* number of input bytes */
extern long bytes_out; /* number of output bytes */
extern long overhead; /* number of bytes in gzip header */
#define isize bytes_in
/* for compatibility with old zip sources (to be cleaned) */
extern int ifd; /* input file descriptor */
extern int ofd; /* output file descriptor */
extern char ifname[]; /* input filename or "stdin" */
extern char ofname[]; /* output filename or "stdout" */
extern ulg time_stamp; /* original time stamp (modification time) */
extern long ifile_size; /* input file size, -1 for devices (debug only) */
extern int exit_code; /* program exit code */
typedef int file_t; /* Do not use stdio */
#define NO_FILE (-1) /* in memory compression */
#define GZIP_MAGIC "\037\213" /* Magic header for gzip files, 1F 8B */
#define OLD_GZIP_MAGIC "\037\236" /* Magic header for gzip 0.5 = freeze 1.x */
#define PKZIP_MAGIC "PK\003\004" /* Magic header for pkzip files */
#define PACK_MAGIC "\037\036" /* Magic header for packed files */
/* gzip flag byte */
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
#define COMMENT 0x10 /* bit 4 set: file comment present */
#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
#define RESERVED 0xC0 /* bit 6,7: reserved */
/* internal file attribute */
#define UNKNOWN (-1)
#define BINARY 0
#define ASCII 1
#ifndef WSIZE
# define WSIZE 0x8000 /* window size--must be a power of two, and */
#endif /* at least 32K for zip's deflate method */
#define MIN_MATCH 3
#define MAX_MATCH 258
/* The minimum and maximum match lengths */
#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
/* Minimum amount of lookahead, except at the end of the input file.
* See deflate.c for comments about the MIN_MATCH+1.
*/
#define MAX_DIST (WSIZE-MIN_LOOKAHEAD)
/* In order to simplify the code, particularly on 16 bit machines, match
* distances are limited to MAX_DIST instead of WSIZE.
*/
extern int decrypt; /* flag to turn on decryption */
extern int save_orig_name; /* set if original name must be saved */
extern int verbose; /* be verbose (-v) */
extern int level; /* compression level */
extern int test; /* check .z file integrity */
extern int to_stdout; /* output to stdout (-c) */
#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
/* put_byte is used for the compressed output, put_char for the
* uncompressed output. However unlzw() uses window for its
* suffix table instead of its output buffer, so it does not use put_char.
* (to be cleaned up).
*/
#define put_byte(c) {outbuf[outcnt++]=(uch)(c); if (outcnt==OUTBUFSIZ)\
flush_outbuf();}
#define put_char(c) {window[outcnt++]=(uch)(c); if (outcnt==WSIZE)\
flush_window();}
/* Output a 16 bit value, lsb first */
#define put_short(w) \
{ if (outcnt < OUTBUFSIZ-2) { \
outbuf[outcnt++] = (uch) ((w) & 0xff); \
outbuf[outcnt++] = (uch) ((ush)(w) >> 8); \
} else { \
put_byte((uch)((w) & 0xff)); \
put_byte((uch)((ush)(w) >> 8)); \
} \
}
/* Output a 32 bit value to the bit stream, lsb first */
#define put_long(n) { \
put_short((n) & 0xffff); \
put_short(((ulg)(n)) >> 16); \
}
#define seekable() 0 /* force sequential output */
#define translate_eol 0 /* no option -a yet */
#define tolow(c) (isupper(c) ? (c)-'A'+'a' : (c)) /* force to lower case */
/* Macros for getting two-byte and four-byte header values */
#define SH(p) ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8))
#define LG(p) ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16))
/* Diagnostic functions */
#ifdef DEBUG
# define Assert(cond,msg) {if(!(cond)) error(msg);}
# define Trace(x) fprintf x
# define Tracev(x) {if (verbose) fprintf x ;}
# define Tracevv(x) {if (verbose>1) fprintf x ;}
# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
#else
# define Assert(cond,msg)
# define Trace(x)
# define Tracev(x)
# define Tracevv(x)
# define Tracec(c,x)
# define Tracecv(c,x)
#endif
/* in zip.c: */
extern void zip OF((int in, int out));
extern int file_read OF((char *buf, unsigned size));
/* in unzip.c */
extern void unzip OF((int in, int out));
extern int check_zipfile OF((int in));
/* in unpack.c */
extern void unpack OF((int in, int out));
/* in gzip.c */
RETSIGTYPE abort_gzip OF((void));
/* in deflate.c */
void lm_init OF((int pack_level, ush *flags));
ulg deflate OF((void));
/* in trees.c */
void ct_init OF((ush *attr, int *method));
int ct_tally OF((int dist, int lc));
ulg flush_block OF((char *buf, ulg stored_len, int eof));
/* in bits.c */
void bi_init OF((file_t zipfile));
void send_bits OF((int value, int length));
unsigned bi_reverse OF((unsigned value, int length));
void bi_windup OF((void));
void copy_block OF((char *buf, unsigned len, int header));
extern int (*read_buf) OF((char *buf, unsigned size));
/* in util.c: */
extern ulg updcrc OF((uch *s, unsigned n));
extern void clear_bufs OF((void));
extern int fill_inbuf OF((void));
extern void flush_outbuf OF((void));
extern void flush_window OF((void));
extern char *strlwr OF((char *s));
extern char *basename OF((char *fname));
extern char *add_envopt OF((int *argcp, char ***argvp, char *env));
extern void error OF((char *m));
extern void warn OF((char *a, char *b));
extern void read_error OF((void));
extern void write_error OF((void));
extern void display_ratio OF((long num, long den));
extern voidp xmalloc OF((unsigned int size));
/* in inflate.c */
extern int inflate OF((void));
/*
* linux/boot/head.s
*
* Copyright (C) 1991, 1992, 1993 Linus Torvalds
*/
/*
* head.s contains the 32-bit startup code.
*
* NOTE!!! Startup happens at absolute address 0x00000000, which is also where
* the page directory will exist. The startup code will be overwritten by
* the page directory.
*/
.text
startup_32:
cld
cli
movl $0x10,%eax
mov %ax,%ds
mov %ax,%es
mov %ax,%fs
mov %ax,%gs
lss _stack_start,%esp
xorl %eax,%eax
1: incl %eax # check that A20 really IS enabled
movl %eax,0x000000 # loop forever if it isn't
cmpl %eax,0x100000
je 1b
/*
* Initialize eflags. Some BIOS's leave bits like NT set. This would
* confuse the debugger if this code is traced.
* XXX - best to initialize before switching to protected mode.
*/
pushl $0
popfl
call _decompress_kernel
ljmp $0x08, $0x100000
This diff is collapsed.
/* lzw.h -- define the lzw functions.
* Copyright (C) 1992-1993 Jean-loup Gailly.
* This is free software; you can redistribute it and/or modify it under the
* terms of the GNU General Public License, see the file COPYING.
*/
#if !defined(OF) && defined(lint)
# include "gzip.h"
#endif
#ifndef BITS
# define BITS 16
#endif
#define INIT_BITS 9 /* Initial number of bits per code */
#define LZW_MAGIC "\037\235" /* Magic header for lzw files, 1F 9D */
#define BIT_MASK 0x1f /* Mask for 'number of compresssion bits' */
/* Mask 0x20 is reserved to mean a fourth header byte, and 0x40 is free.
* It's a pity that old uncompress does not check bit 0x20. That makes
* extension of the format actually undesirable because old compress
* would just crash on the new format instead of giving a meaningful
* error message. It does check the number of bits, but it's more
* helpful to say "unsupported format, get a new version" than
* "can only handle 16 bits".
*/
#define BLOCK_MODE 0x80
/* Block compresssion: if table is full and compression rate is dropping,
* clear the dictionary.
*/
#define LZW_RESERVED 0x60 /* reserved bits */
#define CLEAR 256 /* flush the dictionary */
#define FIRST (CLEAR+1) /* first free entry */
extern int maxbits; /* max bits per code for LZW */
extern int block_mode; /* block compress mode -C compatible with 2.0 */
extern void lzw OF((int in, int out));
extern void unlzw OF((int in, int out));
This diff is collapsed.
#include <stdio.h>
int main(int argc, char *argv[])
{
int c, n=0, len=0;
printf(
".globl _input_data\n"
".data\n"
"_input_data:\n");
while ((c=getchar()) != EOF)
{
len++;
if (!n) printf("\n.byte "); else printf(",");
printf("%d", c);
n = (n+1) & 0x1f;
}
printf("\n\n");
fprintf(stderr, "Compressed size %d.\n", len);
printf( ".globl _input_len\n"
".align 2\n"
"_input_len:\n"
"\t.long %d\n", len);
exit(0);
}
/* unzip.c -- decompress files in gzip or pkzip format.
* Copyright (C) 1992-1993 Jean-loup Gailly
* This is free software; you can redistribute it and/or modify it under the
* terms of the GNU General Public License, see the file COPYING.
*
* The code in this file is derived from the file funzip.c written
* and put in the public domain by Mark Adler.
*/
/*
This version can extract files in gzip or pkzip format.
For the latter, only the first entry is extracted, and it has to be
either deflated or stored.
*/
#ifndef lint
static char rcsid[] = "$Id: unzip.c,v 0.9 1993/02/10 16:07:22 jloup Exp $";
#endif
/* #include "tailor.h" */
#include "gzip.h"
#include "crypt.h"
#include <stdio.h>
/* PKZIP header definitions */
#define LOCSIG 0x04034b50L /* four-byte lead-in (lsb first) */
#define LOCFLG 6 /* offset of bit flag */
#define CRPFLG 1 /* bit for encrypted entry */
#define EXTFLG 8 /* bit for extended local header */
#define LOCHOW 8 /* offset of compression method */
#define LOCTIM 10 /* file mod time (for decryption) */
#define LOCCRC 14 /* offset of crc */
#define LOCSIZ 18 /* offset of compressed size */
#define LOCLEN 22 /* offset of uncompressed length */
#define LOCFIL 26 /* offset of file name field length */
#define LOCEXT 28 /* offset of extra field length */
#define LOCHDR 30 /* size of local header, including sig */
#define EXTHDR 16 /* size of extended local header, inc sig */
/* Globals */
int decrypt; /* flag to turn on decryption */
char *key; /* not used--needed to link crypt.c */
int pkzip = 0; /* set for a pkzip file */
int extended = 0; /* set if extended local header */
/* ===========================================================================
* Check zip file and advance inptr to the start of the compressed data.
* Get ofname from the local header if necessary.
*/
int check_zipfile(in)
int in; /* input file descriptors */
{
uch *h = inbuf + inptr; /* first local header */
/* ifd = in; */
/* Check validity of local header, and skip name and extra fields */
inptr += LOCHDR + SH(h + LOCFIL) + SH(h + LOCEXT);
if (inptr > insize || LG(h) != LOCSIG) {
error("input not a zip file or empty");
}
method = h[LOCHOW];
if (method != STORED && method != DEFLATED) {
error("first entry not deflated or stored--can't extract");
}
/* If entry encrypted, decrypt and validate encryption header */
if ((decrypt = h[LOCFLG] & CRPFLG) != 0) {
error("encrypted file, not yet supported.\n");
exit_code = ERROR;
return -1;
}
/* Save flags for unzip() */
extended = (h[LOCFLG] & EXTFLG) != 0;
pkzip = 1;
/* Get ofname and time stamp from local header (to be done) */
return 0;
}
/* ===========================================================================
* Unzip in to out. This routine works on both gzip and pkzip files.
*
* IN assertions: the buffer inbuf contains already the beginning of
* the compressed data, from offsets inptr to insize-1 included.
* The magic header has already been checked. The output buffer is cleared.
*/
void unzip(in, out)
int in, out; /* input and output file descriptors */
{
ulg orig_crc = 0; /* original crc */
ulg orig_len = 0; /* original uncompressed length */
int n;
uch buf[EXTHDR]; /* extended local header */
/* ifd = in;
ofd = out; */
updcrc(NULL, 0); /* initialize crc */
if (pkzip && !extended) { /* crc and length at the end otherwise */
orig_crc = LG(inbuf + LOCCRC);
orig_len = LG(inbuf + LOCLEN);
}
/* Decompress */
if (method == DEFLATED) {
int res = inflate();
if (res == 3) {
error("out of memory");
} else if (res != 0) {
error("invalid compressed data--format violated");
}
} else if (pkzip && method == STORED) {
register ulg n = LG(inbuf + LOCLEN);
if (n != LG(inbuf + LOCSIZ) - (decrypt ? RAND_HEAD_LEN : 0)) {
error("invalid compressed data--length mismatch");
}
while (n--) {
uch c = (uch)get_byte();
#ifdef CRYPT
if (decrypt) zdecode(c);
#endif
if (!test) put_char(c);
}
} else {
error("internal error, invalid method");
}
/* Get the crc and original length */
if (!pkzip) {
/* crc32 (see algorithm.doc)
* uncompressed input size modulo 2^32
*/
for (n = 0; n < 8; n++) {
buf[n] = (uch)get_byte(); /* may cause an error if EOF */
}
orig_crc = LG(buf);
orig_len = LG(buf+4);
} else if (extended) { /* If extended header, check it */
/* signature - 4bytes: 0x50 0x4b 0x07 0x08
* CRC-32 value
* compressed size 4-bytes
* uncompressed size 4-bytes
*/
for (n = 0; n < EXTHDR; n++) {
buf[n] = (uch)get_byte(); /* may cause an error if EOF */
}
orig_crc = LG(buf+4);
orig_len = LG(buf+12);
}
/* Validate decompression */
if (orig_crc != updcrc(outbuf, 0)) {
error("invalid compressed data--crc error");
}
if (orig_len != bytes_out) {
error("invalid compressed data--length error");
}
/* Check if there are more entries in a pkzip file */
if (pkzip && inptr + 4 < insize && LG(inbuf+inptr) == LOCSIG) {
error("zip file has more than one entry");
}
extended = pkzip = 0; /* for next file */
}
/*
* linux/tools/build.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
* This file builds a disk-image from three different files:
*
* - bootsect: max 510 bytes of 8086 machine code, loads the rest
* - setup: max 4 sectors of 8086 machine code, sets up system parm
* - system: 80386 code for actual system
*
* It does some checking that all files are of the correct type, and
* just writes the result to stdout, removing headers and padding to
* the right amount. It also writes some system data to stderr.
*/
/*
* Changes by tytso to allow root device specification
*/
#include <stdio.h> /* fprintf */
#include <string.h>
#include <stdlib.h> /* contains exit */
#include <sys/types.h> /* unistd.h needs this */
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <unistd.h> /* contains read/write */
#include <fcntl.h>
#include <a.out.h>
#include <linux/config.h>
#define GCC_HEADER 1024
#define STRINGIFY(x) #x
void die(char * str)
{
fprintf(stderr,"%s\n",str);
exit(1);
}
void usage(void)
{
die("Usage: xtract system [ | gzip | piggyback > piggy.s]");
}
int main(int argc, char ** argv)
{
int i,c,id, sz;
char buf[1024];
char major_root, minor_root;
struct stat sb;
struct exec *ex = (struct exec *)buf;
if (argc != 2)
usage();
if ((id=open(argv[1],O_RDONLY,0))<0)
die("Unable to open 'system'");
if (read(id,buf,GCC_HEADER) != GCC_HEADER)
die("Unable to read header of 'system'");
if (N_MAGIC(*ex) != ZMAGIC)
die("Non-GCC header of 'system'");
sz = N_SYMOFF(*ex) - GCC_HEADER + 4; /* +4 to get the same result than tools/build */
fprintf(stderr, "System size is %d\n", sz);
while (sz)
{
int l, n;
l = sz;
if (l > sizeof(buf)) l = sizeof(buf);
if ((n=read(id, buf, l)) !=l)
{
if (n == -1)
perror(argv[1]);
else
fprintf(stderr, "Unexpected EOF\n");
die("Can't read system");
}
write(1, buf, l);
sz -= l;
}
close(id);
return(0);
}
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