glue_netfs.c

来自「EFI(Extensible Firmware Interface)是下一代BI」· C语言 代码 · 共 266 行

C
266
字号
/* *  Copyright (C) 2001-2003 Hewlett-Packard Co. *	Contributed by Stephane Eranian <eranian@hpl.hp.com> * * This file is part of the ELILO, the EFI Linux boot loader. * *  ELILO is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. * *  ELILO is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with ELILO; see the file COPYING.  If not, write to the Free *  Software Foundation, 59 Temple Place - Suite 330, Boston, MA *  02111-1307, USA. * * Please check out the elilo.txt for complete documentation on how * to use this program. */#include <efi.h>#include <efilib.h>#include "glue_netfs.h"#include "fs/netfs.h"#include "strops.h"#include "elilo.h"#include "vars.h"/* * disable this if you only want the default config file (elilo.conf) * and not the ip-address based first file attempt */static INTN glue(fileops_t *this, VOID *intf);/* object exported to fileops */fileops_fs_t netfs_glue = { NETFS_PROTOCOL  , glue, netfs_install, netfs_uninstall};	#define NETFS_DEFAULT_KERNEL		L"vmlinux"#define NETFS_DEFAULT_CONFIG		L"elilo.conf"#define NETFS_DEFAULT_SERVER_TYPE	EFI_PXE_BASE_CODE_BOOT_TYPE_REDHAT_BOOTstatic CHAR16 netfs_default_path[FILENAME_MAXLEN];/* * Pxe Discovery protocol layers * Layer 0 is used to download the boot loader */#define NETFS_CONFIG_LAYER	1#define NETFS_KERNEL_LAYER	2static CHAR16 *hexa=L"0123456789ABCDEF";static VOIDconvert_ip2hex(UINT8 *ip, INTN l, CHAR16 *str){	UINTN i;	for(i=0; i < l; i++) {		str[2*i]   = hexa[(ip[i] & 0xf0)>>4];		str[2*i+1] = hexa[ip[i] & 0x0f];	}}static VOIDconvert_ip2decstr(UINT8 *ip, INTN l, CHAR16 *str){	UINTN i, j;	UINTN v, val;	for(i=0, j=0; i < l; i++) {		val = ip[i];		v = val / 100;		if (v) {			str[j++] = L'0'+v;		}		val = val % 100;		v = val / 10;		if (v || ip[i] >= 100) {			str[j++] = L'0'+v;		}		v = val % 10;		str[j++] = L'0'+v;		if (i < l-1) str[j++] = L'.';	}	str[j] = CHAR_NULL;}static intnetfs_set_default_path(netfs_interface_t *netfs, netfs_info_t *info){ 	INTN len; 	StrnCpy(netfs_default_path, info->bootfile, FILENAME_MAXLEN);	len = StrLen(netfs_default_path) - 1; 	while (len >= 0) { 		if (netfs_default_path[len] == CHAR_SLASH || netfs_default_path[len] == CHAR_BACKSLASH) break;		len--; 	} 	netfs_default_path[len+1] = CHAR_NULL; 	DBG_PRT((L"netfs_default_path=%s\n", netfs_default_path)); 	return EFI_SUCCESS;}static EFI_STATUSnetfs_setdefaults(VOID *intf, config_file_t *config, CHAR16 *kname, UINTN maxlen, CHAR16 *devpath){	netfs_interface_t *netfs = (netfs_interface_t *)intf;	netfs_info_t info;	EFI_STATUS status;	UINT8 *ipaddr;	UINTN m;	CHAR16 ip_var[64], str[64];	UINT8 *ip;	if (config == NULL || kname == NULL || maxlen < 1) return EFI_INVALID_PARAMETER;	netfs->netfs_getinfo(netfs, &info);	m      = info.using_ipv6 ? 16 : 4;	ipaddr = info.using_ipv6 ? info.cln_ipaddr.v6.Addr: info.cln_ipaddr.v4.Addr;	convert_ip2decstr(ipaddr, m, ip_var);	set_var(VAR_NETFS_IPADDR, ip_var);	ip = info.using_ipv6 ? info.netmask.v6.Addr: info.netmask.v4.Addr;	convert_ip2decstr(ip, m, str);	set_var(VAR_NETFS_NETMASK, str);	ip = info.using_ipv6 ? info.gw_ipaddr.v6.Addr: info.gw_ipaddr.v4.Addr;	convert_ip2decstr(ip, m, str);	set_var(VAR_NETFS_GATEWAY, str);	set_var(VAR_NETFS_HOSTNAME, info.hostname);	set_var(VAR_NETFS_DOMAINAME, info.domainame);	if (info.using_pxe) {		status = netfs->netfs_query_layer(netfs, 0, NETFS_CONFIG_LAYER, maxlen, config[0].fname);		if (EFI_ERROR(status)) {			StrnCpy(config[0].fname, NETFS_DEFAULT_CONFIG, maxlen-1);			config[0].fname[maxlen-1] = CHAR_NULL;		}		status = netfs->netfs_query_layer(netfs, 0, NETFS_KERNEL_LAYER, maxlen, kname);		if (EFI_ERROR(status)) {			StrnCpy(kname, NETFS_DEFAULT_KERNEL, maxlen-1);			kname[maxlen-1] = CHAR_NULL;		}	} else {#ifdef ENABLE_MACHINE_SPECIFIC_NETCONFIG#  if defined(CONFIG_ia64)#    define CONFIG_ARCH_EXTENSION L"-ia64.conf\0"#  elif defined (CONFIG_ia32)#    define CONFIG_ARCH_EXTENSION L"-ia64.conf\0"#  else#    error "You need to specfy your default arch config file"#  endif            #  define CONFIG_EXTENSION L".conf\0"		/*		 * will try machine/subnet specific files first.		 * the filenames are constructed based on the IP(v4) address		 */		convert_ip2hex(ipaddr, m, str);		StrnCpy(config[0].fname, str, maxlen-1);		StrnCpy(config[0].fname+8, CONFIG_EXTENSION, 6);		StrnCpy(config[1].fname, str, maxlen-1);		StrnCpy(config[1].fname+6, CONFIG_ARCH_EXTENSION, 11);		StrnCpy(config[2].fname, str, maxlen-1);		StrnCpy(config[2].fname+6, CONFIG_EXTENSION, 6);		StrnCpy(config[3].fname, str, maxlen-1);		StrnCpy(config[3].fname+4, CONFIG_ARCH_EXTENSION, 11);		StrnCpy(config[4].fname, str, maxlen-1);		StrnCpy(config[4].fname+4, CONFIG_EXTENSION, 6);                		StrnCpy(config[5].fname, str, maxlen-1);		StrnCpy(config[5].fname+2, CONFIG_ARCH_EXTENSION, 11);		StrnCpy(config[6].fname, str, maxlen-1);		StrnCpy(config[6].fname+2, CONFIG_EXTENSION, 6);#else		StrnCpy(config[0].fname, NETFS_DEFAULT_CONFIG, maxlen-1);		config[0].fname[maxlen-1] = CHAR_NULL;#endif		StrnCpy(kname, NETFS_DEFAULT_KERNEL, maxlen-1);		kname[maxlen-1] = CHAR_NULL;		/*		 * extract bootloader path prefix to be used for 		 * the config file (and possibly the other files we 		 * need to download)		 */		netfs_set_default_path(netfs, &info);	}	return EFI_SUCCESS;}static EFI_STATUSnetfs_getdefault_path(CHAR16 *path, UINTN maxlen){	if (maxlen <= StrLen(netfs_default_path)) return EFI_BUFFER_TOO_SMALL;	StrCpy(path, netfs_default_path);	return EFI_SUCCESS;}static EFI_STATUS glue_open(VOID *intf, CHAR16 *name, fops_fd_t *fd){	netfs_interface_t *netfs = (netfs_interface_t *)intf;	CHAR16 fullname[FILENAME_MAXLEN];	if (name[0] != CHAR_SLASH && name[0] != CHAR_BACKSLASH && netfs_default_path[0] != CHAR_NULL) {		if (StrLen(netfs_default_path) + StrLen(name) + 1 >= FILENAME_MAXLEN)			return EFI_INVALID_PARAMETER;		StrCpy(fullname, netfs_default_path);		StrCat(fullname, name);		name = fullname;	}	return netfs->netfs_open(intf, name, fd);}static INTNglue(fileops_t *fp, VOID *intf){	netfs_interface_t *netfs = (netfs_interface_t *)intf;	/* record underlying interface */	fp->intf        = intf;	fp->open            = glue_open;	fp->read            = (fops_read_t)netfs->netfs_read;	fp->close           = (fops_close_t)netfs->netfs_close;	fp->infosize        = (fops_infosize_t)netfs->netfs_infosize;	fp->seek            = (fops_seek_t)netfs->netfs_seek;	fp->setdefaults     = (fops_setdefaults_t)netfs_setdefaults;	fp->getdefault_path = (fops_getdefault_path_t)netfs_getdefault_path;	fp->intf	    = intf;	/* fill out the name of the underlying file system */	netfs->netfs_name(netfs, fp->name, FILEOPS_NAME_MAXLEN);	return 0;}

⌨️ 快捷键说明

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