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

📄 nfs.c

📁 关于s3c2440之bootloader的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * vivi/net/nfs.c  * * Based on u-boot * * $Id: nfs.c,v 1.0 2004/08/12 11:14:01 kingmonkey Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Description: net nfs protocol routines . * */ #include "printk.h"#include "command.h"#include "net.h"#include "nfs.h"#include "bootp.h"#include <malloc.h>#include <string.h>/*#define NFS_DEBUG*/#if (CONFIG_CMD_NET) && CONFIG_CMD_NFS)#define HASHES_PER_LINE 65	/* Number of "loading" hashes per line	*/#define NFS_TIMEOUT 10static int fs_mounted = 0;static unsigned long rpc_id = 0;static int nfs_offset = -1;static int nfs_len;static char dirfh[NFS_FHSIZE];	/* file handle of directory */static char filefh[NFS_FHSIZE]; /* file handle of kernel image */static IPaddr_t NfsServerIP;static int	NfsSrvMountPort;static int	NfsSrvNfsPort;static int	NfsOurPort;static int	NfsTimeoutCount;static int	NfsState;#define STATE_PRCLOOKUP_PROG_MOUNT_REQ	1#define STATE_PRCLOOKUP_PROG_NFS_REQ	2#define STATE_MOUNT_REQ			3#define STATE_UMOUNT_REQ		4#define STATE_LOOKUP_REQ		5#define STATE_READ_REQ			6#define STATE_READLINK_REQ		7static char default_filename[64];static char *nfs_filename;static char *nfs_path;static char nfs_path_buff[2048];static __inline__ voidstore_block (uchar * src, unsigned offset, unsigned len){	ulong newsize = offset + len;	(void)memcpy ((void *)(load_addr + offset), src, len);		if (NetBootFileXferSize < (offset+len))		NetBootFileXferSize = newsize;}static char*basename (char *path){	char *fname;	fname = path + strlen(path) - 1;	while (fname >= path) {		if (*fname == '/') {			fname++;			break;		}		fname--;	}	return fname;}static char*dirname (char *path){	char *fname;	fname = basename (path);	--fname;	*fname = '\0';	return path;}/**************************************************************************RPC_ADD_CREDENTIALS - Add RPC authentication/verifier entries**************************************************************************/static long *rpc_add_credentials (long *p){	int hl;	int hostnamelen;	char hostname[256];	strcpy (hostname, "");	hostnamelen=strlen (hostname);	/* Here's the executive summary on authentication requirements of the	 * various NFS server implementations:	Linux accepts both AUTH_NONE	 * and AUTH_UNIX authentication (also accepts an empty hostname field	 * in the AUTH_UNIX scheme).  *BSD refuses AUTH_NONE, but accepts	 * AUTH_UNIX (also accepts an empty hostname field in the AUTH_UNIX	 * scheme).  To be safe, use AUTH_UNIX and pass the hostname if we have	 * it (if the BOOTP/DHCP reply didn't give one, just use an empty	 * hostname).  */	hl = (hostnamelen + 3) & ~3;	/* Provide an AUTH_UNIX credential.  */	*p++ = htonl(1);		/* AUTH_UNIX */	*p++ = htonl(hl+20);		/* auth length */	*p++ = htonl(0);		/* stamp */	*p++ = htonl(hostnamelen);	/* hostname string */	if (hostnamelen & 3) {		*(p + hostnamelen / 4) = 0; /* add zero padding */	}	memcpy (p, hostname, hostnamelen);	p += hl / 4;	*p++ = 0;			/* uid */	*p++ = 0;			/* gid */	*p++ = 0;			/* auxiliary gid list */	/* Provide an AUTH_NONE verifier.  */	*p++ = 0;			/* AUTH_NONE */	*p++ = 0;			/* auth length */	return p;}/**************************************************************************RPC_LOOKUP - Lookup RPC Port numbers**************************************************************************/static voidrpc_req (int rpc_prog, int rpc_proc, u32 *data, int datalen){	struct rpc_t pkt;	unsigned long id;	u32 *p;	int pktlen;	int sport;	id = ++rpc_id;	pkt.u.call.id = htonl(id);	pkt.u.call.type = htonl(MSG_CALL);	pkt.u.call.rpcvers = htonl(2);	/* use RPC version 2 */	pkt.u.call.prog = htonl(rpc_prog);	pkt.u.call.vers = htonl(2);	/* portmapper is version 2 */	pkt.u.call.proc = htonl(rpc_proc);	p = (u32 *)&(pkt.u.call.data);	if (datalen)		memcpy ((char *)p, (char *)data, datalen*sizeof(u32));	pktlen = (char *)p + datalen*sizeof(u32) - (char *)&pkt;	memcpy ((char *)NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE, (char *)&pkt, pktlen);	if (rpc_prog == PROG_PORTMAP)		sport = SUNRPC_PORT;	else if (rpc_prog == PROG_MOUNT)		sport = NfsSrvMountPort;	else		sport = NfsSrvNfsPort;	NetSendUDPPacket (NetServerEther, NfsServerIP, sport, NfsOurPort, pktlen);}/**************************************************************************RPC_LOOKUP - Lookup RPC Port numbers**************************************************************************/static voidrpc_lookup_req (int prog, int ver){	u32 data[16];	data[0] = 0; data[1] = 0;	/* auth credential */	data[2] = 0; data[3] = 0;	/* auth verifier */	data[4] = htonl(prog);	data[5] = htonl(ver);	data[6] = htonl(17);	/* IP_UDP */	data[7] = 0;	rpc_req (PROG_PORTMAP, PORTMAP_GETPORT, data, 8);}/**************************************************************************NFS_MOUNT - Mount an NFS Filesystem**************************************************************************/static voidnfs_mount_req (char *path){	u32 data[1024];	u32 *p;	int len;	int pathlen;	pathlen = strlen (path);	p = &(data[0]);	p = (u32 *)rpc_add_credentials((long *)p);	*p++ = htonl(pathlen);	if (pathlen & 3) *(p + pathlen / 4) = 0;	memcpy (p, path, pathlen);	p += (pathlen + 3) / 4;	len = (u32 *)p - (u32 *)&(data[0]);	rpc_req (PROG_MOUNT, MOUNT_ADDENTRY, data, len);}/**************************************************************************NFS_UMOUNTALL - Unmount all our NFS Filesystems on the Server**************************************************************************/static voidnfs_umountall_req (void){	u32 data[1024];	u32 *p;	int len;	if ((NfsSrvMountPort == -1) || (!fs_mounted)) {		/* Nothing mounted, nothing to umount */		return;	}	p = &(data[0]);	p = (u32 *)rpc_add_credentials ((long *)p);	len = (u32 *)p - (u32 *)&(data[0]);	rpc_req (PROG_MOUNT, MOUNT_UMOUNTALL, data, len);}/*************************************************************************** * NFS_READLINK (AH 2003-07-14) * This procedure is called when read of the first block fails - * this probably happens when it's a directory or a symlink * In case of successful readlink(), the dirname is manipulated, * so that inside the nfs() function a recursion can be done. **************************************************************************/static voidnfs_readlink_req (void){	u32 data[1024];	u32 *p;	int len;	p = &(data[0]);	p = (u32 *)rpc_add_credentials ((long *)p);	memcpy (p, filefh, NFS_FHSIZE);	p += (NFS_FHSIZE / 4);	len = (u32 *)p - (u32 *)&(data[0]);	rpc_req (PROG_NFS, NFS_READLINK, data, len);}/**************************************************************************NFS_LOOKUP - Lookup Pathname**************************************************************************/static voidnfs_lookup_req (char *fname){	u32 data[1024];	u32 *p;	int len;	int fnamelen;	fnamelen = strlen (fname);	p = &(data[0]);	p = (u32 *)rpc_add_credentials ((long *)p);	memcpy (p, dirfh, NFS_FHSIZE);	p += (NFS_FHSIZE / 4);	*p++ = htonl(fnamelen);	if (fnamelen & 3) *(p + fnamelen / 4) = 0;	memcpy (p, fname, fnamelen);	p += (fnamelen + 3) / 4;	len = (u32 *)p - (u32 *)&(data[0]);	rpc_req (PROG_NFS, NFS_LOOKUP, data, len);}/**************************************************************************NFS_READ - Read File on NFS Server**************************************************************************/static voidnfs_read_req (int offset, int readlen){	u32 data[1024];	u32 *p;	int len;	p = &(data[0]);	p = (u32 *)rpc_add_credentials ((long *)p);	memcpy (p, filefh, NFS_FHSIZE);	p += (NFS_FHSIZE / 4);	*p++ = htonl(offset);	*p++ = htonl(readlen);	*p++ = 0;	len = (u32 *)p - (u32 *)&(data[0]);	rpc_req (PROG_NFS, NFS_READ, data, len);}/**************************************************************************RPC request dispatcher**************************************************************************/static voidNfsSend (void){#ifdef NFS_DEBUG	printk ("%s\n", __FUNCTION__);#endif	switch (NfsState) {	case STATE_PRCLOOKUP_PROG_MOUNT_REQ:		rpc_lookup_req (PROG_MOUNT, 1);		break;	case STATE_PRCLOOKUP_PROG_NFS_REQ:		rpc_lookup_req (PROG_NFS, 2);		break;	case STATE_MOUNT_REQ:		nfs_mount_req (nfs_path);		break;	case STATE_UMOUNT_REQ:		nfs_umountall_req ();		break;	case STATE_LOOKUP_REQ:		nfs_lookup_req (nfs_filename);		break;	case STATE_READ_REQ:		nfs_read_req (nfs_offset, nfs_len);		break;	case STATE_READLINK_REQ:		nfs_readlink_req ();		break;	}}/**************************************************************************Handlers for the reply from server**************************************************************************/static intrpc_lookup_reply (int prog, uchar *pkt, unsigned len){	struct rpc_t rpc_pkt;	memcpy ((unsigned char *)&rpc_pkt, pkt, len);#ifdef NFS_DEBUG	printk ("%s\n", __FUNCTION__);#endif

⌨️ 快捷键说明

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