2 * Copyright (C) 2001-2003 Hewlett-Packard Co.
3 * Contributed by Stephane Eranian <eranian@hpl.hp.com>
5 * This file is part of the ELILO, the EFI Linux boot loader.
7 * ELILO is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * ELILO is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with ELILO; see the file COPYING. If not, write to the Free
19 * Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 * Please check out the elilo.txt for complete documentation on how
23 * to use this program.
28 #include "glue_netfs.h"
36 * disable this if you only want the default config file (elilo.conf)
37 * and not the ip-address based first file attempt
40 static INTN glue(fileops_t *this, VOID *intf);
42 /* object exported to fileops */
43 fileops_fs_t netfs_glue = { NETFS_PROTOCOL , glue, netfs_install, netfs_uninstall};
46 #define NETFS_DEFAULT_KERNEL L"vmlinux"
47 #define NETFS_DEFAULT_CONFIG L"elilo.conf"
48 #define NETFS_DEFAULT_SERVER_TYPE EFI_PXE_BASE_CODE_BOOT_TYPE_REDHAT_BOOT
51 static CHAR16 netfs_default_path[FILENAME_MAXLEN];
55 * Pxe Discovery protocol layers
56 * Layer 0 is used to download the boot loader
58 #define NETFS_CONFIG_LAYER 1
59 #define NETFS_KERNEL_LAYER 2
61 static CHAR16 *hexa=L"0123456789ABCDEF";
64 convert_ip2hex(UINT8 *ip, INTN l, CHAR16 *str)
68 for(i=0; i < l; i++) {
69 str[2*i] = hexa[(ip[i] & 0xf0)>>4];
70 str[2*i+1] = hexa[ip[i] & 0x0f];
75 convert_ip2decstr(UINT8 *ip, INTN l, CHAR16 *str)
80 for(i=0, j=0; i < l; i++) {
88 if (v || ip[i] >= 100) {
94 if (i < l-1) str[j++] = L'.';
100 netfs_set_default_path(netfs_interface_t *netfs, netfs_info_t *info)
104 StrnCpy(netfs_default_path, info->bootfile, FILENAME_MAXLEN);
106 len = StrLen(netfs_default_path) - 1;
109 if (netfs_default_path[len] == CHAR_SLASH || netfs_default_path[len] == CHAR_BACKSLASH) break;
112 netfs_default_path[len+1] = CHAR_NULL;
114 DBG_PRT((L"netfs_default_path=%s\n", netfs_default_path));
120 netfs_setdefaults(VOID *intf, CHAR16 *config, CHAR16 *kname, UINTN maxlen, CHAR16 *devpath)
122 netfs_interface_t *netfs = (netfs_interface_t *)intf;
127 CHAR16 ip_var[64], str[64];
130 if (config == NULL || kname == NULL || maxlen < 1) return EFI_INVALID_PARAMETER;
132 netfs->netfs_getinfo(netfs, &info);
134 m = info.using_ipv6 ? 16 : 4;
135 ipaddr = info.using_ipv6 ? info.cln_ipaddr.v6.Addr: info.cln_ipaddr.v4.Addr;
137 convert_ip2decstr(ipaddr, m, ip_var);
138 set_var(VAR_NETFS_IPADDR, ip_var);
140 ip = info.using_ipv6 ? info.netmask.v6.Addr: info.netmask.v4.Addr;
141 convert_ip2decstr(ip, m, str);
142 set_var(VAR_NETFS_NETMASK, str);
144 ip = info.using_ipv6 ? info.gw_ipaddr.v6.Addr: info.gw_ipaddr.v4.Addr;
145 convert_ip2decstr(ip, m, str);
146 set_var(VAR_NETFS_GATEWAY, str);
148 set_var(VAR_NETFS_HOSTNAME, info.hostname);
149 set_var(VAR_NETFS_DOMAINAME, info.domainame);
151 if (info.using_pxe) {
152 status = netfs->netfs_query_layer(netfs, 0, NETFS_CONFIG_LAYER, maxlen, config);
153 if (EFI_ERROR(status)) {
154 StrnCpy(config, NETFS_DEFAULT_CONFIG, maxlen-1);
155 config[maxlen-1] = CHAR_NULL;
158 status = netfs->netfs_query_layer(netfs, 0, NETFS_KERNEL_LAYER, maxlen, kname);
159 if (EFI_ERROR(status)) {
160 StrnCpy(kname, NETFS_DEFAULT_KERNEL, maxlen-1);
161 kname[maxlen-1] = CHAR_NULL;
164 #ifdef ENABLE_MACHINE_SPECIFIC_NETCONFIG
166 * will try a machine specific file first.
167 * the file is constructed based on the IP(v4) address
169 convert_ip2hex(ipaddr, m, config);
176 config[13] = CHAR_NULL;
178 StrnCpy(config, NETFS_DEFAULT_CONFIG, maxlen-1);
179 config[maxlen-1] = CHAR_NULL;
181 StrnCpy(kname, NETFS_DEFAULT_KERNEL, maxlen-1);
182 kname[maxlen-1] = CHAR_NULL;
185 * extract bootloader path prefix to be used for
186 * the config file (and possibly the other files we
189 netfs_set_default_path(netfs, &info);
195 netfs_getdefault_path(CHAR16 *path, UINTN maxlen)
197 if (maxlen <= StrLen(netfs_default_path)) return EFI_BUFFER_TOO_SMALL;
199 StrCpy(path, netfs_default_path);
205 glue_open(VOID *intf, CHAR16 *name, fops_fd_t *fd)
207 netfs_interface_t *netfs = (netfs_interface_t *)intf;
208 CHAR16 fullname[FILENAME_MAXLEN];
210 if (name[0] != CHAR_SLASH && name[0] != CHAR_BACKSLASH && netfs_default_path[0] != CHAR_NULL) {
211 if (StrLen(netfs_default_path) + StrLen(name) + 1 >= FILENAME_MAXLEN)
212 return EFI_INVALID_PARAMETER;
214 StrCpy(fullname, netfs_default_path);
215 StrCat(fullname, name);
218 return netfs->netfs_open(intf, name, fd);
222 glue(fileops_t *fp, VOID *intf)
224 netfs_interface_t *netfs = (netfs_interface_t *)intf;
226 /* record underlying interface */
229 fp->open = glue_open;
230 fp->read = (fops_read_t)netfs->netfs_read;
231 fp->close = (fops_close_t)netfs->netfs_close;
232 fp->infosize = (fops_infosize_t)netfs->netfs_infosize;
233 fp->seek = (fops_seek_t)netfs->netfs_seek;
234 fp->setdefaults = (fops_setdefaults_t)netfs_setdefaults;
235 fp->getdefault_path = (fops_getdefault_path_t)netfs_getdefault_path;
238 /* fill out the name of the underlying file system */
239 netfs->netfs_name(netfs, fp->name, FILEOPS_NAME_MAXLEN);