Commit d80e0e9b authored by Linus Torvalds's avatar Linus Torvalds

Import 0.99.14d

parent 39b3ec53
VERSION = 0.99 VERSION = 0.99
PATCHLEVEL = 14 PATCHLEVEL = 14
ALPHA = c ALPHA = d
all: Version zImage all: Version zImage
......
...@@ -974,6 +974,7 @@ void con_write(struct tty_struct * tty) ...@@ -974,6 +974,7 @@ void con_write(struct tty_struct * tty)
if (!EMPTY(&tty->write_q) && currcons == sel_cons) if (!EMPTY(&tty->write_q) && currcons == sel_cons)
clear_selection(); clear_selection();
#endif /* CONFIG_SELECTION */ #endif /* CONFIG_SELECTION */
disable_bh(KEYBOARD_BH);
while (!tty->stopped && (c = get_tty_queue(&tty->write_q)) >= 0) { while (!tty->stopped && (c = get_tty_queue(&tty->write_q)) >= 0) {
if (state == ESnormal && translate[c]) { if (state == ESnormal && translate[c]) {
if (need_wrap) { if (need_wrap) {
...@@ -1270,9 +1271,9 @@ void con_write(struct tty_struct * tty) ...@@ -1270,9 +1271,9 @@ void con_write(struct tty_struct * tty)
state = ESnormal; state = ESnormal;
} }
} }
if (vcmode == KD_GRAPHICS) if (vcmode != KD_GRAPHICS)
return; set_cursor(currcons);
set_cursor(currcons); enable_bh(KEYBOARD_BH);
} }
void do_keyboard_interrupt(void) void do_keyboard_interrupt(void)
...@@ -1288,7 +1289,7 @@ void do_keyboard_interrupt(void) ...@@ -1288,7 +1289,7 @@ void do_keyboard_interrupt(void)
timer_table[BLANK_TIMER].expires = jiffies + blankinterval; timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
timer_active |= 1<<BLANK_TIMER; timer_active |= 1<<BLANK_TIMER;
} }
} }
void * memsetw(void * s,unsigned short c,int count) void * memsetw(void * s,unsigned short c,int count)
{ {
......
...@@ -20,10 +20,18 @@ ...@@ -20,10 +20,18 @@
* General Public License for more details. * General Public License for more details.
* *
* $Id: aha152x.c,v 0.99 1993/10/24 16:19:59 root Exp root $ * $Id: aha152x.c,v 0.101 1993/12/13 01:16:27 root Exp $
* *
* $Log: aha152x.c,v $ * $Log: aha152x.c,v $
* Revision 0.101 1993/12/13 01:16:27 root
* - fixed STATUS phase (non-GOOD stati were dropped sometimes;
* fixes problems with CD-ROM sector size detection & media change)
*
* Revision 0.100 1993/12/10 16:58:47 root
* - fix for unsuccessful selections in case of non-continuous id assignments
* on the scsi bus.
*
* Revision 0.99 1993/10/24 16:19:59 root * Revision 0.99 1993/10/24 16:19:59 root
* - fixed DATA IN (rare read errors gone) * - fixed DATA IN (rare read errors gone)
* *
...@@ -220,7 +228,7 @@ ...@@ -220,7 +228,7 @@
#define P_BUSFREE 1 #define P_BUSFREE 1
#define P_PARITY 2 #define P_PARITY 2
char *aha152x_id = "Adaptec 152x SCSI driver; $Revision: 0.99 $\n"; char *aha152x_id = "Adaptec 152x SCSI driver; $Revision: 0.101 $\n";
static int port_base = 0; static int port_base = 0;
static int this_host = 0; static int this_host = 0;
...@@ -662,6 +670,7 @@ int aha152x_detect(int hostno) ...@@ -662,6 +670,7 @@ int aha152x_detect(int hostno)
SETBITS(SCSISEQ, SCSIRSTO ); SETBITS(SCSISEQ, SCSIRSTO );
do_pause(5); do_pause(5);
CLRBITS(SCSISEQ, SCSIRSTO ); CLRBITS(SCSISEQ, SCSIRSTO );
do_pause(10);
aha152x_reset(NULL); aha152x_reset(NULL);
...@@ -948,6 +957,7 @@ int aha152x_reset(Scsi_Cmnd * __unused) ...@@ -948,6 +957,7 @@ int aha152x_reset(Scsi_Cmnd * __unused)
SETPORT(SCSISEQ, SCSIRSTO); SETPORT(SCSISEQ, SCSIRSTO);
do_pause(5); do_pause(5);
SETPORT(SCSISEQ, 0); SETPORT(SCSISEQ, 0);
do_pause(10);
SETPORT(SIMODE0, 0 ); SETPORT(SIMODE0, 0 );
SETPORT(SIMODE1, issue_SC ? ENBUSFREE : 0); SETPORT(SIMODE1, issue_SC ? ENBUSFREE : 0);
...@@ -1140,7 +1150,7 @@ void aha152x_intr( int irqno ) ...@@ -1140,7 +1150,7 @@ void aha152x_intr( int irqno )
SETPORT( SXFRCTL0, CH1); SETPORT( SXFRCTL0, CH1);
identify_msg = GETPORT(SCSIDAT); identify_msg = GETPORT(SCSIBUS);
if(!(identify_msg & IDENTIFY_BASE)) if(!(identify_msg & IDENTIFY_BASE))
{ {
...@@ -1301,6 +1311,9 @@ void aha152x_intr( int irqno ) ...@@ -1301,6 +1311,9 @@ void aha152x_intr( int irqno )
#if defined(DEBUG_SELECTION) || defined(DEBUG_PHASES) #if defined(DEBUG_SELECTION) || defined(DEBUG_PHASES)
printk("SELTO, "); printk("SELTO, ");
#endif #endif
/* end selection attempt */
CLRBITS(SCSISEQ, ENSELO|ENAUTOATNO );
/* timeout */ /* timeout */
SETPORT( SSTAT1, CLRSELTIMO ); SETPORT( SSTAT1, CLRSELTIMO );
...@@ -1498,7 +1511,7 @@ void aha152x_intr( int irqno ) ...@@ -1498,7 +1511,7 @@ void aha152x_intr( int irqno )
while( phase == P_MSGI ) while( phase == P_MSGI )
{ {
current_SC->SCp.Message = GETPORT( SCSIDAT ); current_SC->SCp.Message = GETPORT( SCSIBUS );
switch(current_SC->SCp.Message) switch(current_SC->SCp.Message)
{ {
case DISCONNECT: case DISCONNECT:
...@@ -1541,7 +1554,7 @@ void aha152x_intr( int irqno ) ...@@ -1541,7 +1554,7 @@ void aha152x_intr( int irqno )
if(getphase()!=P_MSGI) if(getphase()!=P_MSGI)
break; break;
i=GETPORT(SCSIDAT); i=GETPORT(SCSIBUS);
#if defined(DEBUG_MSGI) #if defined(DEBUG_MSGI)
printk("length (%d), ", i); printk("length (%d), ", i);
...@@ -1555,7 +1568,7 @@ void aha152x_intr( int irqno ) ...@@ -1555,7 +1568,7 @@ void aha152x_intr( int irqno )
if(getphase()!=P_MSGI) if(getphase()!=P_MSGI)
break; break;
code = GETPORT(SCSIDAT); code = GETPORT(SCSIBUS);
switch( code ) switch( code )
{ {
...@@ -1598,9 +1611,9 @@ void aha152x_intr( int irqno ) ...@@ -1598,9 +1611,9 @@ void aha152x_intr( int irqno )
while( --i && (make_acklow(), getphase()==P_MSGI)) while( --i && (make_acklow(), getphase()==P_MSGI))
{ {
#if defined(DEBUG_MSGI) #if defined(DEBUG_MSGI)
printk("%x ", GETPORT(SCSIDAT) ); printk("%x ", GETPORT(SCSIBUS) );
#else #else
GETPORT(SCSIDAT); GETPORT(SCSIBUS);
#endif #endif
} }
#if defined(DEBUG_MSGI) #if defined(DEBUG_MSGI)
...@@ -1655,24 +1668,12 @@ void aha152x_intr( int irqno ) ...@@ -1655,24 +1668,12 @@ void aha152x_intr( int irqno )
SETPORT( SXFRCTL0, CH1); SETPORT( SXFRCTL0, CH1);
SETPORT( SIMODE0, 0 ); SETPORT( SIMODE0, 0 );
SETPORT( SIMODE1, ENPHASEMIS|ENREQINIT ); SETPORT( SIMODE1, ENREQINIT );
SETBITS( SXFRCTL0, SCSIEN );
#if defined(DEBUG_STATUS)
printk("waiting for status, ");
#endif
#if defined(DEBUG_STATUS)
disp_ports();
#endif
while( TESTLO( DMASTAT, INTSTAT ) )
;
#if 0
if(TESTLO( SSTAT0, SPIORDY ) )
aha152x_panic("passing STATUS phase");
#endif
current_SC->SCp.Status = GETPORT( SCSIDAT ); if( TESTHI( SSTAT1, PHASEMIS ) )
printk("aha152x: passing STATUS phase");
current_SC->SCp.Status = GETPORT( SCSIBUS );
make_acklow(); make_acklow();
getphase(); getphase();
...@@ -1680,13 +1681,6 @@ void aha152x_intr( int irqno ) ...@@ -1680,13 +1681,6 @@ void aha152x_intr( int irqno )
printk("inbound status "); printk("inbound status ");
print_status( current_SC->SCp.Status ); print_status( current_SC->SCp.Status );
printk(", "); printk(", ");
#endif
CLRBITS( SXFRCTL0, SCSIEN );
while( TESTHI( SXFRCTL0, SCSIEN ) )
;
#if 0
CLRBITS( SXFRCTL0, SPIOEN);
#endif #endif
break; break;
......
...@@ -126,8 +126,10 @@ static int isofs_readdir(struct inode * inode, struct file * filp, ...@@ -126,8 +126,10 @@ static int isofs_readdir(struct inode * inode, struct file * filp,
offset = filp->f_pos & (bufsize - 1); offset = filp->f_pos & (bufsize - 1);
block = isofs_bmap(inode,(filp->f_pos)>> bufbits); block = isofs_bmap(inode,(filp->f_pos)>> bufbits);
if (!block if (!block
|| !(bh = bread(inode->i_dev,block,bufsize))) || !(bh = bread(inode->i_dev,block,bufsize))) {
kfree_s(cpnt, 1 << ISOFS_BLOCK_BITS);
return 0; return 0;
};
memcpy((char *)cpnt+bufsize, bh->b_data, bufsize); memcpy((char *)cpnt+bufsize, bh->b_data, bufsize);
} }
......
...@@ -585,6 +585,7 @@ int isofs_lookup_grandparent(struct inode * parent, int extent) ...@@ -585,6 +585,7 @@ int isofs_lookup_grandparent(struct inode * parent, int extent)
if (offset >= bufsize) if (offset >= bufsize)
{ {
if((block & 1) != 0) return -1;
cpnt = kmalloc(1<<ISOFS_BLOCK_BITS,GFP_KERNEL); cpnt = kmalloc(1<<ISOFS_BLOCK_BITS,GFP_KERNEL);
memcpy(cpnt, bh->b_data, bufsize); memcpy(cpnt, bh->b_data, bufsize);
de = (struct iso_directory_record *) de = (struct iso_directory_record *)
...@@ -592,9 +593,10 @@ int isofs_lookup_grandparent(struct inode * parent, int extent) ...@@ -592,9 +593,10 @@ int isofs_lookup_grandparent(struct inode * parent, int extent)
brelse(bh); brelse(bh);
offset -= bufsize; offset -= bufsize;
block++; block++;
if((block & 1) == 0) return -1; if (!(bh = bread(parent->i_dev,block,bufsize))) {
if (!(bh = bread(parent->i_dev,block,bufsize))) kfree_s(cpnt, 1 << ISOFS_BLOCK_BITS);
return -1; return -1;
};
memcpy((char *)cpnt+bufsize, bh->b_data, bufsize); memcpy((char *)cpnt+bufsize, bh->b_data, bufsize);
} }
......
...@@ -122,8 +122,10 @@ static struct buffer_head * isofs_find_entry(struct inode * dir, ...@@ -122,8 +122,10 @@ static struct buffer_head * isofs_find_entry(struct inode * dir,
brelse(bh); brelse(bh);
offset = f_pos & (bufsize - 1); offset = f_pos & (bufsize - 1);
block = isofs_bmap(dir,f_pos>>bufbits); block = isofs_bmap(dir,f_pos>>bufbits);
if (!block || !(bh = bread(dir->i_dev,block,bufsize))) if (!block || !(bh = bread(dir->i_dev,block,bufsize))) {
kfree_s(cpnt, 1 << ISOFS_BLOCK_BITS);
return 0; return 0;
};
memcpy((char *)cpnt+bufsize,bh->b_data,bufsize); memcpy((char *)cpnt+bufsize,bh->b_data,bufsize);
} }
......
...@@ -413,6 +413,8 @@ static int get_maps(int pid, char *buf) ...@@ -413,6 +413,8 @@ static int get_maps(int pid, char *buf)
return sz; return sz;
} }
asmlinkage int get_module_list( char *);
static int array_read(struct inode * inode, struct file * file,char * buf, int count) static int array_read(struct inode * inode, struct file * file,char * buf, int count)
{ {
char * page; char * page;
...@@ -463,6 +465,9 @@ static int array_read(struct inode * inode, struct file * file,char * buf, int c ...@@ -463,6 +465,9 @@ static int array_read(struct inode * inode, struct file * file,char * buf, int c
case 15: case 15:
length = get_maps(pid, page); length = get_maps(pid, page);
break; break;
case 16:
length = get_module_list(page);
break;
default: default:
free_page((unsigned long) page); free_page((unsigned long) page);
return -EBADF; return -EBADF;
......
...@@ -65,6 +65,7 @@ static struct proc_dir_entry root_dir[] = { ...@@ -65,6 +65,7 @@ static struct proc_dir_entry root_dir[] = {
{13,6,"malloc" }, {13,6,"malloc" },
#endif #endif
{14,5,"kcore" }, {14,5,"kcore" },
{16,7,"modules" },
}; };
#define NR_ROOT_DIRENTRY ((sizeof (root_dir))/(sizeof (root_dir[0]))) #define NR_ROOT_DIRENTRY ((sizeof (root_dir))/(sizeof (root_dir[0])))
......
...@@ -319,6 +319,7 @@ extern struct file_operations def_blk_fops; ...@@ -319,6 +319,7 @@ extern struct file_operations def_blk_fops;
extern struct inode_operations blkdev_inode_operations; extern struct inode_operations blkdev_inode_operations;
extern int register_chrdev(unsigned int, const char *, struct file_operations *); extern int register_chrdev(unsigned int, const char *, struct file_operations *);
extern int unregister_chrdev( unsigned int major, const char * name);
extern int chrdev_open(struct inode * inode, struct file * filp); extern int chrdev_open(struct inode * inode, struct file * filp);
extern struct file_operations def_chr_fops; extern struct file_operations def_chr_fops;
extern struct inode_operations chrdev_inode_operations; extern struct inode_operations chrdev_inode_operations;
......
/*
* Dynamic loading of modules into the kernel.
*/
#ifndef _LINUX_MODULE_H
#define _LINUX_MODULE_H
/* values of module.state */
#define MOD_UNINITIALIZED 0
#define MOD_RUNNING 1
#define MOD_DELETED 2
/* maximum length of module name */
#define MOD_MAX_NAME 64
/* maximum length of symbol name */
#define SYM_MAX_NAME 60
struct module {
struct module *next;
char *name;
int size; /* size of module in pages */
void* addr; /* address of module */
int state;
void (*cleanup)(void); /* cleanup routine */
};
struct mod_routines {
int (*init)(void); /* initialization routine */
void (*cleanup)(void); /* cleanup routine */
};
struct kernel_sym {
unsigned long value; /* value of symbol */
char name[SYM_MAX_NAME]; /* name of symbol */
};
extern struct module *module_list;
/*
* The first word of the module contains the use count.
*/
#define GET_USE_COUNT(module) (* (int *) (module)->addr)
/*
* define the count variable, and usage macros.
*/
extern int mod_use_count_;
#define MOD_INC_USE_COUNT mod_use_count_++
#define MOD_DEC_USE_COUNT mod_use_count_--
#define MOD_IN_USE (mod_use_count_ != 0)
#endif
...@@ -8,133 +8,137 @@ ...@@ -8,133 +8,137 @@
extern "C" { extern "C" {
#endif #endif
extern int sys_setup(); extern int sys_setup(); /* 0 */
extern int sys_exit(); extern int sys_exit();
extern int sys_fork(); extern int sys_fork();
extern int sys_read(); extern int sys_read();
extern int sys_write(); extern int sys_write();
extern int sys_open(); extern int sys_open(); /* 5 */
extern int sys_close(); extern int sys_close();
extern int sys_waitpid(); extern int sys_waitpid();
extern int sys_creat(); extern int sys_creat();
extern int sys_link(); extern int sys_link();
extern int sys_unlink(); extern int sys_unlink(); /* 10 */
extern int sys_execve(); extern int sys_execve();
extern int sys_chdir(); extern int sys_chdir();
extern int sys_time(); extern int sys_time();
extern int sys_mknod(); extern int sys_mknod();
extern int sys_chmod(); extern int sys_chmod(); /* 15 */
extern int sys_chown(); extern int sys_chown();
extern int sys_break(); extern int sys_break();
extern int sys_stat(); extern int sys_stat();
extern int sys_lseek(); extern int sys_lseek();
extern int sys_getpid(); extern int sys_getpid(); /* 20 */
extern int sys_mount(); extern int sys_mount();
extern int sys_umount(); extern int sys_umount();
extern int sys_setuid(); extern int sys_setuid();
extern int sys_getuid(); extern int sys_getuid();
extern int sys_stime(); extern int sys_stime(); /* 25 */
extern int sys_ptrace(); extern int sys_ptrace();
extern int sys_alarm(); extern int sys_alarm();
extern int sys_fstat(); extern int sys_fstat();
extern int sys_pause(); extern int sys_pause();
extern int sys_utime(); extern int sys_utime(); /* 30 */
extern int sys_stty(); extern int sys_stty();
extern int sys_gtty(); extern int sys_gtty();
extern int sys_access(); extern int sys_access();
extern int sys_nice(); extern int sys_nice();
extern int sys_ftime(); extern int sys_ftime(); /* 35 */
extern int sys_sync(); extern int sys_sync();
extern int sys_kill(); extern int sys_kill();
extern int sys_rename(); extern int sys_rename();
extern int sys_mkdir(); extern int sys_mkdir();
extern int sys_rmdir(); extern int sys_rmdir(); /* 40 */
extern int sys_dup(); extern int sys_dup();
extern int sys_pipe(); extern int sys_pipe();
extern int sys_times(); extern int sys_times();
extern int sys_prof(); extern int sys_prof();
extern int sys_brk(); extern int sys_brk(); /* 45 */
extern int sys_setgid(); extern int sys_setgid();
extern int sys_getgid(); extern int sys_getgid();
extern int sys_signal(); extern int sys_signal();
extern int sys_geteuid(); extern int sys_geteuid();
extern int sys_getegid(); extern int sys_getegid(); /* 50 */
extern int sys_acct(); extern int sys_acct();
extern int sys_phys(); extern int sys_phys();
extern int sys_lock(); extern int sys_lock();
extern int sys_ioctl(); extern int sys_ioctl();
extern int sys_fcntl(); extern int sys_fcntl(); /* 55 */
extern int sys_mpx(); extern int sys_mpx();
extern int sys_setpgid(); extern int sys_setpgid();
extern int sys_ulimit(); extern int sys_ulimit();
extern int sys_uname(); extern int sys_uname();
extern int sys_umask(); extern int sys_umask(); /* 60 */
extern int sys_chroot(); extern int sys_chroot();
extern int sys_ustat(); extern int sys_ustat();
extern int sys_dup2(); extern int sys_dup2();
extern int sys_getppid(); extern int sys_getppid();
extern int sys_getpgrp(); extern int sys_getpgrp(); /* 65 */
extern int sys_setsid(); extern int sys_setsid();
extern int sys_sigaction(); extern int sys_sigaction();
extern int sys_sgetmask(); extern int sys_sgetmask();
extern int sys_ssetmask(); extern int sys_ssetmask();
extern int sys_setreuid(); extern int sys_setreuid(); /* 70 */
extern int sys_setregid(); extern int sys_setregid();
extern int sys_sigpending(); extern int sys_sigpending();
extern int sys_sigsuspend(); extern int sys_sigsuspend();
extern int sys_sethostname(); extern int sys_sethostname();
extern int sys_setrlimit(); extern int sys_setrlimit(); /* 75 */
extern int sys_getrlimit(); extern int sys_getrlimit();
extern int sys_getrusage(); extern int sys_getrusage();
extern int sys_gettimeofday(); extern int sys_gettimeofday();
extern int sys_settimeofday(); extern int sys_settimeofday();
extern int sys_getgroups(); extern int sys_getgroups(); /* 80 */
extern int sys_setgroups(); extern int sys_setgroups();
extern int sys_select(); extern int sys_select();
extern int sys_symlink(); extern int sys_symlink();
extern int sys_lstat(); extern int sys_lstat();
extern int sys_readlink(); extern int sys_readlink(); /* 85 */
extern int sys_uselib(); extern int sys_uselib();
extern int sys_swapon(); extern int sys_swapon();
extern int sys_reboot(); extern int sys_reboot();
extern int sys_readdir(); extern int sys_readdir();
extern int sys_mmap(); extern int sys_mmap(); /* 90 */
extern int sys_munmap(); extern int sys_munmap();
extern int sys_truncate(); extern int sys_truncate();
extern int sys_ftruncate(); extern int sys_ftruncate();
extern int sys_fchmod(); extern int sys_fchmod();
extern int sys_fchown(); extern int sys_fchown(); /* 95 */
extern int sys_getpriority(); extern int sys_getpriority();
extern int sys_setpriority(); extern int sys_setpriority();
extern int sys_profil(); extern int sys_profil();
extern int sys_statfs(); extern int sys_statfs();
extern int sys_fstatfs(); extern int sys_fstatfs(); /* 100 */
extern int sys_ioperm(); extern int sys_ioperm();
extern int sys_socketcall(); extern int sys_socketcall();
extern int sys_syslog(); extern int sys_syslog();
extern int sys_getitimer(); extern int sys_getitimer();
extern int sys_setitimer(); extern int sys_setitimer(); /* 105 */
extern int sys_newstat(); extern int sys_newstat();
extern int sys_newlstat(); extern int sys_newlstat();
extern int sys_newfstat(); extern int sys_newfstat();
extern int sys_newuname(); extern int sys_newuname();
extern int sys_iopl(); extern int sys_iopl(); /* 110 */
extern int sys_vhangup(); extern int sys_vhangup();
extern int sys_idle(); extern int sys_idle();
extern int sys_vm86(); extern int sys_vm86();
extern int sys_wait4(); extern int sys_wait4();
extern int sys_swapoff(); extern int sys_swapoff(); /* 115 */
extern int sys_sysinfo(); extern int sys_sysinfo();
extern int sys_ipc(); extern int sys_ipc();
extern int sys_fsync(); extern int sys_fsync();
extern int sys_sigreturn(); extern int sys_sigreturn();
extern int sys_setdomainname(); extern int sys_setdomainname(); /* 120 */
extern int sys_olduname(); extern int sys_olduname();
extern int sys_old_syscall(); extern int sys_old_syscall();
extern int sys_modify_ldt(); extern int sys_modify_ldt();
extern int sys_adjtimex(); extern int sys_adjtimex();
extern int sys_mprotect(); extern int sys_mprotect(); /* 125 */
extern int sys_sigprocmask(); extern int sys_sigprocmask();
extern int sys_create_module();
extern int sys_init_module();
extern int sys_delete_module();
extern int sys_get_kernel_syms(); /* 130 */
/* /*
* These are system calls that will be removed at some time * These are system calls that will be removed at some time
......
...@@ -133,6 +133,10 @@ ...@@ -133,6 +133,10 @@
#define __NR_adjtimex 124 #define __NR_adjtimex 124
#define __NR_mprotect 125 #define __NR_mprotect 125
#define __NR_sigprocmask 126 #define __NR_sigprocmask 126
#define __NR_create_module 127
#define __NR_init_module 128
#define __NR_delete_module 129
#define __NR_get_kernel_syms 130
extern int errno; extern int errno;
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
$(CC) $(CFLAGS) -c $< $(CC) $(CFLAGS) -c $<
OBJS = sched.o sys_call.o traps.o irq.o dma.o fork.o \ OBJS = sched.o sys_call.o traps.o irq.o dma.o fork.o \
panic.o printk.o vsprintf.o sys.o exit.o \ panic.o printk.o vsprintf.o sys.o module.o ksyms.o exit.o \
signal.o mktime.o ptrace.o ioport.o itimer.o \ signal.o mktime.o ptrace.o ioport.o itimer.o \
info.o ldt.o time.o info.o ldt.o time.o
...@@ -34,6 +34,11 @@ sys_call.o: sys_call.s ...@@ -34,6 +34,11 @@ sys_call.o: sys_call.s
sched.o: sched.c sched.o: sched.c
$(CC) $(CFLAGS) $(PROFILING) -fno-omit-frame-pointer -c $< $(CC) $(CFLAGS) $(PROFILING) -fno-omit-frame-pointer -c $<
ksyms.o: ksyms.S ksyms.sh /usr/include/linux/autoconf.h
$(CPP) $(CFLAGS) ksyms.S > ksyms.lst
sh ksyms.sh > ksyms.s
$(AS) -o ksyms.o ksyms.s
dep: dep:
$(CPP) -M *.c > .depend $(CPP) -M *.c > .depend
......
#include <linux/autoconf.h>
/*
* Herein lies all the functions/variables that are "exported" for linkage
* With dynamically loaded kernel modules. Could do with making this a bit
* cleaner!
*
* Jon.
*/
_register_chrdev
_unregister_chrdev
_verify_area
_wake_up_interruptible
_current
_jiffies
_printk
_schedule
#ifdef CONFIG_FTAPE
#
# The next labels are needed for ftape driver.
#
_ftape_big_buffer
_xtime
_do_floppy
_tick
#endif
# This program will construct ksyms.s. Ksyms.s contains a symbol table
# for all the kernel symbols included in the file ksyms.lst. The following
# variables are defined in ksym.s:
#
# int symbol_table_size; /* number of symbols */
# struct {
# void *value; /* value of symbol */
# char *name; /* name of symbol */
# } symbol_table[];
#
#
trap "rm -f ksyms.tmp ksyms.lst" 0 1 2
sed -e '/^#/d' -e '/^[ ]*$/d' ksyms.lst | sort > ksyms.tmp
echo ' .data
.globl _symbol_table_size, _symbol_table
_symbol_table_size:'
echo " .long" `wc -l < ksyms.tmp`
echo '
_symbol_table:'
awk 'BEGIN {stringloc = 0}
{print " .long " $1; print " .long strings+" stringloc; \
stringloc += length($1) + 1;}' ksyms.tmp
echo '
strings:'
awk '{print " .ascii \"" $1 "\\0\""}' ksyms.tmp
#
# Alternativly, if the kernel is c++ compiled:
# By using gsub() we can forse all function names to appear as extern "C".
# This allows linkable drivers written in C or C++ - Jon
# awk '{gsub(/__F.*/, "") ; print " .ascii \"" $0 "\\0\""}' ksyms.tmp
#include <linux/errno.h>
#include <linux/kernel.h>
#include <asm/segment.h>
#include <linux/mm.h> /* defines GFP_KERNEL */
#include <linux/string.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/malloc.h>
struct module *module_list = NULL;
int freeing_modules; /* true if some modules are marked for deletion */
struct module *find_module( const char *name);
int get_mod_name( char *user_name, char *buf);
int free_modules( void);
/*
* Allocate space for a module.
*/
asmlinkage int
sys_create_module(char *module_name, unsigned long size)
{
int npages;
void* addr;
int len;
char name[MOD_MAX_NAME];
char *savename;
struct module *mp;
int error;
if (!suser())
return -EPERM;
if (name == NULL || size == 0)
return -EINVAL;
if ((error = get_mod_name(module_name, name)) != 0)
return error;
if (find_module(name) != NULL) {
return -EEXIST;
}
len = strlen(name) + 1;
if ((savename = (char*) kmalloc(len, GFP_KERNEL)) == NULL)
return -ENOMEM;
memcpy(savename, name, len);
if ((mp = (struct module*) kmalloc(sizeof *mp, GFP_KERNEL)) == NULL) {
kfree(savename);
return -ENOMEM;
}
npages = (size + sizeof (int) + 4095) / 4096;
if ((addr = vmalloc(npages * 4096)) == 0) {
kfree_s(mp, sizeof *mp);
kfree(savename);
return -ENOMEM;
}
mp->name = savename;
mp->size = npages;
mp->addr = addr;
mp->state = MOD_UNINITIALIZED;
* (int *) addr = 0; /* set use count to zero */
mp->cleanup = NULL;
mp->next = module_list;
module_list = mp;
printk("module `%s' (%lu pages @ 0x%08lx) created\n",
mp->name, (unsigned long) mp->size, (unsigned long) mp->addr);
return (int) addr;
}
/*
* Initialize a module.
*/
asmlinkage int
sys_init_module(char *module_name, char *code, unsigned codesize,
struct mod_routines *routines)
{
struct module *mp;
char name[MOD_MAX_NAME];
int error;
struct mod_routines rt;
if (!suser())
return -EPERM;
/*
* First reclaim any memory from dead modules that where not
* freed when deleted. Should I think be done by timers when
* the module was deleted - Jon.
*/
free_modules();
if ((error = get_mod_name(module_name, name)) != 0)
return error;
printk( "initializing module `%s', %d (0x%x) bytes\n",
name, codesize, codesize);
memcpy_fromfs(&rt, routines, sizeof rt);
if ((mp = find_module(name)) == NULL)
return -ENOENT;
if ((codesize + sizeof (int) + 4095) / 4096 > mp->size)
return -EINVAL;
memcpy_fromfs((char *)mp->addr + sizeof (int), code, codesize);
memset((char *)mp->addr + sizeof (int) + codesize, 0,
mp->size * 4096 - (codesize + sizeof (int)));
printk( " init enty @ 0x%08lx, cleanup entry @ 0x%08lx\n",
(unsigned long) rt.init, (unsigned long) rt.cleanup);
mp->cleanup = rt.cleanup;
if ((*rt.init)() != 0)
return -EBUSY;
mp->state = MOD_RUNNING;
return 0;
}
asmlinkage int
sys_delete_module(char *module_name)
{
struct module *mp;
char name[MOD_MAX_NAME];
int error;
if (!suser())
return -EPERM;
if (module_name != NULL) {
if ((error = get_mod_name(module_name, name)) != 0)
return error;
if ((mp = find_module(name)) == NULL)
return -ENOENT;
if (mp->state == MOD_RUNNING)
(*mp->cleanup)();
mp->state = MOD_DELETED;
}
free_modules();
return 0;
}
/*
* Copy the kernel symbol table to user space. If the argument is null,
* just return the size of the table.
*/
asmlinkage int
sys_get_kernel_syms(struct kernel_sym *table)
{
struct symbol {
unsigned long addr;
char *name;
};
extern int symbol_table_size;
extern struct symbol symbol_table[];
int i;
struct symbol *from;
struct kernel_sym *to;
struct kernel_sym sym;
if (table != NULL) {
from = symbol_table;
to = table;
verify_area(VERIFY_WRITE, to, symbol_table_size * sizeof *table);
for (i = symbol_table_size ; --i >= 0 ; ) {
sym.value = from->addr;
strncpy(sym.name, from->name, sizeof sym.name);
memcpy_tofs(to, &sym, sizeof sym);
from++, to++;
}
}
return symbol_table_size;
}
/*
* Copy the name of a module from user space.
*/
int
get_mod_name(char *user_name, char *buf)
{
int i;
i = 0;
for (i = 0 ; (buf[i] = get_fs_byte(user_name + i)) != '\0' ; ) {
if (++i >= MOD_MAX_NAME)
return -E2BIG;
}
return 0;
}
/*
* Look for a module by name, ignoring modules marked for deletion.
*/
struct module *
find_module( const char *name)
{
struct module *mp;
for (mp = module_list ; mp ; mp = mp->next) {
if (mp->state == MOD_DELETED)
continue;
if (!strcmp(mp->name, name))
break;
}
return mp;
}
/*
* Try to free modules which have been marked for deletion. Returns nonzero
* if a module was actually freed.
*/
int
free_modules( void)
{
struct module *mp;
struct module **mpp;
int did_deletion;
did_deletion = 0;
freeing_modules = 0;
mpp = &module_list;
while ((mp = *mpp) != NULL) {
if (mp->state != MOD_DELETED) {
mpp = &mp->next;
} else if (GET_USE_COUNT(mp) != 0) {
freeing_modules = 1;
mpp = &mp->next;
} else { /* delete it */
*mpp = mp->next;
vfree(mp->addr);
kfree(mp->name);
kfree_s(mp, sizeof *mp);
did_deletion = 1;
}
}
return did_deletion;
}
/*
* Called by the /proc file system to return a current list of modules.
*/
int
get_module_list( char *buf)
{
char *p;
char *q;
int i;
struct module *mp;
char size[32];
p = buf;
for (mp = module_list ; mp ; mp = mp->next) {
if (p - buf > 4096 - 100)
break; /* avoid overflowing buffer */
q = mp->name;
i = 20;
while (*q) {
*p++ = *q++;
i--;
}
sprintf(size, "%d", mp->size);
i -= strlen(size);
if (i <= 0)
i = 1;
while (--i >= 0)
*p++ = ' ';
q = size;
while (*q)
*p++ = *q++;
if (mp->state == MOD_UNINITIALIZED)
q = " (uninitialized)";
else if (mp->state == MOD_RUNNING)
q = "";
else if (mp->state == MOD_DELETED)
q = " (deleted)";
else
q = " (bad state)";
while (*q)
*p++ = *q++;
*p++ = '\n';
}
return p - buf;
}
...@@ -126,7 +126,8 @@ sys_syslog, sys_setitimer, sys_getitimer, sys_newstat, sys_newlstat, ...@@ -126,7 +126,8 @@ sys_syslog, sys_setitimer, sys_getitimer, sys_newstat, sys_newlstat,
sys_newfstat, sys_uname, sys_iopl, sys_vhangup, sys_idle, sys_vm86, sys_newfstat, sys_uname, sys_iopl, sys_vhangup, sys_idle, sys_vm86,
sys_wait4, sys_swapoff, sys_sysinfo, sys_ipc, sys_fsync, sys_sigreturn, sys_wait4, sys_swapoff, sys_sysinfo, sys_ipc, sys_fsync, sys_sigreturn,
sys_clone, sys_setdomainname, sys_newuname, sys_modify_ldt, sys_clone, sys_setdomainname, sys_newuname, sys_modify_ldt,
sys_adjtimex, sys_mprotect, sys_sigprocmask }; sys_adjtimex, sys_mprotect, sys_sigprocmask,
sys_create_module, sys_init_module, sys_delete_module, sys_get_kernel_syms };
/* So we don't have to do any more manual updating.... */ /* So we don't have to do any more manual updating.... */
int NR_syscalls = sizeof(sys_call_table)/sizeof(fn_ptr); int NR_syscalls = sizeof(sys_call_table)/sizeof(fn_ptr);
......
...@@ -25,6 +25,13 @@ struct vm_struct { ...@@ -25,6 +25,13 @@ struct vm_struct {
static struct vm_struct * vmlist = NULL; static struct vm_struct * vmlist = NULL;
/* Just any arbitrary offset to the start of the vmalloc VM area: the
* current 8MB value just means that there will be a 8MB "hole" after the
* physical memory until the kernel virtual memory starts. That means that
* any out-of-bounds memory accesses will hopefully be caught.
* The vmalloc() routines leaves a hole of 4kB between each vmalloced
* area for the same reason. ;)
*/
#define VMALLOC_OFFSET (8*1024*1024) #define VMALLOC_OFFSET (8*1024*1024)
static inline void set_pgdir(unsigned long dindex, unsigned long value) static inline void set_pgdir(unsigned long dindex, unsigned long value)
......
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