Index: fs/devices.c
*** linux.pl9.ALPHA/fs/devices.c	Wed Feb 17 14:20:50 1993
--- linux/fs/devices.c	Fri May  7 14:38:17 1993
***************
*** 43,48 ****
--- 43,64 ----
  	return 0;
  }
  
+ int free_chrdev(unsigned int major, const char * name)
+ {
+ 	if (major >= MAX_CHRDEV)
+ 		return -EINVAL;
+ 	chrdev_fops[major] = NULL;
+ 	return 0;
+ }
+ 
+ int free_blkdev(unsigned int major, const char * name)
+ {
+ 	if (major >= MAX_BLKDEV)
+ 		return -EINVAL;
+ 	blkdev_fops[major] = NULL;
+ 	return 0;
+ }
+ 
  /*
   * Called every time a block special file is opened
   */
Index: fs/proc/array.c
*** linux.pl9.ALPHA/fs/proc/array.c	Sun Mar  7 14:07:16 1993
--- linux/fs/proc/array.c	Fri May  7 11:48:24 1993
***************
*** 298,303 ****
--- 298,304 ----
  	int length;
  	int end;
  	unsigned int type, pid;
+ 	extern int get_module_list(char *);
  
  	if (count < 0)
  		return -EINVAL;
***************
*** 332,337 ****
--- 333,341 ----
  		case 12:
  			length = get_statm(pid, page);
  			break;
+ 		case 16:
+ 			length = get_module_list(page);
+ 			break;
  		default:
  			free_page((unsigned long) page);
  			return -EBADF;
Index: fs/proc/root.c
*** linux.pl9.ALPHA/fs/proc/root.c	Sun Feb 28 06:59:43 1993
--- linux/fs/proc/root.c	Fri May  7 11:49:27 1993
***************
*** 58,64 ****
  	{ 4,7,"meminfo" },
  	{ 5,4,"kmsg" },
  	{ 6,7,"version" },
! 	{ 7,4,"self" }	/* will change inode # */
  };
  
  #define NR_ROOT_DIRENTRY ((sizeof (root_dir))/(sizeof (root_dir[0])))
--- 58,65 ----
  	{ 4,7,"meminfo" },
  	{ 5,4,"kmsg" },
  	{ 6,7,"version" },
! 	{ 7,4,"self" },	/* will change inode # */
! 	{ 16,7,"modules" }
  };
  
  #define NR_ROOT_DIRENTRY ((sizeof (root_dir))/(sizeof (root_dir[0])))
Index: include/linux/module.h
*** /dev/null	Mon May 10 13:39:01 1993
--- linux/include/linux/module.h	Mon May 10 09:20:31 1993
***************
*** 0 ****
--- 1,46 ----
+ /*
+  * 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
+ 
+ 
+ struct module {
+ 	struct module *next;
+ 	char *name;
+ 	int size;			/* size of module in pages */
+ 	unsigned long 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[28];			/* name of symbol */
+ };
+ 
+ 
+ /*
+  * The first word of the module contains the use count.
+  */
+ #define GET_USE_COUNT(module)	(* (int *) (module)->addr)
+ 
+ extern struct module *module_list;
+ 
+ #endif
Index: include/linux/sys.h
*** linux.pl9.ALPHA/include/linux/sys.h	Fri Apr 23 13:15:27 1993
--- linux/include/linux/sys.h	Mon May 10 08:49:29 1993
***************
*** 124,153 ****
  extern int sys_ipc();
  extern int sys_fsync();
  extern int sys_sigreturn();
  
! fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read,
! sys_write, sys_open, sys_close, sys_waitpid, sys_creat, sys_link,
! sys_unlink, sys_execve, sys_chdir, sys_time, sys_mknod, sys_chmod,
! sys_chown, sys_break, sys_stat, sys_lseek, sys_getpid, sys_mount,
! sys_umount, sys_setuid, sys_getuid, sys_stime, sys_ptrace, sys_alarm,
! sys_fstat, sys_pause, sys_utime, sys_stty, sys_gtty, sys_access,
! sys_nice, sys_ftime, sys_sync, sys_kill, sys_rename, sys_mkdir,
! sys_rmdir, sys_dup, sys_pipe, sys_times, sys_prof, sys_brk, sys_setgid,
! sys_getgid, sys_signal, sys_geteuid, sys_getegid, sys_acct, sys_phys,
! sys_lock, sys_ioctl, sys_fcntl, sys_mpx, sys_setpgid, sys_ulimit,
! sys_uname, sys_umask, sys_chroot, sys_ustat, sys_dup2, sys_getppid,
! sys_getpgrp, sys_setsid, sys_sigaction, sys_sgetmask, sys_ssetmask,
! sys_setreuid,sys_setregid, sys_sigsuspend, sys_sigpending,
! sys_sethostname, sys_setrlimit, sys_getrlimit, sys_getrusage,
! sys_gettimeofday, sys_settimeofday, sys_getgroups, sys_setgroups,
! sys_select, sys_symlink, sys_lstat, sys_readlink, sys_uselib,
! sys_swapon, sys_reboot, sys_readdir, sys_mmap, sys_munmap, sys_truncate,
! sys_ftruncate, sys_fchmod, sys_fchown, sys_getpriority, sys_setpriority,
! sys_profil, sys_statfs, sys_fstatfs, sys_ioperm, sys_socketcall,
! sys_syslog, sys_setitimer, sys_getitimer, sys_newstat, sys_newlstat,
! sys_newfstat, sys_newuname, sys_iopl, sys_vhangup, sys_idle, sys_vm86,
! sys_wait4, sys_swapoff, sys_sysinfo, sys_ipc, sys_fsync, sys_sigreturn,
! sys_clone };
  
  /* So we don't have to do any more manual updating.... */
  int NR_syscalls = sizeof(sys_call_table)/sizeof(fn_ptr);
--- 124,162 ----
  extern int sys_ipc();
  extern int sys_fsync();
  extern int sys_sigreturn();
+ extern int no_sys();
+ extern int sys_create_module();
+ extern int sys_init_module();
+ extern int sys_delete_module();
+ extern int sys_get_kernel_syms();
  
! fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read,	/* 4 */
! sys_write, sys_open, sys_close, sys_waitpid, sys_creat, sys_link,	/* 10 */
! sys_unlink, sys_execve, sys_chdir, sys_time, sys_mknod, sys_chmod,	/* 16 */
! sys_chown, sys_break, sys_stat, sys_lseek, sys_getpid, sys_mount,	/* 22 */
! sys_umount, sys_setuid, sys_getuid, sys_stime, sys_ptrace, sys_alarm,	/* 28 */
! sys_fstat, sys_pause, sys_utime, sys_stty, sys_gtty, sys_access,	/* 34 */
! sys_nice, sys_ftime, sys_sync, sys_kill, sys_rename, sys_mkdir,		/* 40 */
! sys_rmdir, sys_dup, sys_pipe, sys_times, sys_prof, sys_brk, sys_setgid, /* 47 */
  
+ sys_getgid, sys_signal, sys_geteuid, sys_getegid, sys_acct, sys_phys,	/* 53 */
+ sys_lock, sys_ioctl, sys_fcntl, sys_mpx, sys_setpgid, sys_ulimit,	/* 59 */
+ sys_uname, sys_umask, sys_chroot, sys_ustat, sys_dup2, sys_getppid,	/* 65 */
+ sys_getpgrp, sys_setsid, sys_sigaction, sys_sgetmask, sys_ssetmask,	/* 70 */
+ sys_setreuid,sys_setregid, sys_sigsuspend, sys_sigpending,		/* 74 */
+ sys_sethostname, sys_setrlimit, sys_getrlimit, sys_getrusage,		/* 78 */
+ sys_gettimeofday, sys_settimeofday, sys_getgroups, sys_setgroups,	/* 82 */
+ sys_select, sys_symlink, sys_lstat, sys_readlink, sys_uselib,		/* 87 */
+ sys_swapon, sys_reboot, sys_readdir, sys_mmap, sys_munmap, sys_truncate,/* 93 */	
+ sys_ftruncate, sys_fchmod, sys_fchown, sys_getpriority, sys_setpriority,/* 98 */
+ sys_profil, sys_statfs, sys_fstatfs, sys_ioperm, sys_socketcall,	/* 103 */
+ sys_syslog, sys_setitimer, sys_getitimer, sys_newstat, sys_newlstat,	/* 108 */
+ sys_newfstat, sys_newuname, sys_iopl, sys_vhangup, sys_idle, sys_vm86,	/* 115 */
+ sys_wait4, sys_swapoff, sys_sysinfo, sys_ipc, sys_fsync, sys_sigreturn,	/* 121 */
+ sys_clone,
+ no_sys, sys_create_module, sys_init_module, sys_delete_module, 		/* 125 */
+ sys_get_kernel_syms, no_sys, no_sys, no_sys, no_sys };			/* 131 */
+ 
+ 
  /* So we don't have to do any more manual updating.... */
  int NR_syscalls = sizeof(sys_call_table)/sizeof(fn_ptr);
Index: include/linux/use_count.h
*** /dev/null	Mon May 10 13:39:01 1993
--- linux/include/linux/use_count.h	Mon May 10 09:20:31 1993
***************
*** 0 ****
--- 1,4 ----
+ extern int use_count_;
+ 
+ #define INC_USE_COUNT	use_count_++
+ #define DEC_USE_COUNT	use_count_--
Index: kernel/Makefile
*** linux.pl9.ALPHA/kernel/Makefile	Fri Dec 11 15:33:52 1992
--- linux/kernel/Makefile	Fri May  7 11:47:03 1993
***************
*** 19,25 ****
  SUBDIRS	= chr_drv blk_drv FPU-emu
  
  OBJS  = sched.o sys_call.o traps.o irq.o dma.o fork.o \
! 	panic.o printk.o vsprintf.o sys.o exit.o \
  	signal.o mktime.o ptrace.o ioport.o itimer.o \
  	info.o
  
--- 19,25 ----
  SUBDIRS	= chr_drv blk_drv FPU-emu
  
  OBJS  = sched.o sys_call.o traps.o irq.o dma.o fork.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 \
  	info.o
  
***************
*** 36,41 ****
--- 36,45 ----
  
  sys_call.o: sys_call.s
  
+ ksyms.o: ksyms.lst ksyms.sh
+ 	sh ksyms.sh > ksyms.s
+ 	$(AS) -o ksyms.o ksyms.s
+ 
  sched.o: sched.c
  	$(CC) $(CFLAGS) $(PROFILING) -fno-omit-frame-pointer -c $<
  
Index: kernel/ksyms.lst
*** /dev/null	Mon May 10 13:39:01 1993
--- linux/kernel/ksyms.lst	Fri May  7 15:01:47 1993
***************
*** 0 ****
--- 1,662 ----
+ _NR_syscalls
+ _ROOT_DEV
+ ____strtok
+ ___bad_page
+ ___bad_pagetable
+ ___get_free_page
+ ___wait_on_buffer
+ ___wait_on_super
+ ___zero_page
+ __ctmp
+ __ctype
+ __edata
+ __end
+ __etext
+ __exit
+ __getitimer
+ __setitimer
+ _accent_table
+ _add_timer
+ _adjust_clock
+ _alignment_check
+ _audit_ptree
+ _aux_device_present
+ _avenrun
+ _bad_task_ptr
+ _base_type
+ _bh_active
+ _bh_base
+ _bh_mask
+ _blank_screen
+ _blankinterval
+ _blk_dev
+ _blk_dev_init
+ _blk_size
+ _blkdev_fops
+ _blkdev_inode_operations
+ _blkdev_open
+ _block_read
+ _block_write
+ _bmap
+ _bounds
+ _bread
+ _bread_page
+ _breada
+ _brelse
+ _bucket_dir
+ _buffer_init
+ _buffermem
+ _cache_add
+ _cache_init
+ _cache_inval_dev
+ _cache_inval_inode
+ _cache_lookup
+ _change_console
+ _check_disk_change
+ _chr_dev_init
+ _chrdev_fops
+ _chrdev_inode_operations
+ _chrdev_open
+ _clear_inode
+ _clear_page_tables
+ _clone_page_tables
+ _close_fp
+ _complete_change_console
+ _con_init
+ _con_open
+ _con_write
+ _console_print
+ _coprocessor_error
+ _coprocessor_segment_overrun
+ _copy_page_tables
+ _copy_to_cooked
+ _core_dump
+ _ctrl_alt_del
+ _current
+ _current_type
+ _date_dos2unix
+ _date_unix2dos
+ _debug
+ _def_blk_fops
+ _def_chr_fops
+ _del_timer
+ _device_not_available
+ _die_if_kernel
+ _divide_error
+ _dload_pages
+ _do_IRQ
+ _do_SAK
+ _do_alignment_check
+ _do_bottom_half
+ _do_bounds
+ _do_coprocessor_error
+ _do_coprocessor_segment_overrun
+ _do_debug
+ _do_device_not_available
+ _do_divide_error
+ _do_double_fault
+ _do_execve
+ _do_exit
+ _do_fast_IRQ
+ _do_floppy
+ _do_general_protection
+ _do_hd
+ _do_int3
+ _do_invalid_TSS
+ _do_invalid_op
+ _do_keyboard_interrupt
+ _do_mknod
+ _do_nmi
+ _do_no_page
+ _do_overflow
+ _do_page_fault
+ _do_reserved
+ _do_screendump
+ _do_segment_not_present
+ _do_select
+ _do_signal
+ _do_stack_segment
+ _do_tty_hangup
+ _do_wp_page
+ _double_fault
+ _drive_info
+ _edata
+ _empty_bad_page
+ _empty_bad_page_table
+ _empty_zero_page
+ _end
+ _errno
+ _etext
+ _ext2_bmap
+ _ext2_bread
+ _ext2_check_dir_entry
+ _ext2_count_free_blocks
+ _ext2_count_free_inodes
+ _ext2_create
+ _ext2_dcache_add
+ _ext2_dcache_invalidate
+ _ext2_dcache_lookup
+ _ext2_dcache_remove
+ _ext2_dir_inode_operations
+ _ext2_file_inode_operations
+ _ext2_file_read
+ _ext2_free_block
+ _ext2_free_inode
+ _ext2_getblk
+ _ext2_ioctl
+ _ext2_link
+ _ext2_lookup
+ _ext2_mkdir
+ _ext2_mknod
+ _ext2_new_block
+ _ext2_new_inode
+ _ext2_permission
+ _ext2_put_inode
+ _ext2_put_super
+ _ext2_read_inode
+ _ext2_read_super
+ _ext2_release
+ _ext2_rename
+ _ext2_rmdir
+ _ext2_statfs
+ _ext2_symlink
+ _ext2_symlink_inode_operations
+ _ext2_truncate
+ _ext2_unlink
+ _ext2_write_inode
+ _ext2_write_super
+ _ext_bmap
+ _ext_bread
+ _ext_count_free_blocks
+ _ext_count_free_inodes
+ _ext_create
+ _ext_dir_inode_operations
+ _ext_file_inode_operations
+ _ext_free_block
+ _ext_free_inode
+ _ext_getblk
+ _ext_link
+ _ext_lookup
+ _ext_mkdir
+ _ext_mknod
+ _ext_new_block
+ _ext_new_inode
+ _ext_put_inode
+ _ext_put_super
+ _ext_read_inode
+ _ext_read_super
+ _ext_release
+ _ext_rename
+ _ext_rmdir
+ _ext_statfs
+ _ext_symlink
+ _ext_symlink_inode_operations
+ _ext_truncate
+ _ext_unlink
+ _ext_write_inode
+ _ext_write_super
+ _fat_access
+ _fat_free
+ _fcntl_getlk
+ _fcntl_init_locks
+ _fcntl_remove_locks
+ _fcntl_setlk
+ _fdtape_big_buffer
+ _fg_console
+ _file_systems
+ _file_table
+ _file_table_init
+ _find_module
+ _floppy_change
+ _floppy_init
+ _floppy_track_buffer
+ _flush_input
+ _flush_output
+ _follow_link
+ _free_blkdev
+ _free_chrdev
+ _free_dma
+ _free_irq
+ _free_modules
+ _free_page
+ _free_page_list
+ _free_page_tables
+ _freeing_modules
+ _fs_may_mount
+ _fs_may_umount
+ _fs_panic
+ _gdt
+ _gendisk_head
+ _general_protection
+ _get_cluster
+ _get_empty_filp
+ _get_empty_inode
+ _get_fs_type
+ _get_hash_table
+ _get_mod_name
+ _get_module_list
+ _get_pipe_inode
+ _get_tty_queue
+ _getblk
+ _getname
+ _getrusage
+ _grow_buffers
+ _hard_math
+ _hard_reset_now
+ _hd_info
+ _hd_init
+ _high_memory
+ _idt
+ _iget
+ _ignore_irq13
+ _in_group_p
+ _init
+ _init_IRQ
+ _init_fifo
+ _inode_init
+ _int3
+ _interruptible_sleep_on
+ _invalid_TSS
+ _invalid_op
+ _invalidate_buffers
+ _invalidate_inodes
+ _iput
+ _irqaction
+ _is_binary
+ _is_ignored
+ _is_orphaned_pgrp
+ _is_read_only
+ _jiffies
+ _jiffies_offset
+ _kbd_dead_keys
+ _kbd_flags
+ _kbd_init
+ _kbd_prev_dead_keys
+ _kbd_table
+ _kbdsave
+ _kd_mksound
+ _kernel_mktime
+ _keypress_wait
+ _kfree_s
+ _kill_pg
+ _kill_proc
+ _kill_sl
+ _kmalloc
+ _last_pid
+ _last_task_used_math
+ _ld_alloc_mem
+ _ld_free_mem
+ _ldiscs
+ _linux_banner
+ _ll_rw_block
+ _ll_rw_page
+ _ll_rw_swap_file
+ _lnamei
+ _lock_creation
+ _lock_fat
+ _log_size
+ _log_to_console
+ _log_wait
+ _lookup
+ _lp_init
+ _lp_table
+ _math_emulate
+ _math_state_restore
+ _mem_init
+ _mem_map
+ _memchr
+ _memcmp
+ _memcpy
+ _memmove
+ _memset
+ _memsetw
+ _minix_bmap
+ _minix_bread
+ _minix_count_free_blocks
+ _minix_count_free_inodes
+ _minix_create
+ _minix_dir_inode_operations
+ _minix_file_inode_operations
+ _minix_free_block
+ _minix_free_inode
+ _minix_getblk
+ _minix_link
+ _minix_lookup
+ _minix_mkdir
+ _minix_mknod
+ _minix_new_block
+ _minix_new_inode
+ _minix_put_inode
+ _minix_put_super
+ _minix_read_inode
+ _minix_read_super
+ _minix_rename
+ _minix_rmdir
+ _minix_statfs
+ _minix_symlink
+ _minix_symlink_inode_operations
+ _minix_truncate
+ _minix_unlink
+ _minix_write_inode
+ _module_list
+ _mount_root
+ _mouse_init
+ _msdos_add_cluster
+ _msdos_bmap
+ _msdos_create
+ _msdos_dir_inode_operations
+ _msdos_file_inode_operations
+ _msdos_file_inode_operations_no_bmap
+ _msdos_get_entry
+ _msdos_lookup
+ _msdos_mkdir
+ _msdos_notify_change
+ _msdos_parent_ino
+ _msdos_put_inode
+ _msdos_put_super
+ _msdos_read_inode
+ _msdos_read_super
+ _msdos_rename
+ _msdos_rmdir
+ _msdos_scan
+ _msdos_smap
+ _msdos_statfs
+ _msdos_subdirs
+ _msdos_truncate
+ _msdos_unlink
+ _msdos_write_inode
+ _namei
+ _need_resched
+ _nmi
+ _no_idt
+ _no_sys
+ _notify_change
+ _notify_parent
+ _nr_buffer_heads
+ _nr_buffers
+ _nr_free_pages
+ _nr_secondary_pages
+ _oom
+ _open_namei
+ _overflow
+ _page_fault
+ _paging_init
+ _panic
+ _permission
+ _pg0
+ _printk
+ _proc_array_inode_operations
+ _proc_base_inode_operations
+ _proc_fd_inode_operations
+ _proc_kmsg_inode_operations
+ _proc_link_inode_operations
+ _proc_match
+ _proc_mem_inode_operations
+ _proc_put_inode
+ _proc_put_super
+ _proc_read_inode
+ _proc_read_super
+ _proc_root_inode_operations
+ _proc_statfs
+ _proc_write_inode
+ _prof_buffer
+ _prof_len
+ _pty_open
+ _put_dirty_page
+ _put_super
+ _put_tty_queue
+ _putname
+ _ramdisk_size
+ _rd_init
+ _rd_length
+ _rd_load
+ _rd_start
+ _rdwr_pipe_fops
+ _read_ahead
+ _read_pipe_fops
+ _redirect
+ _register_blkdev
+ _register_chrdev
+ _register_console
+ _release
+ _remap_page_range
+ _request
+ _request_dma
+ _request_done
+ _request_irq
+ _reserved
+ _resetup_one_dev
+ _root_mountflags
+ _rs_init
+ _rs_open
+ _rs_table
+ _rs_write
+ _rw_swap_page
+ _save_v86_state
+ _sched_init
+ _schedule
+ _screen_info
+ _secondary_page_list
+ _segment_not_present
+ _send_sig
+ _session_of_pgrp
+ _set_device_ro
+ _setup_rw_floppy
+ _show_mem
+ _show_state
+ _shrink_buffers
+ _si_meminfo
+ _si_swapinfo
+ _simple_strtoul
+ _sleep_on
+ _sock_awaitconn
+ _sock_fcntl
+ _sock_init
+ _sockets
+ _socki_lookup
+ _sound_mem_init
+ _soundcard_init
+ _sprintf
+ _stack
+ _stack_segment
+ _stack_start
+ _start_kernel
+ _startup_time
+ _strcat
+ _strchr
+ _strcmp
+ _strcpy
+ _strcspn
+ _strlen
+ _strncat
+ _strncmp
+ _strncpy
+ _strpbrk
+ _strrchr
+ _strspn
+ _strstr
+ _strtok
+ _super_block
+ _swap_duplicate
+ _swap_free
+ _swap_in
+ _swapper_pg_dir
+ _symbol_table
+ _symbol_table_size
+ _sync_dev
+ _sync_inodes
+ _sync_supers
+ _sys_access
+ _sys_acct
+ _sys_alarm
+ _sys_break
+ _sys_brk
+ _sys_call_table
+ _sys_chdir
+ _sys_chmod
+ _sys_chown
+ _sys_chroot
+ _sys_close
+ _sys_creat
+ _sys_create_module
+ _sys_delete_module
+ _sys_dup
+ _sys_dup2
+ _sys_execve
+ _sys_exit
+ _sys_fchmod
+ _sys_fchown
+ _sys_fcntl
+ _sys_fork
+ _sys_fstat
+ _sys_fstatfs
+ _sys_fsync
+ _sys_ftime
+ _sys_ftruncate
+ _sys_get_kernel_syms
+ _sys_getegid
+ _sys_geteuid
+ _sys_getgid
+ _sys_getgroups
+ _sys_getitimer
+ _sys_getpgrp
+ _sys_getpid
+ _sys_getppid
+ _sys_getpriority
+ _sys_getrlimit
+ _sys_getrusage
+ _sys_gettimeofday
+ _sys_getuid
+ _sys_gtty
+ _sys_idle
+ _sys_init_module
+ _sys_ioctl
+ _sys_ioperm
+ _sys_iopl
+ _sys_ipc
+ _sys_kill
+ _sys_link
+ _sys_lock
+ _sys_lseek
+ _sys_lstat
+ _sys_mkdir
+ _sys_mknod
+ _sys_mmap
+ _sys_mount
+ _sys_mpx
+ _sys_munmap
+ _sys_newfstat
+ _sys_newlstat
+ _sys_newstat
+ _sys_newuname
+ _sys_nice
+ _sys_open
+ _sys_pause
+ _sys_phys
+ _sys_pipe
+ _sys_prof
+ _sys_profil
+ _sys_ptrace
+ _sys_read
+ _sys_readdir
+ _sys_readlink
+ _sys_reboot
+ _sys_rename
+ _sys_rmdir
+ _sys_select
+ _sys_setgid
+ _sys_setgroups
+ _sys_sethostname
+ _sys_setitimer
+ _sys_setpgid
+ _sys_setpriority
+ _sys_setregid
+ _sys_setreuid
+ _sys_setrlimit
+ _sys_setsid
+ _sys_settimeofday
+ _sys_setuid
+ _sys_setup
+ _sys_sgetmask
+ _sys_sigaction
+ _sys_signal
+ _sys_sigpending
+ _sys_sigreturn
+ _sys_sigsuspend
+ _sys_socketcall
+ _sys_ssetmask
+ _sys_stat
+ _sys_statfs
+ _sys_stime
+ _sys_stty
+ _sys_swapoff
+ _sys_swapon
+ _sys_symlink
+ _sys_sync
+ _sys_sysinfo
+ _sys_syslog
+ _sys_time
+ _sys_times
+ _sys_truncate
+ _sys_tz
+ _sys_ulimit
+ _sys_umask
+ _sys_umount
+ _sys_uname
+ _sys_unlink
+ _sys_uselib
+ _sys_ustat
+ _sys_utime
+ _sys_vhangup
+ _sys_vm86
+ _sys_wait4
+ _sys_waitpid
+ _sys_write
+ _syscall_trace
+ _system_call
+ _system_utsname
+ _task
+ _timer_active
+ _timer_table
+ _tmp_floppy_area
+ _trap_init
+ _tty_bh_routine
+ _tty_check_write
+ _tty_hangup
+ _tty_hung_up_p
+ _tty_init
+ _tty_ioctl
+ _tty_read_flush
+ _tty_read_raw_data
+ _tty_register_ldisc
+ _tty_table
+ _tty_termios
+ _tty_unhangup
+ _tty_vhangup
+ _tty_write_data
+ _tty_write_flush
+ _unblank_screen
+ _unexpected_hd_interrupt
+ _unix_proto_ops
+ _unlock_creation
+ _unlock_fat
+ _unmap_page_range
+ _update_screen
+ _user_params
+ _user_stack
+ _vc_scrbuf
+ _verify_area
+ _video_num_columns
+ _video_num_lines
+ _vsprintf
+ _vt_cons
+ _vt_ioctl
+ _vt_waitactive
+ _wait_for_keypress
+ _wait_for_request
+ _wait_until_sent
+ _wake_up
+ _wake_up_interruptible
+ _write_pipe_fops
+ _zeromap_page_range
+ ret_from_sys_call
Index: kernel/ksyms.sh
*** /dev/null	Mon May 10 13:39:01 1993
--- linux/kernel/ksyms.sh	Sun Jan 24 15:06:22 1993
***************
*** 0 ****
--- 1,25 ----
+ # 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[];
+ 
+ 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 " $0; print "	.long strings+" stringloc; stringloc += length($0) + 1;}' ksyms.tmp
+ echo '
+ strings:'
+ awk '{print "	.ascii \"" $0 "\\0\""}' ksyms.tmp
+ rm ksyms.tmp
Index: kernel/module.c
*** /dev/null	Mon May 10 13:39:01 1993
--- linux/kernel/module.c	Fri May  7 15:14:05 1993
***************
*** 0 ****
--- 1,255 ----
+ #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>
+ 
+ 
+ extern unsigned long ld_alloc_mem(int);
+ extern void ld_free_mem(unsigned long, int);
+ 
+ struct module *module_list = NULL;
+ int freeing_modules;		/* true if some modules are marked for deletion */
+ 
+ int get_mod_name(char *, char *);
+ struct module *find_module(const char *);
+ int free_modules(void);
+ 
+ 
+ int no_sys()
+ {
+ 	return -ENOSYS;
+ }
+ 
+ /*
+  * Allocate space for a module.
+  */
+ int sys_create_module(char *module_name, unsigned long size)
+ {
+ 	int npages;
+ 	unsigned long addr;
+ 	int len;
+ 	char name[MOD_MAX_NAME];
+ 	char *savename;
+ 	struct module *mp;
+ 	int error;
+ 
+ 	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 = kmalloc(len, GFP_KERNEL)) == NULL)
+ 		return -ENOMEM;
+ 	memcpy(savename, name, len);
+ 	if ((mp = kmalloc(sizeof *mp, GFP_KERNEL)) == NULL) {
+ 		kfree(savename);
+ 		return -ENOMEM;
+ 	}
+ 	npages = (size + sizeof (int) + 4095) / 4096;
+ 	if ((addr = ld_alloc_mem(npages)) == 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 created:  mp=0x%x, addr=0x%x\n",
+ 	       mp->name, mp, addr + sizeof (int));
+ 	return addr;
+ }
+ 
+ /*
+  * Initialize a module.
+  */
+ 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 ((error = get_mod_name(module_name, name)) != 0)
+ 		return error;
+ 	printk("init_module %s, codesize = %d, ", name, 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=0x%x, cleanup=0x%x\n", rt.init, rt.cleanup);
+ 	mp->cleanup = rt.cleanup;
+ 	if ((*rt.init)() != 0)
+ 		return -EBUSY;
+ 	mp->state = MOD_RUNNING;
+ 	return 0;
+ }
+ 
+ int sys_delete_module(char *module_name)
+ {
+ 	struct module *mp;
+ 	char name[MOD_MAX_NAME];
+ 	int error;
+ 
+ 	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.
+  */
+ 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->state == MOD_DELETED || strcmp(mp->name, name) != 0) ;
+ 	     mp = mp->next);
+ 	return mp;
+ }
+ 
+ 
+ /*
+  * Try to free modules which have been marked for deletion.  Returns nonzero
+  * if a module was actually freed.
+  */
+ int free_modules()
+ {
+ 	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;
+ 			ld_free_mem(mp->addr, mp->size);
+ 			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;
+ }
Index: mm/memory.c
*** linux.pl9.ALPHA/mm/memory.c	Mon May 10 08:42:40 1993
--- linux/mm/memory.c	Fri May  7 11:47:04 1993
***************
*** 58,63 ****
--- 58,65 ----
  
  unsigned short * mem_map = NULL;
  
+ unsigned long *dload_pages;	/* for dynamic loading - KA */
+ 
  #define CODE_SPACE(addr,p) ((addr) < (p)->end_code)
  
  /*
***************
*** 1033,1038 ****
--- 1035,1049 ----
  			address += 4096;
  		}
  	}
+ 	/*
+ 	 * Set up 4 MB of virtual address space for dynamicly loaded
+ 	 * kernel code.
+ 	 */
+ 	dload_pages = (unsigned long *) start_mem;
+ 	start_mem += 4096;
+ 	memset(dload_pages, 0, 4096);
+ 	swapper_pg_dir[800] = (unsigned long) dload_pages | 7;
+ 
  	invalidate();
  	return start_mem;
  }
Index: mm/swap.c
*** linux.pl9.ALPHA/mm/swap.c	Sat Apr 17 11:56:26 1993
--- linux/mm/swap.c	Fri May  7 11:47:04 1993
***************
*** 44,49 ****
--- 44,53 ----
  
  extern unsigned long free_page_list;
  
+ extern int freeing_modules;		/* from module.c */
+ extern int free_modules(void);		/* from module.c */
+ 
+ 
  /*
   * The following are used to make sure we don't thrash too much...
   * NOTE!! NR_LAST_FREE_PAGES must be a power of 2...
***************
*** 329,334 ****
--- 333,340 ----
  {
  	int i=6;
  
+ 	if (free_modules())
+ 		return 1;
  	while (i--) {
  		if (shrink_buffers(i))
  			return 1;
***************
*** 722,724 ****
--- 728,794 ----
  	val->totalswap <<= PAGE_SHIFT;
  	return;
  }
+ 
+ 
+ extern unsigned long *dload_pages;	/* set up in memory.c */
+ 
+ /*
+  * Allocate a block of pages at contiguous virtual memory addresses.
+  * Used for dynamic loading of kernel modules.
+  */
+ unsigned long ld_alloc_mem(int npages)
+ {
+ 	int i;
+ 	int freecount;
+ 	int freeloc;
+ 	unsigned long page;
+ 
+ 	freecount = 0;
+ 	for (i = 0 ; i < 1024 ; i++) {
+ 		if (dload_pages[i] != 0) {
+ 			freecount = 0;
+ 		} else if (++freecount >= npages) {
+ 			break;
+ 		}
+ 	}
+ 	if (freecount < npages)
+ 		return 0;
+ 	freeloc = i + 1 - npages;
+ 	do {
+ 		dload_pages[i] = 2;  /* mark page as taken */
+ 	} while (--i >= freeloc);
+ 	i += npages;
+ 	for (i = 0 ; i < npages ; i++) {
+ 		page = get_free_page(GFP_KERNEL);
+ 		if (page == 0)
+ 			goto bad;
+ 		dload_pages[freeloc + i] = page | 7;
+ 	}
+ 	invalidate();
+ 	return (unsigned long)(freeloc + 32 * 1024) * 4096;
+ 
+ bad:
+ 	for (i = 0 ; i < npages ; i++) {
+ 		page = dload_pages[freeloc + i];
+ 		if (page != 2)
+ 			free_page(page);
+ 		dload_pages[freeloc + i] = 0;
+ 	}
+ 	return 0;
+ }
+ 
+ /*
+  * Free memory obtained from ld_alloc_mem.
+  */
+ void ld_free_mem(unsigned long addr, int npages)
+ {
+ 	int i;
+ 	int page;
+ 	int freeloc = (addr >> 12) - 32 * 1024;
+ 
+ 	for (i = 0 ; i < npages ; i++) {
+ 		page = dload_pages[freeloc + i];
+ 		free_page(page);
+ 		dload_pages[freeloc + i] = 0;
+ 	}
+ }
