~hamo/ubuntu/precise/grub2/grub2.hi_res

« back to all changes in this revision

Viewing changes to fs/i386/pc/pxe.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson, Colin Watson, Robert Millan, Updated translations
  • Date: 2010-11-22 12:24:56 UTC
  • mfrom: (1.26.4 upstream) (17.3.36 sid)
  • mto: (17.3.43 sid)
  • mto: This revision was merged to the branch mainline in revision 89.
  • Revision ID: james.westby@ubuntu.com-20101122122456-y82z3sfb7k4zfdcc
Tags: 1.99~20101122-1
[ Colin Watson ]
* New Bazaar snapshot.  Too many changes to list in full, but some of the
  more user-visible ones are as follows:
  - GRUB script:
    + Function parameters, "break", "continue", "shift", "setparams",
      "return", and "!".
    + "export" command supports multiple variable names.
    + Multi-line quoted strings support.
    + Wildcard expansion.
  - sendkey support.
  - USB hotunplugging and USB serial support.
  - Rename CD-ROM to cd on BIOS.
  - Add new --boot-directory option to grub-install, grub-reboot, and
    grub-set-default; the old --root-directory option is still accepted
    but was often confusing.
  - Basic btrfs detection/UUID support (but no file reading yet).
  - bash-completion for utilities.
  - If a device is listed in device.map, always assume that it is
    BIOS-visible rather than using extra layers such as LVM or RAID.
  - Add grub-mknetdir script (closes: #550658).
  - Remove deprecated "root" command.
  - Handle RAID devices containing virtio components.
  - GRUB Legacy configuration file support (via grub-menulst2cfg).
  - Keyboard layout support (via grub-mklayout and grub-kbdcomp).
  - Check generated grub.cfg for syntax errors before saving.
  - Pause execution for at most ten seconds if any errors are displayed,
    so that the user has a chance to see them.
  - Support submenus.
  - Write embedding zone using Reed-Solomon, so that it's robust against
    being partially overwritten (closes: #550702, #591416, #593347).
  - GRUB_DISABLE_LINUX_RECOVERY and GRUB_DISABLE_NETBSD_RECOVERY merged
    into a single GRUB_DISABLE_RECOVERY variable.
  - Fix loader memory allocation failure (closes: #551627).
  - Don't call savedefault on recovery entries (closes: #589325).
  - Support triple-indirect blocks on ext2 (closes: #543924).
  - Recognise DDF1 fake RAID (closes: #603354).

[ Robert Millan ]
* Use dpkg architecture wildcards.

[ Updated translations ]
* Slovenian (Vanja Cvelbar).  Closes: #604003
* Dzongkha (dawa pemo via Tenzin Dendup).  Closes: #604102

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* pxe.c - Driver to provide access to the pxe filesystem  */
2
 
/*
3
 
 *  GRUB  --  GRand Unified Bootloader
4
 
 *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
5
 
 *
6
 
 *  GRUB is free software: you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation, either version 3 of the License, or
9
 
 *  (at your option) any later version.
10
 
 *
11
 
 *  GRUB is distributed in the hope that it will be useful,
12
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 *  GNU General Public License for more details.
15
 
 *
16
 
 *  You should have received a copy of the GNU General Public License
17
 
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
18
 
 */
19
 
 
20
 
#include <grub/dl.h>
21
 
#include <grub/fs.h>
22
 
#include <grub/mm.h>
23
 
#include <grub/disk.h>
24
 
#include <grub/file.h>
25
 
#include <grub/misc.h>
26
 
#include <grub/bufio.h>
27
 
#include <grub/env.h>
28
 
 
29
 
#include <grub/machine/pxe.h>
30
 
#include <grub/machine/memory.h>
31
 
 
32
 
#define SEGMENT(x)      ((x) >> 4)
33
 
#define OFFSET(x)       ((x) & 0xF)
34
 
#define SEGOFS(x)       ((SEGMENT(x) << 16) + OFFSET(x))
35
 
#define LINEAR(x)       (void *) (((x >> 16) <<4) + (x & 0xFFFF))
36
 
 
37
 
struct grub_pxe_disk_data
38
 
{
39
 
  grub_uint32_t server_ip;
40
 
  grub_uint32_t gateway_ip;
41
 
};
42
 
 
43
 
struct grub_pxenv *grub_pxe_pxenv;
44
 
static grub_uint32_t grub_pxe_your_ip;
45
 
static grub_uint32_t grub_pxe_default_server_ip;
46
 
static grub_uint32_t grub_pxe_default_gateway_ip;
47
 
static unsigned grub_pxe_blksize = GRUB_PXE_MIN_BLKSIZE;
48
 
 
49
 
static grub_file_t curr_file = 0;
50
 
 
51
 
struct grub_pxe_data
52
 
{
53
 
  grub_uint32_t packet_number;
54
 
  grub_uint32_t block_size;
55
 
  char filename[0];
56
 
};
57
 
 
58
 
static int
59
 
grub_pxe_iterate (int (*hook) (const char *name))
60
 
{
61
 
  if (hook ("pxe"))
62
 
    return 1;
63
 
  return 0;
64
 
}
65
 
 
66
 
static grub_err_t
67
 
parse_ip (const char *val, grub_uint32_t *ip, const char **rest)
68
 
{
69
 
  grub_uint32_t newip = 0;
70
 
  unsigned long t;
71
 
  int i;
72
 
  const char *ptr = val;
73
 
 
74
 
  for (i = 0; i < 4; i++)
75
 
    {
76
 
      t = grub_strtoul (ptr, (char **) &ptr, 0);
77
 
      if (grub_errno)
78
 
        return grub_errno;
79
 
      if (t & ~0xff)
80
 
        return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP.");
81
 
      newip >>= 8;
82
 
      newip |= (t << 24);
83
 
      if (i != 3 && *ptr != '.')
84
 
        return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP.");
85
 
      ptr++;
86
 
    }
87
 
  *ip = newip;
88
 
  if (rest)
89
 
    *rest = ptr - 1;
90
 
  return 0;
91
 
}
92
 
 
93
 
static grub_err_t
94
 
grub_pxe_open (const char *name, grub_disk_t disk)
95
 
{
96
 
  struct grub_pxe_disk_data *data;
97
 
 
98
 
  if (grub_strcmp (name, "pxe") != 0
99
 
      && grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) != 0)
100
 
    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a pxe disk");
101
 
 
102
 
  data = grub_malloc (sizeof (*data));
103
 
  if (!data)
104
 
    return grub_errno;
105
 
 
106
 
  if (grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) == 0)
107
 
    {
108
 
      const char *ptr;
109
 
      grub_err_t err;
110
 
 
111
 
      ptr = name + sizeof ("pxe:") - 1;
112
 
      err = parse_ip (ptr, &(data->server_ip), &ptr);
113
 
      if (err)
114
 
        return err;
115
 
      if (*ptr == ':')
116
 
        {
117
 
          err = parse_ip (ptr + 1, &(data->server_ip), 0);
118
 
          if (err)
119
 
            return err;
120
 
        }
121
 
      else
122
 
        data->gateway_ip = grub_pxe_default_gateway_ip;
123
 
    }
124
 
  else
125
 
    {
126
 
      data->server_ip = grub_pxe_default_server_ip;
127
 
      data->gateway_ip = grub_pxe_default_gateway_ip;
128
 
    }
129
 
 
130
 
  disk->total_sectors = 0;
131
 
  disk->id = (unsigned long) data;
132
 
 
133
 
  disk->has_partitions = 0;
134
 
  disk->data = data;
135
 
 
136
 
  return GRUB_ERR_NONE;
137
 
}
138
 
 
139
 
static void
140
 
grub_pxe_close (grub_disk_t disk)
141
 
{
142
 
  grub_free (disk->data);
143
 
}
144
 
 
145
 
static grub_err_t
146
 
grub_pxe_read (grub_disk_t disk __attribute((unused)),
147
 
               grub_disk_addr_t sector __attribute((unused)),
148
 
               grub_size_t size __attribute((unused)),
149
 
               char *buf __attribute((unused)))
150
 
{
151
 
  return GRUB_ERR_OUT_OF_RANGE;
152
 
}
153
 
 
154
 
static grub_err_t
155
 
grub_pxe_write (grub_disk_t disk __attribute((unused)),
156
 
                grub_disk_addr_t sector __attribute((unused)),
157
 
                grub_size_t size __attribute((unused)),
158
 
                const char *buf __attribute((unused)))
159
 
{
160
 
  return GRUB_ERR_OUT_OF_RANGE;
161
 
}
162
 
 
163
 
static struct grub_disk_dev grub_pxe_dev =
164
 
  {
165
 
    .name = "pxe",
166
 
    .id = GRUB_DISK_DEVICE_PXE_ID,
167
 
    .iterate = grub_pxe_iterate,
168
 
    .open = grub_pxe_open,
169
 
    .close = grub_pxe_close,
170
 
    .read = grub_pxe_read,
171
 
    .write = grub_pxe_write,
172
 
    .next = 0
173
 
  };
174
 
 
175
 
static grub_err_t
176
 
grub_pxefs_dir (grub_device_t device __attribute__ ((unused)),
177
 
                const char *path  __attribute__ ((unused)),
178
 
                int (*hook) (const char *filename,
179
 
                             const struct grub_dirhook_info *info)
180
 
                __attribute__ ((unused)))
181
 
{
182
 
  return GRUB_ERR_NONE;
183
 
}
184
 
 
185
 
static grub_err_t
186
 
grub_pxefs_open (struct grub_file *file, const char *name)
187
 
{
188
 
  union
189
 
    {
190
 
      struct grub_pxenv_tftp_get_fsize c1;
191
 
      struct grub_pxenv_tftp_open c2;
192
 
    } c;
193
 
  struct grub_pxe_data *data;
194
 
  struct grub_pxe_disk_data *disk_data = file->device->disk->data;
195
 
  grub_file_t file_int, bufio;
196
 
 
197
 
  if (curr_file != 0)
198
 
    {
199
 
      grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c.c2);
200
 
      curr_file = 0;
201
 
    }
202
 
 
203
 
  c.c1.server_ip = disk_data->server_ip;
204
 
  c.c1.gateway_ip = disk_data->gateway_ip;
205
 
  grub_strcpy ((char *)&c.c1.filename[0], name);
206
 
  grub_pxe_call (GRUB_PXENV_TFTP_GET_FSIZE, &c.c1);
207
 
  if (c.c1.status)
208
 
    return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
209
 
 
210
 
  file->size = c.c1.file_size;
211
 
 
212
 
  c.c2.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
213
 
  c.c2.packet_size = grub_pxe_blksize;
214
 
  grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &c.c2);
215
 
  if (c.c2.status)
216
 
    return grub_error (GRUB_ERR_BAD_FS, "open fails");
217
 
 
218
 
  data = grub_zalloc (sizeof (struct grub_pxe_data) + grub_strlen (name) + 1);
219
 
  if (! data)
220
 
    return grub_errno;
221
 
 
222
 
  data->block_size = c.c2.packet_size;
223
 
  grub_strcpy (data->filename, name);
224
 
 
225
 
  file_int = grub_malloc (sizeof (*file_int));
226
 
  if (! file_int)
227
 
    {
228
 
      grub_free (data);
229
 
      return grub_errno;
230
 
    }
231
 
 
232
 
  file->data = data;
233
 
  grub_memcpy (file_int, file, sizeof (struct grub_file));
234
 
  curr_file = file_int;
235
 
 
236
 
  bufio = grub_bufio_open (file_int, data->block_size);
237
 
  if (! bufio)
238
 
    {
239
 
      grub_free (file_int);
240
 
      grub_free (data);
241
 
      return grub_errno;
242
 
    }
243
 
 
244
 
  grub_memcpy (file, bufio, sizeof (struct grub_file));
245
 
 
246
 
  return GRUB_ERR_NONE;
247
 
}
248
 
 
249
 
static grub_ssize_t
250
 
grub_pxefs_read (grub_file_t file, char *buf, grub_size_t len)
251
 
{
252
 
  struct grub_pxenv_tftp_read c;
253
 
  struct grub_pxe_data *data;
254
 
  struct grub_pxe_disk_data *disk_data = file->device->disk->data;
255
 
  grub_uint32_t pn, r;
256
 
 
257
 
  data = file->data;
258
 
 
259
 
  pn = grub_divmod64 (file->offset, data->block_size, &r);
260
 
  if (r)
261
 
    {
262
 
      grub_error (GRUB_ERR_BAD_FS,
263
 
                  "read access must be aligned to packet size");
264
 
      return -1;
265
 
    }
266
 
 
267
 
  if ((curr_file != file) || (data->packet_number > pn))
268
 
    {
269
 
      struct grub_pxenv_tftp_open o;
270
 
 
271
 
      if (curr_file != 0)
272
 
        grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &o);
273
 
 
274
 
      o.server_ip = disk_data->server_ip;
275
 
      o.gateway_ip = disk_data->gateway_ip;
276
 
      grub_strcpy ((char *)&o.filename[0], data->filename);
277
 
      o.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
278
 
      o.packet_size = grub_pxe_blksize;
279
 
      grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &o);
280
 
      if (o.status)
281
 
        {
282
 
          grub_error (GRUB_ERR_BAD_FS, "open fails");
283
 
          return -1;
284
 
        }
285
 
      data->block_size = o.packet_size;
286
 
      data->packet_number = 0;
287
 
      curr_file = file;
288
 
    }
289
 
 
290
 
  c.buffer = SEGOFS (GRUB_MEMORY_MACHINE_SCRATCH_ADDR);
291
 
  while (pn >= data->packet_number)
292
 
    {
293
 
      c.buffer_size = data->block_size;
294
 
      grub_pxe_call (GRUB_PXENV_TFTP_READ, &c);
295
 
      if (c.status)
296
 
        {
297
 
          grub_error (GRUB_ERR_BAD_FS, "read fails");
298
 
          return -1;
299
 
        }
300
 
      data->packet_number++;
301
 
    }
302
 
 
303
 
  grub_memcpy (buf, (char *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, len);
304
 
 
305
 
  return len;
306
 
}
307
 
 
308
 
static grub_err_t
309
 
grub_pxefs_close (grub_file_t file)
310
 
{
311
 
  struct grub_pxenv_tftp_close c;
312
 
 
313
 
  if (curr_file == file)
314
 
    {
315
 
      grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c);
316
 
      curr_file = 0;
317
 
    }
318
 
 
319
 
  grub_free (file->data);
320
 
 
321
 
  return GRUB_ERR_NONE;
322
 
}
323
 
 
324
 
static grub_err_t
325
 
grub_pxefs_label (grub_device_t device __attribute ((unused)),
326
 
                   char **label __attribute ((unused)))
327
 
{
328
 
  *label = 0;
329
 
  return GRUB_ERR_NONE;
330
 
}
331
 
 
332
 
static struct grub_fs grub_pxefs_fs =
333
 
  {
334
 
    .name = "pxefs",
335
 
    .dir = grub_pxefs_dir,
336
 
    .open = grub_pxefs_open,
337
 
    .read = grub_pxefs_read,
338
 
    .close = grub_pxefs_close,
339
 
    .label = grub_pxefs_label,
340
 
    .next = 0
341
 
  };
342
 
 
343
 
static char *
344
 
grub_env_write_readonly (struct grub_env_var *var __attribute__ ((unused)),
345
 
                         const char *val __attribute__ ((unused)))
346
 
{
347
 
  return NULL;
348
 
}
349
 
 
350
 
static void
351
 
set_mac_env (grub_uint8_t *mac_addr, grub_size_t mac_len)
352
 
{
353
 
  char buf[(sizeof ("XX:") - 1) * mac_len + 1];
354
 
  char *ptr = buf;
355
 
  unsigned i;
356
 
 
357
 
  for (i = 0; i < mac_len; i++)
358
 
    {
359
 
      grub_snprintf (ptr, sizeof (buf) - (ptr - buf),
360
 
                     "%02x:", mac_addr[i] & 0xff);
361
 
      ptr += (sizeof ("XX:") - 1);
362
 
    }
363
 
  if (mac_len)
364
 
    *(ptr - 1) = 0;
365
 
  else
366
 
    buf[0] = 0;
367
 
 
368
 
  grub_env_set ("net_pxe_mac", buf);
369
 
  /* XXX: Is it possible to change MAC in PXE?  */
370
 
  grub_register_variable_hook ("net_pxe_mac", 0, grub_env_write_readonly);
371
 
}
372
 
 
373
 
static void
374
 
set_env_limn_ro (const char *varname, char *value, grub_size_t len)
375
 
{
376
 
  char c;
377
 
  c = value[len];
378
 
  value[len] = 0;
379
 
  grub_env_set (varname, value);
380
 
  value[len] = c;
381
 
  grub_register_variable_hook (varname, 0, grub_env_write_readonly);
382
 
}
383
 
 
384
 
static void
385
 
parse_dhcp_vendor (void *vend, int limit)
386
 
{
387
 
  grub_uint8_t *ptr, *ptr0;
388
 
 
389
 
  ptr = ptr0 = vend;
390
 
 
391
 
  if (grub_be_to_cpu32 (*(grub_uint32_t *) ptr) != 0x63825363)
392
 
    return;
393
 
  ptr = ptr + sizeof (grub_uint32_t);
394
 
  while (ptr - ptr0 < limit)
395
 
    {
396
 
      grub_uint8_t tagtype;
397
 
      grub_uint8_t taglength;
398
 
 
399
 
      tagtype = *ptr++;
400
 
 
401
 
      /* Pad tag.  */
402
 
      if (tagtype == 0)
403
 
        continue;
404
 
 
405
 
      /* End tag.  */
406
 
      if (tagtype == 0xff)
407
 
        return;
408
 
 
409
 
      taglength = *ptr++;
410
 
 
411
 
      switch (tagtype)
412
 
        {
413
 
        case 12:
414
 
          set_env_limn_ro ("net_pxe_hostname", (char *) ptr, taglength);
415
 
          break;
416
 
 
417
 
        case 15:
418
 
          set_env_limn_ro ("net_pxe_domain", (char *) ptr, taglength);
419
 
          break;
420
 
 
421
 
        case 17:
422
 
          set_env_limn_ro ("net_pxe_rootpath", (char *) ptr, taglength);
423
 
          break;
424
 
 
425
 
        case 18:
426
 
          set_env_limn_ro ("net_pxe_extensionspath", (char *) ptr, taglength);
427
 
          break;
428
 
 
429
 
          /* If you need any other options please contact GRUB
430
 
             developpement team.  */
431
 
        }
432
 
 
433
 
      ptr += taglength;
434
 
    }
435
 
}
436
 
 
437
 
static void
438
 
grub_pxe_detect (void)
439
 
{
440
 
  struct grub_pxenv *pxenv;
441
 
  struct grub_pxenv_get_cached_info ci;
442
 
  struct grub_pxenv_boot_player *bp;
443
 
 
444
 
  pxenv = grub_pxe_scan ();
445
 
  if (! pxenv)
446
 
    return;
447
 
 
448
 
  ci.packet_type = GRUB_PXENV_PACKET_TYPE_DHCP_ACK;
449
 
  ci.buffer = 0;
450
 
  ci.buffer_size = 0;
451
 
  grub_pxe_call (GRUB_PXENV_GET_CACHED_INFO, &ci);
452
 
  if (ci.status)
453
 
    return;
454
 
 
455
 
  bp = LINEAR (ci.buffer);
456
 
 
457
 
  grub_pxe_your_ip = bp->your_ip;
458
 
  grub_pxe_default_server_ip = bp->server_ip;
459
 
  grub_pxe_default_gateway_ip = bp->gateway_ip;
460
 
  set_mac_env (bp->mac_addr, bp->hw_len < sizeof (bp->mac_addr) ? bp->hw_len
461
 
               : sizeof (bp->mac_addr));
462
 
  set_env_limn_ro ("net_pxe_boot_file", (char *) bp->boot_file,
463
 
                   sizeof (bp->boot_file));
464
 
  set_env_limn_ro ("net_pxe_dhcp_server_name", (char *) bp->server_name,
465
 
                   sizeof (bp->server_name));
466
 
  parse_dhcp_vendor (&bp->vendor, sizeof (bp->vendor));
467
 
  grub_pxe_pxenv = pxenv;
468
 
}
469
 
 
470
 
void
471
 
grub_pxe_unload (void)
472
 
{
473
 
  if (grub_pxe_pxenv)
474
 
    {
475
 
      grub_fs_unregister (&grub_pxefs_fs);
476
 
      grub_disk_dev_unregister (&grub_pxe_dev);
477
 
 
478
 
      grub_pxe_pxenv = 0;
479
 
    }
480
 
}
481
 
 
482
 
static void
483
 
set_ip_env (char *varname, grub_uint32_t ip)
484
 
{
485
 
  char buf[sizeof ("XXX.XXX.XXX.XXX")];
486
 
 
487
 
  grub_snprintf (buf, sizeof (buf), "%d.%d.%d.%d", (ip & 0xff),
488
 
                 (ip >> 8) & 0xff, (ip >> 16) & 0xff, (ip >> 24) & 0xff);
489
 
  grub_env_set (varname, buf);
490
 
}
491
 
 
492
 
static char *
493
 
write_ip_env (grub_uint32_t *ip, const char *val)
494
 
{
495
 
  char *buf;
496
 
  grub_err_t err;
497
 
  grub_uint32_t newip;
498
 
  
499
 
  err = parse_ip (val, &newip, 0);
500
 
  if (err)
501
 
    return 0;
502
 
 
503
 
  /* Normalize the IP.  */
504
 
  buf = grub_xasprintf ("%d.%d.%d.%d", (newip & 0xff), (newip >> 8) & 0xff,
505
 
                       (newip >> 16) & 0xff, (newip >> 24) & 0xff);
506
 
  if (!buf)
507
 
    return 0;
508
 
 
509
 
  *ip = newip;
510
 
 
511
 
  return buf; 
512
 
}
513
 
 
514
 
static char *
515
 
grub_env_write_pxe_default_server (struct grub_env_var *var 
516
 
                                   __attribute__ ((unused)),
517
 
                                   const char *val)
518
 
{
519
 
  return write_ip_env (&grub_pxe_default_server_ip, val);
520
 
}
521
 
 
522
 
static char *
523
 
grub_env_write_pxe_default_gateway (struct grub_env_var *var
524
 
                                    __attribute__ ((unused)),
525
 
                                    const char *val)
526
 
{
527
 
  return write_ip_env (&grub_pxe_default_gateway_ip, val);
528
 
}
529
 
 
530
 
static char *
531
 
grub_env_write_pxe_blocksize (struct grub_env_var *var __attribute__ ((unused)),
532
 
                              const char *val)
533
 
{
534
 
  unsigned size;
535
 
  char *buf;
536
 
 
537
 
  size = grub_strtoul (val, 0, 0);
538
 
  if (grub_errno)
539
 
    return 0;
540
 
 
541
 
  if (size < GRUB_PXE_MIN_BLKSIZE)
542
 
    size = GRUB_PXE_MIN_BLKSIZE;
543
 
  else if (size > GRUB_PXE_MAX_BLKSIZE)
544
 
    size = GRUB_PXE_MAX_BLKSIZE;
545
 
  
546
 
  buf = grub_xasprintf ("%d", size);
547
 
  if (!buf)
548
 
    return 0;
549
 
 
550
 
  grub_pxe_blksize = size;
551
 
  
552
 
  return buf;
553
 
}
554
 
 
555
 
 
556
 
GRUB_MOD_INIT(pxe)
557
 
{
558
 
  grub_pxe_detect ();
559
 
  if (grub_pxe_pxenv)
560
 
    {
561
 
      char *buf;
562
 
 
563
 
      buf = grub_xasprintf ("%d", grub_pxe_blksize);
564
 
      if (buf)
565
 
        grub_env_set ("net_pxe_blksize", buf);
566
 
      grub_free (buf);
567
 
 
568
 
      set_ip_env ("pxe_default_server", grub_pxe_default_server_ip);
569
 
      set_ip_env ("pxe_default_gateway", grub_pxe_default_gateway_ip);
570
 
      set_ip_env ("net_pxe_ip", grub_pxe_your_ip);
571
 
      grub_register_variable_hook ("net_pxe_default_server", 0,
572
 
                                   grub_env_write_pxe_default_server);
573
 
      grub_register_variable_hook ("net_pxe_default_gateway", 0,
574
 
                                   grub_env_write_pxe_default_gateway);
575
 
 
576
 
      /* XXX: Is it possible to change IP in PXE?  */
577
 
      grub_register_variable_hook ("net_pxe_ip", 0,
578
 
                                   grub_env_write_readonly);
579
 
      grub_register_variable_hook ("net_pxe_blksize", 0,
580
 
                                   grub_env_write_pxe_blocksize);
581
 
      grub_disk_dev_register (&grub_pxe_dev);
582
 
      grub_fs_register (&grub_pxefs_fs);
583
 
    }
584
 
}
585
 
 
586
 
GRUB_MOD_FINI(pxe)
587
 
{
588
 
  grub_pxe_unload ();
589
 
}