⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 misc.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: misc.c,v 1.31 2000/12/14 22:57:25 davem Exp $ * misc.c: Miscelaneous syscall emulation for Solaris * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) */#include <linux/config.h>#include <linux/module.h> #include <linux/types.h>#include <linux/smp_lock.h>#include <linux/utsname.h>#include <linux/limits.h>#include <linux/mm.h>#include <linux/smp.h>#include <linux/mman.h>#include <linux/file.h>#include <linux/timex.h>#include <asm/uaccess.h>#include <asm/string.h>#include <asm/oplib.h>#include <asm/idprom.h>#include "conv.h"/* Conversion from Linux to Solaris errnos. 0-34 are identity mapped.   Some Linux errnos (EPROCLIM, EDOTDOT, ERREMOTE, EUCLEAN, ENOTNAM,    ENAVAIL, EISNAM, EREMOTEIO, ENOMEDIUM, EMEDIUMTYPE) have no Solaris   equivalents. I return EINVAL in that case, which is very wrong. If   someone suggest a better value for them, you're welcomed.   On the other side, Solaris ECANCELED and ENOTSUP have no Linux equivalents,   but that doesn't matter here. --jj */int solaris_err_table[] = {/* 0 */  0, 1, 2, 3, 4, 5, 6, 7, 8, 9,/* 10 */  10, 11, 12, 13, 14, 15, 16, 17, 18, 19,/* 20 */  20, 21, 22, 23, 24, 25, 26, 27, 28, 29,/* 30 */  30, 31, 32, 33, 34, 22, 150, 149, 95, 96,/* 40 */  97, 98, 99, 120, 121, 122, 123, 124, 125, 126, /* 50 */ 127, 128, 129, 130, 131, 132, 133, 134, 143, 144,/* 60 */ 145, 146, 90, 78, 147, 148, 93, 22, 94, 49,/* 70 */ 151, 66, 60, 62, 63, 35, 77, 36, 45, 46, /* 80 */ 64, 22, 67, 68, 69, 70, 71, 74, 22, 82, /* 90 */ 89, 92, 79, 81, 37, 38, 39, 40, 41, 42,/* 100 */ 43, 44, 50, 51, 52, 53, 54, 55, 56, 57,/* 110 */ 87, 61, 84, 65, 83, 80, 91, 22, 22, 22,/* 120 */ 22, 22, 88, 86, 85, 22, 22,};#define SOLARIS_NR_OPEN	256static u32 do_solaris_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u64 off){	struct file *file = NULL;	unsigned long retval, ret_type;	/* Do we need it here? */	set_personality(PER_SVR4);	if (flags & MAP_NORESERVE) {		static int cnt = 0;				if (cnt < 5) {			printk("%s:  unimplemented Solaris MAP_NORESERVE mmap() flag\n",			       current->comm);			cnt++;		}		flags &= ~MAP_NORESERVE;	}	retval = -EBADF;	if(!(flags & MAP_ANONYMOUS)) {		if(fd >= SOLARIS_NR_OPEN)			goto out; 		file = fget(fd);		if (!file)			goto out;		else {			struct inode * inode = file->f_dentry->d_inode;			if(MAJOR(inode->i_rdev) == MEM_MAJOR &&			   MINOR(inode->i_rdev) == 5) {				flags |= MAP_ANONYMOUS;				fput(file);				file = NULL;			}		}	}	retval = -EINVAL;	len = PAGE_ALIGN(len);	if(!(flags & MAP_FIXED))		addr = 0;	else if (len > 0xf0000000UL || addr > 0xf0000000UL - len)		goto out_putf;	ret_type = flags & _MAP_NEW;	flags &= ~_MAP_NEW;	down(&current->mm->mmap_sem);	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);	retval = do_mmap(file,			 (unsigned long) addr, (unsigned long) len,			 (unsigned long) prot, (unsigned long) flags, off);	up(&current->mm->mmap_sem);	if(!ret_type)		retval = ((retval < 0xf0000000) ? 0 : retval);	                        out_putf:	if (file)		fput(file);out:	return (u32) retval;}asmlinkage u32 solaris_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 off){	return do_solaris_mmap(addr, len, prot, flags, fd, (u64) off);}asmlinkage u32 solaris_mmap64(struct pt_regs *regs, u32 len, u32 prot, u32 flags, u32 fd, u32 offhi){	u32 offlo;		if (regs->u_regs[UREG_G1]) {		if (get_user (offlo, (u32 *)(long)((u32)regs->u_regs[UREG_I6] + 0x5c)))			return -EFAULT;	} else {		if (get_user (offlo, (u32 *)(long)((u32)regs->u_regs[UREG_I6] + 0x60)))			return -EFAULT;	}	return do_solaris_mmap((u32)regs->u_regs[UREG_I0], len, prot, flags, fd, (((u64)offhi)<<32)|offlo);}asmlinkage int solaris_brk(u32 brk){	int (*sunos_brk)(u32) = (int (*)(u32))SUNOS(17);		return sunos_brk(brk);}#define set_utsfield(to, from, dotchop, countfrom) {			\	char *p; 							\	int i, len = (countfrom) ? 					\		((sizeof(to) > sizeof(from) ? 				\			sizeof(from) : sizeof(to))) : sizeof(to); 	\	if (copy_to_user(to, from, len))				\		return -EFAULT;						\	if (dotchop) 							\		for (p=from,i=0; *p && *p != '.' && --len; p++,i++); 	\	else 								\		i = len - 1; 						\	if (__put_user('\0', (char *)(to+i)))				\		return -EFAULT;						\}struct sol_uname {	char sysname[9];	char nodename[9];	char release[9];	char version[9];	char machine[9];};struct sol_utsname {	char sysname[257];	char nodename[257];	char release[257];	char version[257];	char machine[257];};static char *machine(void){	switch (sparc_cpu_model) {	case sun4: return "sun4";	case sun4c: return "sun4c";	case sun4e: return "sun4e";	case sun4m: return "sun4m";	case sun4d: return "sun4d";	case sun4u: return "sun4u";	default: return "sparc";	}}static char *platform(char *buffer){	int len;	*buffer = 0;	len = prom_getproperty(prom_root_node, "name", buffer, 256);	if(len > 0)		buffer[len] = 0;	if (*buffer) {		char *p;		for (p = buffer; *p; p++)			if (*p == '/' || *p == ' ') *p = '_';		return buffer;	}	return "sun4u";}static char *serial(char *buffer){	int node = prom_getchild(prom_root_node);	int len;	node = prom_searchsiblings(node, "options");	*buffer = 0;	len = prom_getproperty(node, "system-board-serial#", buffer, 256);	if(len > 0)		buffer[len] = 0;	if (!*buffer)		return "4512348717234";	else		return buffer;}asmlinkage int solaris_utssys(u32 buf, u32 flags, int which, u32 buf2){	switch (which) {	case 0:	/* old uname */		/* Let's cheat */		set_utsfield(((struct sol_uname *)A(buf))->sysname, 			"SunOS", 1, 0);		down_read(&uts_sem);		set_utsfield(((struct sol_uname *)A(buf))->nodename, 			system_utsname.nodename, 1, 1);		up_read(&uts_sem);		set_utsfield(((struct sol_uname *)A(buf))->release, 			"2.6", 0, 0);		set_utsfield(((struct sol_uname *)A(buf))->version, 			"Generic", 0, 0);		set_utsfield(((struct sol_uname *)A(buf))->machine, 			machine(), 0, 0);		return 0;	case 2: /* ustat */		return -ENOSYS;	case 3: /* fusers */		return -ENOSYS;	default:		return -ENOSYS;	}}asmlinkage int solaris_utsname(u32 buf){	/* Why should we not lie a bit? */	down_read(&uts_sem);	set_utsfield(((struct sol_utsname *)A(buf))->sysname, 			"SunOS", 0, 0);	set_utsfield(((struct sol_utsname *)A(buf))->nodename, 			system_utsname.nodename, 1, 1);	set_utsfield(((struct sol_utsname *)A(buf))->release, 			"5.6", 0, 0);	set_utsfield(((struct sol_utsname *)A(buf))->version, 			"Generic", 0, 0);	set_utsfield(((struct sol_utsname *)A(buf))->machine, 			machine(), 0, 0);	up_read(&uts_sem);	return 0;}#define SI_SYSNAME		1       /* return name of operating system */#define SI_HOSTNAME		2       /* return name of node */#define SI_RELEASE		3       /* return release of operating system */#define SI_VERSION		4       /* return version field of utsname */#define SI_MACHINE		5       /* return kind of machine */#define SI_ARCHITECTURE		6       /* return instruction set arch */#define SI_HW_SERIAL		7       /* return hardware serial number */#define SI_HW_PROVIDER		8       /* return hardware manufacturer */#define SI_SRPC_DOMAIN		9       /* return secure RPC domain */#define SI_PLATFORM		513     /* return platform identifier */asmlinkage int solaris_sysinfo(int cmd, u32 buf, s32 count){	char *p, *q, *r;	char buffer[256];	int len;		/* Again, we cheat :)) */	switch (cmd) {	case SI_SYSNAME: r = "SunOS"; break;	case SI_HOSTNAME:		r = buffer + 256;		down_read(&uts_sem);		for (p = system_utsname.nodename, q = buffer; 		     q < r && *p && *p != '.'; *q++ = *p++);		up_read(&uts_sem);		*q = 0;		r = buffer;		break;	case SI_RELEASE: r = "5.6"; break;	case SI_MACHINE: r = machine(); break;	case SI_ARCHITECTURE: r = "sparc"; break;	case SI_HW_PROVIDER: r = "Sun_Microsystems"; break;	case SI_HW_SERIAL: r = serial(buffer); break;	case SI_PLATFORM: r = platform(buffer); break;	case SI_SRPC_DOMAIN: r = ""; break;	case SI_VERSION: r = "Generic"; break;	default: return -EINVAL;	}	len = strlen(r) + 1;	if (count < len) {		if (copy_to_user((char *)A(buf), r, count - 1) ||		    __put_user(0, (char *)A(buf) + count - 1))			return -EFAULT;	} else {		if (copy_to_user((char *)A(buf), r, len))			return -EFAULT;	}	return len;}#define	SOLARIS_CONFIG_NGROUPS			2#define	SOLARIS_CONFIG_CHILD_MAX		3#define	SOLARIS_CONFIG_OPEN_FILES		4#define	SOLARIS_CONFIG_POSIX_VER		5#define	SOLARIS_CONFIG_PAGESIZE			6#define	SOLARIS_CONFIG_CLK_TCK			7#define	SOLARIS_CONFIG_XOPEN_VER		8#define	SOLARIS_CONFIG_PROF_TCK			10#define	SOLARIS_CONFIG_NPROC_CONF		11#define	SOLARIS_CONFIG_NPROC_ONLN		12#define	SOLARIS_CONFIG_AIO_LISTIO_MAX		13#define	SOLARIS_CONFIG_AIO_MAX			14#define	SOLARIS_CONFIG_AIO_PRIO_DELTA_MAX	15#define	SOLARIS_CONFIG_DELAYTIMER_MAX		16#define	SOLARIS_CONFIG_MQ_OPEN_MAX		17#define	SOLARIS_CONFIG_MQ_PRIO_MAX		18#define	SOLARIS_CONFIG_RTSIG_MAX		19#define	SOLARIS_CONFIG_SEM_NSEMS_MAX		20#define	SOLARIS_CONFIG_SEM_VALUE_MAX		21#define	SOLARIS_CONFIG_SIGQUEUE_MAX		22#define	SOLARIS_CONFIG_SIGRT_MIN		23#define	SOLARIS_CONFIG_SIGRT_MAX		24#define	SOLARIS_CONFIG_TIMER_MAX		25#define	SOLARIS_CONFIG_PHYS_PAGES		26#define	SOLARIS_CONFIG_AVPHYS_PAGES		27extern unsigned prom_cpu_nodes[NR_CPUS];asmlinkage int solaris_sysconf(int id){	switch (id) {	case SOLARIS_CONFIG_NGROUPS:	return NGROUPS_MAX;	case SOLARIS_CONFIG_CHILD_MAX:	return CHILD_MAX;	case SOLARIS_CONFIG_OPEN_FILES:	return OPEN_MAX;	case SOLARIS_CONFIG_POSIX_VER:	return 199309;	case SOLARIS_CONFIG_PAGESIZE:	return PAGE_SIZE;	case SOLARIS_CONFIG_XOPEN_VER:	return 3;	case SOLARIS_CONFIG_CLK_TCK:	case SOLARIS_CONFIG_PROF_TCK:		return prom_getintdefault(prom_cpu_nodes[smp_processor_id()],					  "clock-frequency", 167000000);#ifdef CONFIG_SMP		case SOLARIS_CONFIG_NPROC_CONF:	return NR_CPUS;	case SOLARIS_CONFIG_NPROC_ONLN:	return smp_num_cpus;#else	case SOLARIS_CONFIG_NPROC_CONF:	return 1;	case SOLARIS_CONFIG_NPROC_ONLN:	return 1;#endif	case SOLARIS_CONFIG_SIGRT_MIN:		return 37;	case SOLARIS_CONFIG_SIGRT_MAX:		return 44;	case SOLARIS_CONFIG_PHYS_PAGES:	case SOLARIS_CONFIG_AVPHYS_PAGES:		{			struct sysinfo s;						si_meminfo(&s);			if (id == SOLARIS_CONFIG_PHYS_PAGES)				return s.totalram >>= PAGE_SHIFT;			else				return s.freeram >>= PAGE_SHIFT;		}	/* XXX support these as well -jj */	case SOLARIS_CONFIG_AIO_LISTIO_MAX:	return -EINVAL;	case SOLARIS_CONFIG_AIO_MAX:		return -EINVAL;	case SOLARIS_CONFIG_AIO_PRIO_DELTA_MAX:	return -EINVAL;	case SOLARIS_CONFIG_DELAYTIMER_MAX:	return -EINVAL;	case SOLARIS_CONFIG_MQ_OPEN_MAX:	return -EINVAL;	case SOLARIS_CONFIG_MQ_PRIO_MAX:	return -EINVAL;	case SOLARIS_CONFIG_RTSIG_MAX:		return -EINVAL;	case SOLARIS_CONFIG_SEM_NSEMS_MAX:	return -EINVAL;	case SOLARIS_CONFIG_SEM_VALUE_MAX:	return -EINVAL;	case SOLARIS_CONFIG_SIGQUEUE_MAX:	return -EINVAL;	case SOLARIS_CONFIG_TIMER_MAX:		return -EINVAL;	default: return -EINVAL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -