* [PATCH] PXE support for grub2
@ 2008-07-30 16:50 Bean
2008-08-01 3:46 ` Bean
` (2 more replies)
0 siblings, 3 replies; 15+ messages in thread
From: Bean @ 2008-07-30 16:50 UTC (permalink / raw)
To: The development of GRUB 2
[-- Attachment #1: Type: text/plain, Size: 1916 bytes --]
Hi,
This patch add the (pxe) device that can be used to load files using
the pxe service. It also add a user land command pxe that can be used
to show pxe information as well as set some parameter.
To create a pxe boot image:
./grub-mkimage -d . -o core.img pxe
cat pxeboot.img core.img > g2pxe
g2pxe is the pxe boot file, copy it to tftp server, you also need to
copy *.mod, fs.lst, command.lst, moddep.lst and grub.cfg to /boot/grub
directory in the tftp server.
To test it in qemu, copy the files to directory such as /tftp, then:
qemu -boot n -tftp /tftp -bootp /g2pxe
usage for pxe command:
pxe info
Show information about pxe, like block size, client ip, etc.
pxe blksize size
Set block size. tftp transfer in trunks of bytes, the size can be
configured. The minimum size is 512, which is also the default. The
maximum size is 1432. Normally, you can increase download speed by
setting larger block size, but some old tftp server may not support
it. Also, qemu doesn't support size other than 512.
pxe unload
Unload the pxe runtime environment.
Please note that this patch depends on my other patch bufio, you need
to apply that first.
2008-07-30 Bean <bean123ch@gmail.com>
* boot/i386/pc/pxeboot.S: Use drive number 0x7F for pxe.
* conf/i386-pc.rmk (kernel_img_HEADERS): Add machine/pxe.h.
(pkglib_MODULES): Add pxe.mod and pxecmd.mod.
(pxe_mod_SOURCES): New macro.
(pxe_mod_CFLAGS): Likewise.
(pxe_mod_LDFLAGS): Likewise.
(pxecmd_mod_SOURCES): Likewise.
(pxecmd_mod_CFLAGS): Likewise.
(pxecmd_mod_LDFLAGS): Likewise.
* kern/i386/pc/startup.S (grub_pxe_scan): New function.
(grub_pxe_call): Likewise.
* kern/i386/pc/init.c (make_install_device): Set root to (pxe) for pxe boot.
* include/grub/disk.h (grub_disk_dev_id): Add GRUB_DISK_DEVICE_PXE_ID.
* commands/i386/pc/pxecmd.c: New file.
* disk/i386/pc/pxe.c: Likewise.
* include/grub/i386/pc/pxe.h: Likewise.
--
Bean
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: pxe.diff --]
[-- Type: text/x-diff; name=pxe.diff, Size: 27909 bytes --]
diff --git a/boot/i386/pc/pxeboot.S b/boot/i386/pc/pxeboot.S
index 7f2a143..62a4fb2 100644
--- a/boot/i386/pc/pxeboot.S
+++ b/boot/i386/pc/pxeboot.S
@@ -26,7 +26,8 @@
.globl _start; _start:
/* Root drive will default to boot drive */
- movb $0xFF, %dh
+ movb $0xFF, %dh
+ movb $0x7F, %dl
/* Jump to the real world */
ljmp $0, $0x8200
diff --git a/commands/i386/pc/pxecmd.c b/commands/i386/pc/pxecmd.c
new file mode 100755
index 0000000..6bf3045
--- /dev/null
+++ b/commands/i386/pc/pxecmd.c
@@ -0,0 +1,92 @@
+/* pxe.c - command to control the pxe driver */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * GRUB 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/arg.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/machine/pxe.h>
+
+static void
+print_ip (grub_uint32_t ip)
+{
+ int i;
+
+ for (i = 0; i < 3; i++)
+ {
+ grub_printf ("%d.", ip & 0xFF);
+ ip >>= 8;
+ }
+ grub_printf ("%d", ip);
+}
+
+static grub_err_t
+grub_cmd_pxe (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc, char **args)
+{
+ if (! grub_pxe_pxenv)
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, "no pxe environment");
+
+ if ((argc == 0) || (! grub_strcmp (args[0], "info")))
+ {
+ grub_printf ("blksize : %d\n", grub_pxe_blksize);
+ grub_printf ("client ip : ");
+ print_ip (grub_pxe_your_ip);
+ grub_printf ("\nserver ip : ");
+ print_ip (grub_pxe_server_ip);
+ grub_printf ("\ngateway ip : ");
+ print_ip (grub_pxe_gateway_ip);
+ grub_printf ("\n");
+ }
+ else if (! grub_strcmp (args[0], "blksize"))
+ {
+ int size;
+
+ if (argc < 2)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "no blksize specified");
+
+ size = grub_strtoul (args[1], 0, 0);
+ if (size < GRUB_PXE_MIN_BLKSIZE)
+ size = GRUB_PXE_MIN_BLKSIZE;
+ else if (size > GRUB_PXE_MAX_BLKSIZE)
+ size = GRUB_PXE_MAX_BLKSIZE;
+
+ grub_pxe_blksize = size;
+ }
+ else if (! grub_strcmp (args[0], "unload"))
+ {
+ grub_pxe_unload ();
+ }
+
+ return 0;
+}
+
+GRUB_MOD_INIT(pxecmd)
+{
+ (void) mod; /* To stop warning. */
+ grub_register_command ("pxe", grub_cmd_pxe, GRUB_COMMAND_FLAG_BOTH,
+ "pxe info | blksize size | unload",
+ "Show information about PXE.", 0);
+}
+
+GRUB_MOD_FINI(pxecmd)
+{
+ grub_unregister_command ("pxe");
+}
diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk
index 8617a92..59fc6a3 100644
--- a/conf/i386-pc.rmk
+++ b/conf/i386-pc.rmk
@@ -50,7 +50,8 @@ kernel_img_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \
- machine/memory.h machine/loader.h machine/vga.h machine/vbe.h machine/kernel.h
+ machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \
+ machine/kernel.h machine/pxe.h
kernel_img_CFLAGS = $(COMMON_CFLAGS)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,$(GRUB_MEMORY_MACHINE_LINK_ADDR) $(COMMON_CFLAGS)
@@ -158,7 +159,7 @@ pkglib_MODULES = biosdisk.mod _chain.mod _linux.mod linux.mod normal.mod \
vbe.mod vbetest.mod vbeinfo.mod video.mod gfxterm.mod \
videotest.mod play.mod bitmap.mod tga.mod cpuid.mod serial.mod \
ata.mod vga.mod memdisk.mod jpeg.mod png.mod pci.mod lspci.mod \
- aout.mod _bsd.mod bsd.mod
+ aout.mod _bsd.mod bsd.mod pxe.mod pxecmd.mod
# For biosdisk.mod.
biosdisk_mod_SOURCES = disk/i386/pc/biosdisk.c
@@ -325,4 +326,14 @@ bsd_mod_SOURCES = loader/i386/bsd_normal.c
bsd_mod_CFLAGS = $(COMMON_CFLAGS)
bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+# For pxe.mod
+pxe_mod_SOURCES = disk/i386/pc/pxe.c
+pxe_mod_CFLAGS = $(COMMON_CFLAGS)
+pxe_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For pxecmd.mod
+pxecmd_mod_SOURCES = commands/i386/pc/pxecmd.c
+pxecmd_mod_CFLAGS = $(COMMON_CFLAGS)
+pxecmd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
include $(srcdir)/conf/common.mk
diff --git a/disk/i386/pc/pxe.c b/disk/i386/pc/pxe.c
new file mode 100644
index 0000000..ced1088
--- /dev/null
+++ b/disk/i386/pc/pxe.c
@@ -0,0 +1,335 @@
+/* pxe.c - Driver to provide access to the pxe filesystem */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * GRUB 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/fs.h>
+#include <grub/mm.h>
+#include <grub/disk.h>
+#include <grub/file.h>
+#include <grub/misc.h>
+#include <grub/bufio.h>
+
+#include <grub/machine/pxe.h>
+#include <grub/machine/memory.h>
+
+#define SEGMENT(x) ((x) >> 4)
+#define OFFSET(x) ((x) & 0xF)
+#define SEGOFS(x) ((SEGMENT(x) << 16) + OFFSET(x))
+#define LINEAR(x) (void *) (((x >> 16) <<4) + (x & 0xFFFF))
+
+struct grub_pxenv *grub_pxe_pxenv;
+grub_uint32_t grub_pxe_your_ip;
+grub_uint32_t grub_pxe_server_ip;
+grub_uint32_t grub_pxe_gateway_ip;
+int grub_pxe_blksize = GRUB_PXE_MIN_BLKSIZE;
+
+struct grub_pxe_data
+{
+ grub_uint32_t packet_number;
+ char filename[0];
+};
+
+static int
+grub_pxe_iterate (int (*hook) (const char *name))
+{
+ if (hook ("pxe"))
+ return 1;
+ return 0;
+}
+
+static grub_err_t
+grub_pxe_open (const char *name, grub_disk_t disk)
+{
+ if (grub_strcmp (name, "pxe"))
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a pxe disk");
+
+ disk->total_sectors = 0;
+ disk->id = (unsigned long) "pxe";
+
+ disk->has_partitions = 0;
+ disk->data = 0;
+
+ return GRUB_ERR_NONE;
+}
+
+static void
+grub_pxe_close (grub_disk_t disk __attribute((unused)))
+{
+}
+
+static grub_err_t
+grub_pxe_read (grub_disk_t disk __attribute((unused)),
+ grub_disk_addr_t sector __attribute((unused)),
+ grub_size_t size __attribute((unused)),
+ char *buf __attribute((unused)))
+{
+ return GRUB_ERR_OUT_OF_RANGE;
+}
+
+static grub_err_t
+grub_pxe_write (grub_disk_t disk __attribute((unused)),
+ grub_disk_addr_t sector __attribute((unused)),
+ grub_size_t size __attribute((unused)),
+ const char *buf __attribute((unused)))
+{
+ return GRUB_ERR_OUT_OF_RANGE;
+}
+
+static struct grub_disk_dev grub_pxe_dev =
+ {
+ .name = "pxe",
+ .id = GRUB_DISK_DEVICE_PXE_ID,
+ .iterate = grub_pxe_iterate,
+ .open = grub_pxe_open,
+ .close = grub_pxe_close,
+ .read = grub_pxe_read,
+ .write = grub_pxe_write,
+ .next = 0
+ };
+
+static grub_err_t
+grub_pxefs_dir (grub_device_t device __attribute((unused)),
+ const char *path __attribute((unused)),
+ int (*hook) (const char *filename, int dir) __attribute((unused)))
+{
+ return GRUB_ERR_NONE;
+}
+
+static struct grub_fs grub_pxefs_fs_int;
+
+static grub_err_t
+grub_pxefs_open (struct grub_file *file, const char *name)
+{
+ union
+ {
+ struct grub_pxenv_tftp_get_fsize c1;
+ struct grub_pxenv_tftp_open c2;
+ } c;
+ struct grub_pxe_data *data;
+ grub_file_t file_int, bufio;
+
+ c.c1.server_ip = grub_pxe_server_ip;
+ c.c1.gateway_ip = grub_pxe_gateway_ip;
+ grub_strcpy (c.c1.filename, name);
+ grub_pxe_call (GRUB_PXENV_TFTP_GET_FSIZE, &c.c1);
+ if (c.c1.status)
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
+
+ file->size = c.c1.file_size;
+
+ c.c2.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
+ c.c2.packet_size = grub_pxe_blksize;
+ grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &c.c2);
+ if (c.c2.status)
+ return grub_error (GRUB_ERR_BAD_FS, "open fails");
+
+ data = grub_malloc (sizeof (struct grub_pxe_data) + grub_strlen (name) + 1);
+ if (! data)
+ return grub_errno;
+
+ data->packet_number = 0;
+ grub_strcpy (data->filename, name);
+
+ file_int = grub_malloc (sizeof (*file_int));
+ if (! file_int)
+ {
+ grub_free (data);
+ return grub_errno;
+ }
+
+ file_int->data = data;
+ file_int->offset = 0;
+ file_int->device = 0;
+ file_int->size = file->size;
+ file_int->read_hook = 0;
+ file_int->fs = &grub_pxefs_fs_int;
+
+ bufio = grub_bufio_open (file_int, grub_pxe_blksize);
+ if (! bufio)
+ {
+ grub_free (file_int);
+ grub_free (data);
+ return grub_errno;
+ }
+
+ file->data = bufio;
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_ssize_t
+grub_pxefs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+ grub_file_t bufio;
+
+ bufio = file->data;
+ bufio->offset = file->offset;
+
+ return bufio->fs->read (bufio, buf, len);
+}
+
+static grub_ssize_t
+grub_pxefs_close (grub_file_t file)
+{
+ grub_file_close ((grub_file_t) file->data);
+
+ return grub_errno;
+}
+
+static grub_ssize_t
+grub_pxefs_read_int (grub_file_t file, char *buf, grub_size_t len)
+{
+ struct grub_pxenv_tftp_read c;
+ struct grub_pxe_data *data;
+ grub_uint32_t pn, r;
+
+ data = file->data;
+
+ pn = grub_divmod64 (file->offset, grub_pxe_blksize, &r);
+ if (r)
+ return grub_error (GRUB_ERR_BAD_FS,
+ "read access must be aligned to packet size");
+
+ if (data->packet_number > pn)
+ {
+ struct grub_pxenv_tftp_open o;
+
+ grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &o);
+
+ o.server_ip = grub_pxe_server_ip;
+ o.gateway_ip = grub_pxe_gateway_ip;
+ grub_strcpy (o.filename, data->filename);
+ o.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
+ o.packet_size = grub_pxe_blksize;
+ grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &o);
+ if (o.status)
+ return grub_error (GRUB_ERR_BAD_FS, "open fails");
+ data->packet_number = 0;
+ }
+
+ c.buffer = SEGOFS (GRUB_MEMORY_MACHINE_SCRATCH_ADDR);
+ while (pn >= data->packet_number)
+ {
+ c.buffer_size = grub_pxe_blksize;
+ grub_pxe_call (GRUB_PXENV_TFTP_READ, &c);
+ if (c.status)
+ {
+ grub_error (GRUB_ERR_BAD_FS, "read fails");
+ return -1;
+ }
+ data->packet_number++;
+ }
+
+ grub_memcpy (buf, (char *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, len);
+
+ return len;
+}
+
+static grub_err_t
+grub_pxefs_close_int (grub_file_t file)
+{
+ struct grub_pxenv_tftp_close c;
+
+ grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c);
+ grub_free (file->data);
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_pxefs_label (grub_device_t device __attribute ((unused)),
+ char **label __attribute ((unused)))
+{
+ *label = 0;
+ return GRUB_ERR_NONE;
+}
+
+static struct grub_fs grub_pxefs_fs =
+ {
+ .name = "pxefs",
+ .dir = grub_pxefs_dir,
+ .open = grub_pxefs_open,
+ .read = grub_pxefs_read,
+ .close = grub_pxefs_close,
+ .label = grub_pxefs_label,
+ .next = 0
+ };
+
+static struct grub_fs grub_pxefs_fs_int =
+ {
+ .name = "pxefs",
+ .read = grub_pxefs_read_int,
+ .close = grub_pxefs_close_int,
+ };
+
+static void
+grub_pxe_detect (void)
+{
+ struct grub_pxenv *pxenv;
+ struct grub_pxenv_get_cached_info ci;
+ struct grub_pxenv_boot_player *bp;
+
+ pxenv = grub_pxe_scan ();
+ if (! pxenv)
+ return;
+
+ ci.packet_type = GRUB_PXENV_PACKET_TYPE_DHCP_ACK;
+ ci.buffer = 0;
+ ci.buffer_size = 0;
+ grub_pxe_call (GRUB_PXENV_GET_CACHED_INFO, &ci);
+ if (ci.status)
+ return;
+
+ bp = LINEAR (ci.buffer);
+
+ grub_pxe_your_ip = bp->your_ip;
+ grub_pxe_server_ip = bp->server_ip;
+ grub_pxe_gateway_ip = bp->gateway_ip;
+
+ grub_pxe_pxenv = pxenv;
+}
+
+void
+grub_pxe_unload (void)
+{
+ if (grub_pxe_pxenv)
+ {
+ grub_fs_unregister (&grub_pxefs_fs);
+ grub_disk_dev_unregister (&grub_pxe_dev);
+
+ grub_pxe_pxenv = 0;
+ }
+}
+
+GRUB_MOD_INIT(pxe)
+{
+ (void) mod; /* To stop warning. */
+
+ grub_pxe_detect ();
+ if (grub_pxe_pxenv)
+ {
+ grub_disk_dev_register (&grub_pxe_dev);
+ grub_fs_register (&grub_pxefs_fs);
+ }
+}
+
+GRUB_MOD_FINI(pxe)
+{
+ grub_pxe_unload ();
+}
diff --git a/include/grub/disk.h b/include/grub/disk.h
index 0e27892..16765d0 100644
--- a/include/grub/disk.h
+++ b/include/grub/disk.h
@@ -39,6 +39,7 @@ enum grub_disk_dev_id
GRUB_DISK_DEVICE_MEMDISK_ID,
GRUB_DISK_DEVICE_NAND_ID,
GRUB_DISK_DEVICE_UUID_ID,
+ GRUB_DISK_DEVICE_PXE_ID,
};
struct grub_disk;
diff --git a/include/grub/i386/pc/pxe.h b/include/grub/i386/pc/pxe.h
new file mode 100755
index 0000000..43fec80
--- /dev/null
+++ b/include/grub/i386/pc/pxe.h
@@ -0,0 +1,318 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * GRUB 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CPU_PXE_H
+#define GRUB_CPU_PXE_H
+
+#include <grub/types.h>
+
+#define GRUB_PXENV_TFTP_OPEN 0x0020
+#define GRUB_PXENV_TFTP_CLOSE 0x0021
+#define GRUB_PXENV_TFTP_READ 0x0022
+#define GRUB_PXENV_TFTP_READ_FILE 0x0023
+#define GRUB_PXENV_TFTP_READ_FILE_PMODE 0x0024
+#define GRUB_PXENV_TFTP_GET_FSIZE 0x0025
+
+#define GRUB_PXENV_UDP_OPEN 0x0030
+#define GRUB_PXENV_UDP_CLOSE 0x0031
+#define GRUB_PXENV_UDP_READ 0x0032
+#define GRUB_PXENV_UDP_WRITE 0x0033
+
+#define GRUB_PXENV_START_UNDI 0x0000
+#define GRUB_PXENV_UNDI_STARTUP 0x0001
+#define GRUB_PXENV_UNDI_CLEANUP 0x0002
+#define GRUB_PXENV_UNDI_INITIALIZE 0x0003
+#define GRUB_PXENV_UNDI_RESET_NIC 0x0004
+#define GRUB_PXENV_UNDI_SHUTDOWN 0x0005
+#define GRUB_PXENV_UNDI_OPEN 0x0006
+#define GRUB_PXENV_UNDI_CLOSE 0x0007
+#define GRUB_PXENV_UNDI_TRANSMIT 0x0008
+#define GRUB_PXENV_UNDI_SET_MCAST_ADDR 0x0009
+#define GRUB_PXENV_UNDI_SET_STATION_ADDR 0x000A
+#define GRUB_PXENV_UNDI_SET_PACKET_FILTER 0x000B
+#define GRUB_PXENV_UNDI_GET_INFORMATION 0x000C
+#define GRUB_PXENV_UNDI_GET_STATISTICS 0x000D
+#define GRUB_PXENV_UNDI_CLEAR_STATISTICS 0x000E
+#define GRUB_PXENV_UNDI_INITIATE_DIAGS 0x000F
+#define GRUB_PXENV_UNDI_FORCE_INTERRUPT 0x0010
+#define GRUB_PXENV_UNDI_GET_MCAST_ADDR 0x0011
+#define GRUB_PXENV_UNDI_GET_NIC_TYPE 0x0012
+#define GRUB_PXENV_UNDI_GET_IFACE_INFO 0x0013
+#define GRUB_PXENV_UNDI_ISR 0x0014
+#define GRUB_PXENV_STOP_UNDI 0x0015
+#define GRUB_PXENV_UNDI_GET_STATE 0x0015
+
+#define GRUB_PXENV_UNLOAD_STACK 0x0070
+#define GRUB_PXENV_GET_CACHED_INFO 0x0071
+#define GRUB_PXENV_RESTART_DHCP 0x0072
+#define GRUB_PXENV_RESTART_TFTP 0x0073
+#define GRUB_PXENV_MODE_SWITCH 0x0074
+#define GRUB_PXENV_START_BASE 0x0075
+#define GRUB_PXENV_STOP_BASE 0x0076
+
+#define GRUB_PXENV_EXIT_SUCCESS 0x0000
+#define GRUB_PXENV_EXIT_FAILURE 0x0001
+
+#define GRUB_PXENV_STATUS_SUCCESS 0x00
+#define GRUB_PXENV_STATUS_FAILURE 0x01
+#define GRUB_PXENV_STATUS_BAD_FUNC 0x02
+#define GRUB_PXENV_STATUS_UNSUPPORTED 0x03
+#define GRUB_PXENV_STATUS_KEEP_UNDI 0x04
+#define GRUB_PXENV_STATUS_KEEP_ALL 0x05
+#define GRUB_PXENV_STATUS_OUT_OF_RESOURCES 0x06
+#define GRUB_PXENV_STATUS_ARP_TIMEOUT 0x11
+#define GRUB_PXENV_STATUS_UDP_CLOSED 0x18
+#define GRUB_PXENV_STATUS_UDP_OPEN 0x19
+#define GRUB_PXENV_STATUS_TFTP_CLOSED 0x1A
+#define GRUB_PXENV_STATUS_TFTP_OPEN 0x1B
+#define GRUB_PXENV_STATUS_MCOPY_PROBLEM 0x20
+#define GRUB_PXENV_STATUS_BIS_INTEGRITY_FAILURE 0x21
+#define GRUB_PXENV_STATUS_BIS_VALIDATE_FAILURE 0x22
+#define GRUB_PXENV_STATUS_BIS_INIT_FAILURE 0x23
+#define GRUB_PXENV_STATUS_BIS_SHUTDOWN_FAILURE 0x24
+#define GRUB_PXENV_STATUS_BIS_GBOA_FAILURE 0x25
+#define GRUB_PXENV_STATUS_BIS_FREE_FAILURE 0x26
+#define GRUB_PXENV_STATUS_BIS_GSI_FAILURE 0x27
+#define GRUB_PXENV_STATUS_BIS_BAD_CKSUM 0x28
+#define GRUB_PXENV_STATUS_TFTP_CANNOT_ARP_ADDRESS 0x30
+#define GRUB_PXENV_STATUS_TFTP_OPEN_TIMEOUT 0x32
+
+#define GRUB_PXENV_STATUS_TFTP_UNKNOWN_OPCODE 0x33
+#define GRUB_PXENV_STATUS_TFTP_READ_TIMEOUT 0x35
+#define GRUB_PXENV_STATUS_TFTP_ERROR_OPCODE 0x36
+#define GRUB_PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION 0x38
+#define GRUB_PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION 0x39
+#define GRUB_PXENV_STATUS_TFTP_TOO_MANY_PACKAGES 0x3A
+#define GRUB_PXENV_STATUS_TFTP_FILE_NOT_FOUND 0x3B
+#define GRUB_PXENV_STATUS_TFTP_ACCESS_VIOLATION 0x3C
+#define GRUB_PXENV_STATUS_TFTP_NO_MCAST_ADDRESS 0x3D
+#define GRUB_PXENV_STATUS_TFTP_NO_FILESIZE 0x3E
+#define GRUB_PXENV_STATUS_TFTP_INVALID_PACKET_SIZE 0x3F
+#define GRUB_PXENV_STATUS_DHCP_TIMEOUT 0x51
+#define GRUB_PXENV_STATUS_DHCP_NO_IP_ADDRESS 0x52
+#define GRUB_PXENV_STATUS_DHCP_NO_BOOTFILE_NAME 0x53
+#define GRUB_PXENV_STATUS_DHCP_BAD_IP_ADDRESS 0x54
+#define GRUB_PXENV_STATUS_UNDI_INVALID_FUNCTION 0x60
+#define GRUB_PXENV_STATUS_UNDI_MEDIATEST_FAILED 0x61
+#define GRUB_PXENV_STATUS_UNDI_CANNOT_INIT_NIC_FOR_MCAST 0x62
+#define GRUB_PXENV_STATUS_UNDI_CANNOT_INITIALIZE_NIC 0x63
+#define GRUB_PXENV_STATUS_UNDI_CANNOT_INITIALIZE_PHY 0x64
+#define GRUB_PXENV_STATUS_UNDI_CANNOT_READ_CONFIG_DATA 0x65
+#define GRUB_PXENV_STATUS_UNDI_CANNOT_READ_INIT_DATA 0x66
+#define GRUB_PXENV_STATUS_UNDI_BAD_MAC_ADDRESS 0x67
+#define GRUB_PXENV_STATUS_UNDI_BAD_EEPROM_CHECKSUM 0x68
+#define GRUB_PXENV_STATUS_UNDI_ERROR_SETTING_ISR 0x69
+#define GRUB_PXENV_STATUS_UNDI_INVALID_STATE 0x6A
+#define GRUB_PXENV_STATUS_UNDI_TRANSMIT_ERROR 0x6B
+#define GRUB_PXENV_STATUS_UNDI_INVALID_PARAMETER 0x6C
+#define GRUB_PXENV_STATUS_BSTRAP_PROMPT_MENU 0x74
+#define GRUB_PXENV_STATUS_BSTRAP_MCAST_ADDR 0x76
+#define GRUB_PXENV_STATUS_BSTRAP_MISSING_LIST 0x77
+#define GRUB_PXENV_STATUS_BSTRAP_NO_RESPONSE 0x78
+#define GRUB_PXENV_STATUS_BSTRAP_FILE_TOO_BIG 0x79
+#define GRUB_PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE 0xA0
+#define GRUB_PXENV_STATUS_BINL_NO_PXE_SERVER 0xA1
+#define GRUB_PXENV_STATUS_NOT_AVAILABLE_IN_PMODE 0xA2
+#define GRUB_PXENV_STATUS_NOT_AVAILABLE_IN_RMODE 0xA3
+#define GRUB_PXENV_STATUS_BUSD_DEVICE_NOT_SUPPORTED 0xB0
+#define GRUB_PXENV_STATUS_LOADER_NO_FREE_BASE_MEMORY 0xC0
+#define GRUB_PXENV_STATUS_LOADER_NO_BC_ROMID 0xC1
+#define GRUB_PXENV_STATUS_LOADER_BAD_BC_ROMID 0xC2
+#define GRUB_PXENV_STATUS_LOADER_BAD_BC_RUNTIME_IMAGE 0xC3
+#define GRUB_PXENV_STATUS_LOADER_NO_UNDI_ROMID 0xC4
+#define GRUB_PXENV_STATUS_LOADER_BAD_UNDI_ROMID 0xC5
+#define GRUB_PXENV_STATUS_LOADER_BAD_UNDI_DRIVER_IMAGE 0xC6
+#define GRUB_PXENV_STATUS_LOADER_NO_PXE_STRUCT 0xC8
+#define GRUB_PXENV_STATUS_LOADER_NO_PXENV_STRUCT 0xC9
+#define GRUB_PXENV_STATUS_LOADER_UNDI_START 0xCA
+#define GRUB_PXENV_STATUS_LOADER_BC_START 0xCB
+
+#define GRUB_PXENV_PACKET_TYPE_DHCP_DISCOVER 1
+#define GRUB_PXENV_PACKET_TYPE_DHCP_ACK 2
+#define GRUB_PXENV_PACKET_TYPE_CACHED_REPLY 3
+
+#define GRUB_PXE_BOOTP_REQ 1
+#define GRUB_PXE_BOOTP_REP 2
+
+#define GRUB_PXE_BOOTP_BCAST 0x8000
+
+#if 1
+#define GRUB_PXE_BOOTP_DHCPVEND 1024 /* DHCP extended vendor field size */
+#else
+#define GRUB_PXE_BOOTP_DHCPVEND 312 /* DHCP standard vendor field size */
+#endif
+
+#define GRUB_PXE_MIN_BLKSIZE 512
+#define GRUB_PXE_MAX_BLKSIZE 1432
+
+#define GRUB_PXE_TFTP_PORT 69
+
+#define GRUB_PXE_VM_RFC1048 0x63825363L
+
+#define GRUB_PXE_ERR_LEN 0xFFFFFFFF
+
+#ifndef ASM_FILE
+
+struct grub_pxenv
+{
+ grub_uint8_t signature[6]; /* 'PXENV+' */
+ grub_uint16_t version; /* MSB = major, LSB = minor */
+ grub_uint8_t length; /* structure length */
+ grub_uint8_t checksum; /* checksum pad */
+ grub_uint32_t rm_entry; /* SEG:OFF to PXE entry point */
+ grub_uint32_t pm_offset; /* Protected mode entry */
+ grub_uint16_t pm_selector; /* Protected mode selector */
+ grub_uint16_t stack_seg; /* Stack segment address */
+ grub_uint16_t stack_size; /* Stack segment size (bytes) */
+ grub_uint16_t bc_code_seg; /* BC Code segment address */
+ grub_uint16_t bc_code_size; /* BC Code segment size (bytes) */
+ grub_uint16_t bc_data_seg; /* BC Data segment address */
+ grub_uint16_t bc_data_size; /* BC Data segment size (bytes) */
+ grub_uint16_t undi_data_seg; /* UNDI Data segment address */
+ grub_uint16_t undi_data_size; /* UNDI Data segment size (bytes) */
+ grub_uint16_t undi_code_seg; /* UNDI Code segment address */
+ grub_uint16_t undi_code_size; /* UNDI Code segment size (bytes) */
+ grub_uint32_t pxe_ptr; /* SEG:OFF to !PXE struct */
+} __attribute__ ((packed));
+
+struct grub_pxenv_get_cached_info
+{
+ grub_uint16_t status;
+ grub_uint16_t packet_type;
+ grub_uint16_t buffer_size;
+ grub_uint32_t buffer;
+ grub_uint16_t buffer_limit;
+} __attribute__ ((packed));
+
+#define GRUB_PXE_MAC_ADDR_LEN 16
+
+typedef grub_uint8_t grub_pxe_mac_addr[GRUB_PXE_MAC_ADDR_LEN];
+
+struct grub_pxenv_boot_player
+{
+ grub_uint8_t opcode;
+ grub_uint8_t hw_type; /* hardware type */
+ grub_uint8_t hw_len; /* hardware addr len */
+ grub_uint8_t gate_hops; /* zero it */
+ grub_uint32_t ident; /* random number chosen by client */
+ grub_uint16_t seconds; /* seconds since did initial bootstrap */
+ grub_uint16_t flags;
+ grub_uint32_t client_ip;
+ grub_uint32_t your_ip;
+ grub_uint32_t server_ip;
+ grub_uint32_t gateway_ip;
+ grub_pxe_mac_addr mac_addr;
+ grub_uint8_t server_name[64];
+ grub_uint8_t boot_file[128];
+ union
+ {
+ grub_uint8_t d[GRUB_PXE_BOOTP_DHCPVEND]; /* raw array of vendor/dhcp options */
+ struct
+ {
+ grub_uint32_t magic; /* DHCP magic cookie */
+ grub_uint32_t flags; /* bootp flags/opcodes */
+ grub_uint8_t padding[56];
+ } v;
+ } vendor;
+} __attribute__ ((packed));
+
+struct grub_pxenv_tftp_open
+{
+ grub_uint16_t status;
+ grub_uint32_t server_ip;
+ grub_uint32_t gateway_ip;
+ grub_uint8_t filename[128];
+ grub_uint16_t tftp_port;
+ grub_uint16_t packet_size;
+} __attribute__ ((packed));
+
+struct grub_pxenv_tftp_close
+{
+ grub_uint16_t status;
+} __attribute__ ((packed));
+
+struct grub_pxenv_tftp_read
+{
+ grub_uint16_t status;
+ grub_uint16_t packet_number;
+ grub_uint16_t buffer_size;
+ grub_uint32_t buffer;
+} __attribute__ ((packed));
+
+struct grub_pxenv_tftp_get_fsize
+{
+ grub_uint16_t status;
+ grub_uint32_t server_ip;
+ grub_uint32_t gateway_ip;
+ grub_uint8_t filename[128];
+ grub_uint32_t file_size;
+} __attribute__ ((packed));
+
+struct grub_pxenv_udp_open
+{
+ grub_uint16_t status;
+ grub_uint32_t src_ip;
+} __attribute__ ((packed));
+
+struct grub_pxenv_udp_close
+{
+ grub_uint16_t status;
+} __attribute__ ((packed));
+
+struct grub_pxenv_udp_write
+{
+ grub_uint16_t status;
+ grub_uint32_t ip;
+ grub_uint32_t gateway;
+ grub_uint16_t src_port;
+ grub_uint16_t dst_port;
+ grub_uint16_t buffer_size;
+ grub_uint32_t buffer;
+} __attribute__ ((packed));
+
+struct grub_pxenv_udp_read
+{
+ grub_uint16_t status;
+ grub_uint32_t src_ip;
+ grub_uint32_t dst_ip;
+ grub_uint16_t src_port;
+ grub_uint16_t dst_port;
+ grub_uint16_t buffer_size;
+ grub_uint32_t buffer;
+} __attribute__ ((packed));
+
+struct grub_pxenv_unload_stack
+{
+ grub_uint16_t status;
+ grub_uint8_t reserved[10];
+} __attribute__ ((packed));
+
+struct grub_pxenv * EXPORT_FUNC(grub_pxe_scan) (void);
+int EXPORT_FUNC(grub_pxe_call) (int func, void * data);
+
+extern struct grub_pxenv *grub_pxe_pxenv;
+extern grub_uint32_t grub_pxe_your_ip;
+extern grub_uint32_t grub_pxe_server_ip;
+extern grub_uint32_t grub_pxe_gateway_ip;
+extern int grub_pxe_blksize;
+
+void grub_pxe_unload (void);
+
+#endif
+
+#endif /* GRUB_CPU_PXE_H */
diff --git a/kern/i386/pc/init.c b/kern/i386/pc/init.c
index e47cbfd..646545e 100644
--- a/kern/i386/pc/init.c
+++ b/kern/i386/pc/init.c
@@ -71,14 +71,19 @@ make_install_device (void)
if (grub_root_drive == 0xFF)
grub_root_drive = grub_boot_drive;
- grub_sprintf (dev, "(%cd%u", (grub_root_drive & 0x80) ? 'h' : 'f',
- grub_root_drive & 0x7f);
+ if (grub_root_drive == 0x7F)
+ grub_strcpy (dev, "(pxe");
+ else
+ {
+ grub_sprintf (dev, "(%cd%u", (grub_root_drive & 0x80) ? 'h' : 'f',
+ grub_root_drive & 0x7f);
- if (grub_install_dos_part >= 0)
- grub_sprintf (dev + grub_strlen (dev), ",%u", grub_install_dos_part + 1);
+ if (grub_install_dos_part >= 0)
+ grub_sprintf (dev + grub_strlen (dev), ",%u", grub_install_dos_part + 1);
- if (grub_install_bsd_part >= 0)
- grub_sprintf (dev + grub_strlen (dev), ",%c", grub_install_bsd_part + 'a');
+ if (grub_install_bsd_part >= 0)
+ grub_sprintf (dev + grub_strlen (dev), ",%c", grub_install_bsd_part + 'a');
+ }
grub_sprintf (dev + grub_strlen (dev), ")%s", grub_prefix);
grub_strcpy (grub_prefix, dev);
diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S
index 75c46ad..679ad1f 100644
--- a/kern/i386/pc/startup.S
+++ b/kern/i386/pc/startup.S
@@ -2053,3 +2053,102 @@ FUNCTION(grub_vbe_bios_set_palette_data)
popl %ebx
popl %ebp
ret
+
+
+pxe_rm_entry:
+ .long 0
+
+/*
+ * struct grub_pxenv *grub_pxe_scan (void);
+ */
+FUNCTION(grub_pxe_scan)
+ pushl %ebp
+ pushl %ebx
+
+ xorl %ebx, %ebx
+ xorl %ecx, %ecx
+
+ call prot_to_real
+ .code16
+
+ pushw %es
+
+ movw $0x5650, %ax
+ int $0x1A
+ cmpw $0x564E, %ax
+ jnz 1f
+ cmpl $0x4E455850, %es:(%bx) /* PXEN(V+) */
+ jnz 1f
+ cmpw $0x201, %es:6(%bx) /* API version */
+ jb 1f
+ lesw %es:0x28(%bx), %bx /* !PXE structure */
+ cmpl $0x45585021, %es:(%bx) /* !PXE */
+ jnz 1f
+ movw %es, %cx
+ jmp 2f
+1:
+ xorw %bx, %bx
+ xorw %cx, %cx
+2:
+
+ popw %es
+
+ DATA32 call real_to_prot
+ .code32
+
+ xorl %eax, %eax
+ leal (%eax, %ecx, 4), %ecx
+ leal (%ebx, %ecx, 4), %eax /* eax = ecx * 16 + ebx */
+
+ orl %eax, %eax
+ jz 1f
+
+ movl 0x10(%eax), %ecx
+ movl %ecx, pxe_rm_entry
+
+1:
+
+ popl %ebx
+ popl %ebp
+ ret
+
+/*
+ * int grub_pxe_call (int func, void* data);
+ */
+FUNCTION(grub_pxe_call)
+ pushl %ebp
+ movl %esp, %ebp
+ pushl %esi
+ pushl %edi
+ pushl %ebx
+
+ movl %eax, %ecx
+ movl %edx, %eax
+ andl $0xF, %eax
+ shrl $4, %edx
+ shll $16, %edx
+ addl %eax, %edx
+ movl pxe_rm_entry, %ebx
+
+ call prot_to_real
+ .code16
+
+ pushl %ebx
+ pushl %edx
+ pushw %cx
+ movw %sp, %bx
+ lcall *%ss:6(%bx)
+ cld
+ addw $10, %sp
+ movw %ax, %cx
+
+ DATA32 call real_to_prot
+ .code32
+
+ movzwl %cx, %eax
+
+ popl %ebx
+ popl %edi
+ popl %esi
+ popl %ebp
+ ret
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH] PXE support for grub2
2008-07-30 16:50 [PATCH] PXE support for grub2 Bean
@ 2008-08-01 3:46 ` Bean
2008-08-01 3:52 ` Pavel Roskin
2008-08-02 10:48 ` Robert Millan
2008-08-04 21:08 ` Marco Gerards
2 siblings, 1 reply; 15+ messages in thread
From: Bean @ 2008-08-01 3:46 UTC (permalink / raw)
To: The development of GRUB 2
On Thu, Jul 31, 2008 at 12:50 AM, Bean <bean123ch@gmail.com> wrote:
> Hi,
>
> This patch add the (pxe) device that can be used to load files using
> the pxe service. It also add a user land command pxe that can be used
> to show pxe information as well as set some parameter.
>
> To create a pxe boot image:
>
> ./grub-mkimage -d . -o core.img pxe
> cat pxeboot.img core.img > g2pxe
>
> g2pxe is the pxe boot file, copy it to tftp server, you also need to
> copy *.mod, fs.lst, command.lst, moddep.lst and grub.cfg to /boot/grub
> directory in the tftp server.
>
> To test it in qemu, copy the files to directory such as /tftp, then:
>
> qemu -boot n -tftp /tftp -bootp /g2pxe
>
> usage for pxe command:
>
> pxe info
> Show information about pxe, like block size, client ip, etc.
>
> pxe blksize size
> Set block size. tftp transfer in trunks of bytes, the size can be
> configured. The minimum size is 512, which is also the default. The
> maximum size is 1432. Normally, you can increase download speed by
> setting larger block size, but some old tftp server may not support
> it. Also, qemu doesn't support size other than 512.
>
> pxe unload
> Unload the pxe runtime environment.
>
> Please note that this patch depends on my other patch bufio, you need
> to apply that first.
>
> 2008-07-30 Bean <bean123ch@gmail.com>
>
> * boot/i386/pc/pxeboot.S: Use drive number 0x7F for pxe.
>
> * conf/i386-pc.rmk (kernel_img_HEADERS): Add machine/pxe.h.
> (pkglib_MODULES): Add pxe.mod and pxecmd.mod.
> (pxe_mod_SOURCES): New macro.
> (pxe_mod_CFLAGS): Likewise.
> (pxe_mod_LDFLAGS): Likewise.
> (pxecmd_mod_SOURCES): Likewise.
> (pxecmd_mod_CFLAGS): Likewise.
> (pxecmd_mod_LDFLAGS): Likewise.
>
> * kern/i386/pc/startup.S (grub_pxe_scan): New function.
> (grub_pxe_call): Likewise.
>
> * kern/i386/pc/init.c (make_install_device): Set root to (pxe) for pxe boot.
>
> * include/grub/disk.h (grub_disk_dev_id): Add GRUB_DISK_DEVICE_PXE_ID.
>
> * commands/i386/pc/pxecmd.c: New file.
>
> * disk/i386/pc/pxe.c: Likewise.
>
> * include/grub/i386/pc/pxe.h: Likewise.
Hi,
Any comment ?
--
Bean
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] PXE support for grub2
2008-08-01 3:46 ` Bean
@ 2008-08-01 3:52 ` Pavel Roskin
2008-08-01 11:32 ` Robert Millan
0 siblings, 1 reply; 15+ messages in thread
From: Pavel Roskin @ 2008-08-01 3:52 UTC (permalink / raw)
To: The development of GRUB 2
On Fri, 2008-08-01 at 11:46 +0800, Bean wrote:
> On Thu, Jul 31, 2008 at 12:50 AM, Bean <bean123ch@gmail.com> wrote:
> > Hi,
> >
> > This patch add the (pxe) device that can be used to load files using
> > the pxe service. It also add a user land command pxe that can be used
> > to show pxe information as well as set some parameter.
> >
> > To create a pxe boot image:
> >
> > ./grub-mkimage -d . -o core.img pxe
> > cat pxeboot.img core.img > g2pxe
Perhaps it should be a separate script? Or maybe it should be an option
for grub-mkimage? At least it should be documented. Users who want to
use PXE should be able to figure it out easily.
--
Regards,
Pavel Roskin
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] PXE support for grub2
2008-08-01 3:52 ` Pavel Roskin
@ 2008-08-01 11:32 ` Robert Millan
2008-08-01 16:21 ` Pavel Roskin
0 siblings, 1 reply; 15+ messages in thread
From: Robert Millan @ 2008-08-01 11:32 UTC (permalink / raw)
To: The development of GRUB 2
On Thu, Jul 31, 2008 at 11:52:43PM -0400, Pavel Roskin wrote:
> On Fri, 2008-08-01 at 11:46 +0800, Bean wrote:
> > On Thu, Jul 31, 2008 at 12:50 AM, Bean <bean123ch@gmail.com> wrote:
> > > Hi,
> > >
> > > This patch add the (pxe) device that can be used to load files using
> > > the pxe service. It also add a user land command pxe that can be used
> > > to show pxe information as well as set some parameter.
> > >
> > > To create a pxe boot image:
> > >
> > > ./grub-mkimage -d . -o core.img pxe
> > > cat pxeboot.img core.img > g2pxe
>
> Perhaps it should be a separate script? Or maybe it should be an option
> for grub-mkimage?
You mean for pxeboot.img? Note we have this file in svn already. His code
just adds 'pxe' module AFAICS.
> At least it should be documented. Users who want to
> use PXE should be able to figure it out easily.
Agreed. Maybe in the wiki?
--
Robert Millan
The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
how) you may access your data; but nobody's threatening your freedom: we
still allow you to remove your data and not access it at all."
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] PXE support for grub2
2008-08-01 11:32 ` Robert Millan
@ 2008-08-01 16:21 ` Pavel Roskin
2008-08-01 16:59 ` Bean
0 siblings, 1 reply; 15+ messages in thread
From: Pavel Roskin @ 2008-08-01 16:21 UTC (permalink / raw)
To: The development of GRUB 2
On Fri, 2008-08-01 at 13:32 +0200, Robert Millan wrote:
> On Thu, Jul 31, 2008 at 11:52:43PM -0400, Pavel Roskin wrote:
> > On Fri, 2008-08-01 at 11:46 +0800, Bean wrote:
> > > On Thu, Jul 31, 2008 at 12:50 AM, Bean <bean123ch@gmail.com> wrote:
> > > > Hi,
> > > >
> > > > This patch add the (pxe) device that can be used to load files using
> > > > the pxe service. It also add a user land command pxe that can be used
> > > > to show pxe information as well as set some parameter.
> > > >
> > > > To create a pxe boot image:
> > > >
> > > > ./grub-mkimage -d . -o core.img pxe
> > > > cat pxeboot.img core.img > g2pxe
> >
> > Perhaps it should be a separate script? Or maybe it should be an option
> > for grub-mkimage?
>
> You mean for pxeboot.img? Note we have this file in svn already. His code
> just adds 'pxe' module AFAICS.
I mean that the second line is impossible to guess or get from
grub-mkimage documentation. If I was to make a PXE image, I would need
to go to the list archives to find out how to make it. But I'm not
experienced with network boot. Maybe it's obvious for others, I don't
know.
> > At least it should be documented. Users who want to
> > use PXE should be able to figure it out easily.
>
> Agreed. Maybe in the wiki?
Maybe. But eventually the GRUB releases should be self-contained.
--
Regards,
Pavel Roskin
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] PXE support for grub2
2008-08-01 16:21 ` Pavel Roskin
@ 2008-08-01 16:59 ` Bean
2008-08-02 4:34 ` Bean
0 siblings, 1 reply; 15+ messages in thread
From: Bean @ 2008-08-01 16:59 UTC (permalink / raw)
To: The development of GRUB 2
On Sat, Aug 2, 2008 at 12:21 AM, Pavel Roskin <proski@gnu.org> wrote:
> On Fri, 2008-08-01 at 13:32 +0200, Robert Millan wrote:
>> On Thu, Jul 31, 2008 at 11:52:43PM -0400, Pavel Roskin wrote:
>> > On Fri, 2008-08-01 at 11:46 +0800, Bean wrote:
>> > > On Thu, Jul 31, 2008 at 12:50 AM, Bean <bean123ch@gmail.com> wrote:
>> > > > Hi,
>> > > >
>> > > > This patch add the (pxe) device that can be used to load files using
>> > > > the pxe service. It also add a user land command pxe that can be used
>> > > > to show pxe information as well as set some parameter.
>> > > >
>> > > > To create a pxe boot image:
>> > > >
>> > > > ./grub-mkimage -d . -o core.img pxe
>> > > > cat pxeboot.img core.img > g2pxe
>> >
>> > Perhaps it should be a separate script? Or maybe it should be an option
>> > for grub-mkimage?
>>
>> You mean for pxeboot.img? Note we have this file in svn already. His code
>> just adds 'pxe' module AFAICS.
>
> I mean that the second line is impossible to guess or get from
> grub-mkimage documentation. If I was to make a PXE image, I would need
> to go to the list archives to find out how to make it. But I'm not
> experienced with network boot. Maybe it's obvious for others, I don't
> know.
Hi,
This kind of usage have been around for some time. In grub legacy, it
generates pxe image by catenating pxeloader and pre_stage2.
pxeboot.img is basiclly identical to pxeloader.S, and pre_stage2 and
core.img loaded at the same address, so it can conclude pxe image can
be built by combining pxeboot.img and core.img. But I agree that
perhaps not many people know about it, it's a good idea to write some
doc in the wiki.
BTW, any comment on the content of the patch ?
--
Bean
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] PXE support for grub2
2008-08-01 16:59 ` Bean
@ 2008-08-02 4:34 ` Bean
0 siblings, 0 replies; 15+ messages in thread
From: Bean @ 2008-08-02 4:34 UTC (permalink / raw)
To: The development of GRUB 2
On Sat, Aug 2, 2008 at 12:59 AM, Bean <bean123ch@gmail.com> > Hi,
>
> This kind of usage have been around for some time. In grub legacy, it
> generates pxe image by catenating pxeloader and pre_stage2.
> pxeboot.img is basiclly identical to pxeloader.S, and pre_stage2 and
> core.img loaded at the same address, so it can conclude pxe image can
> be built by combining pxeboot.img and core.img. But I agree that
> perhaps not many people know about it, it's a good idea to write some
> doc in the wiki.
>
> BTW, any comment on the content of the patch ?
Hi,
If there is no objection, I'd commit it soon.
--
Bean
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] PXE support for grub2
2008-07-30 16:50 [PATCH] PXE support for grub2 Bean
2008-08-01 3:46 ` Bean
@ 2008-08-02 10:48 ` Robert Millan
2008-08-02 11:20 ` Bean
2008-08-04 21:08 ` Marco Gerards
2 siblings, 1 reply; 15+ messages in thread
From: Robert Millan @ 2008-08-02 10:48 UTC (permalink / raw)
To: The development of GRUB 2
On Thu, Jul 31, 2008 at 12:50:22AM +0800, Bean wrote:
> +#if 1
> +#define GRUB_PXE_BOOTP_DHCPVEND 1024 /* DHCP extended vendor field size */
> +#else
> +#define GRUB_PXE_BOOTP_DHCPVEND 312 /* DHCP standard vendor field size */
> +#endif
A comment would be helpful to explain the 'if 1' option.
> --- a/kern/i386/pc/init.c
> +++ b/kern/i386/pc/init.c
> @@ -71,14 +71,19 @@ make_install_device (void)
> if (grub_root_drive == 0xFF)
> grub_root_drive = grub_boot_drive;
>
> - grub_sprintf (dev, "(%cd%u", (grub_root_drive & 0x80) ? 'h' : 'f',
> - grub_root_drive & 0x7f);
> + if (grub_root_drive == 0x7F)
> + grub_strcpy (dev, "(pxe");
> + else
> + {
> + grub_sprintf (dev, "(%cd%u", (grub_root_drive & 0x80) ? 'h' : 'f',
> + grub_root_drive & 0x7f);
>
> - if (grub_install_dos_part >= 0)
> - grub_sprintf (dev + grub_strlen (dev), ",%u", grub_install_dos_part + 1);
> + if (grub_install_dos_part >= 0)
> + grub_sprintf (dev + grub_strlen (dev), ",%u", grub_install_dos_part + 1);
>
> - if (grub_install_bsd_part >= 0)
> - grub_sprintf (dev + grub_strlen (dev), ",%c", grub_install_bsd_part + 'a');
> + if (grub_install_bsd_part >= 0)
> + grub_sprintf (dev + grub_strlen (dev), ",%c", grub_install_bsd_part + 'a');
> + }
>
> grub_sprintf (dev + grub_strlen (dev), ")%s", grub_prefix);
> grub_strcpy (grub_prefix, dev);
Can we avoid this? I wish make_install_device() was reduced and eventually
disappeared.
Since we already know at install time that the boot drive will be 0x7f, why not
just set the drive via grub-mkimage --prefix?
> --- a/kern/i386/pc/startup.S
> +++ b/kern/i386/pc/startup.S
> @@ -2053,3 +2053,102 @@ FUNCTION(grub_vbe_bios_set_palette_data)
> popl %ebx
> popl %ebp
> ret
> +
> +
> +pxe_rm_entry:
> + .long 0
> +
> +/*
> + * struct grub_pxenv *grub_pxe_scan (void);
> + */
> +FUNCTION(grub_pxe_scan)
Could these go in a module? If they're only used by disk/i386/pc/pxe.c,
maybe they could be merged with that?
--
Robert Millan
The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
how) you may access your data; but nobody's threatening your freedom: we
still allow you to remove your data and not access it at all."
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH] PXE support for grub2
2008-08-02 10:48 ` Robert Millan
@ 2008-08-02 11:20 ` Bean
2008-08-02 11:49 ` Robert Millan
0 siblings, 1 reply; 15+ messages in thread
From: Bean @ 2008-08-02 11:20 UTC (permalink / raw)
To: The development of GRUB 2
On Sat, Aug 2, 2008 at 6:48 PM, Robert Millan <rmh@aybabtu.com> wrote:
> On Thu, Jul 31, 2008 at 12:50:22AM +0800, Bean wrote:
>> +#if 1
>> +#define GRUB_PXE_BOOTP_DHCPVEND 1024 /* DHCP extended vendor field size */
>> +#else
>> +#define GRUB_PXE_BOOTP_DHCPVEND 312 /* DHCP standard vendor field size */
>> +#endif
>
> A comment would be helpful to explain the 'if 1' option.
>
>> --- a/kern/i386/pc/init.c
>> +++ b/kern/i386/pc/init.c
>> @@ -71,14 +71,19 @@ make_install_device (void)
>> if (grub_root_drive == 0xFF)
>> grub_root_drive = grub_boot_drive;
>>
>> - grub_sprintf (dev, "(%cd%u", (grub_root_drive & 0x80) ? 'h' : 'f',
>> - grub_root_drive & 0x7f);
>> + if (grub_root_drive == 0x7F)
>> + grub_strcpy (dev, "(pxe");
>> + else
>> + {
>> + grub_sprintf (dev, "(%cd%u", (grub_root_drive & 0x80) ? 'h' : 'f',
>> + grub_root_drive & 0x7f);
>>
>> - if (grub_install_dos_part >= 0)
>> - grub_sprintf (dev + grub_strlen (dev), ",%u", grub_install_dos_part + 1);
>> + if (grub_install_dos_part >= 0)
>> + grub_sprintf (dev + grub_strlen (dev), ",%u", grub_install_dos_part + 1);
>>
>> - if (grub_install_bsd_part >= 0)
>> - grub_sprintf (dev + grub_strlen (dev), ",%c", grub_install_bsd_part + 'a');
>> + if (grub_install_bsd_part >= 0)
>> + grub_sprintf (dev + grub_strlen (dev), ",%c", grub_install_bsd_part + 'a');
>> + }
>>
>> grub_sprintf (dev + grub_strlen (dev), ")%s", grub_prefix);
>> grub_strcpy (grub_prefix, dev);
>
> Can we avoid this? I wish make_install_device() was reduced and eventually
> disappeared.
>
> Since we already know at install time that the boot drive will be 0x7f, why not
> just set the drive via grub-mkimage --prefix?
Hi,
Yes, we can set this in grub-mkimage.
>
>> --- a/kern/i386/pc/startup.S
>> +++ b/kern/i386/pc/startup.S
>> @@ -2053,3 +2053,102 @@ FUNCTION(grub_vbe_bios_set_palette_data)
>> popl %ebx
>> popl %ebp
>> ret
>> +
>> +
>> +pxe_rm_entry:
>> + .long 0
>> +
>> +/*
>> + * struct grub_pxenv *grub_pxe_scan (void);
>> + */
>> +FUNCTION(grub_pxe_scan)
>
> Could these go in a module? If they're only used by disk/i386/pc/pxe.c,
> maybe they could be merged with that?
The problem is that they need to call real mode function provided by
the pxe rom, so this code must be loaded under 1m. We can solve this
with real mode stub or the patch suggested by daChaac, but it's not
there yet. So we need to keep it in startup.S for some time.
--
Bean
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH] PXE support for grub2
2008-08-02 11:20 ` Bean
@ 2008-08-02 11:49 ` Robert Millan
0 siblings, 0 replies; 15+ messages in thread
From: Robert Millan @ 2008-08-02 11:49 UTC (permalink / raw)
To: The development of GRUB 2
On Sat, Aug 02, 2008 at 07:20:31PM +0800, Bean wrote:
> >> --- a/kern/i386/pc/startup.S
> >> +++ b/kern/i386/pc/startup.S
> >> @@ -2053,3 +2053,102 @@ FUNCTION(grub_vbe_bios_set_palette_data)
> >> popl %ebx
> >> popl %ebp
> >> ret
> >> +
> >> +
> >> +pxe_rm_entry:
> >> + .long 0
> >> +
> >> +/*
> >> + * struct grub_pxenv *grub_pxe_scan (void);
> >> + */
> >> +FUNCTION(grub_pxe_scan)
> >
> > Could these go in a module? If they're only used by disk/i386/pc/pxe.c,
> > maybe they could be merged with that?
>
> The problem is that they need to call real mode function provided by
> the pxe rom, so this code must be loaded under 1m. We can solve this
> with real mode stub or the patch suggested by daChaac, but it's not
> there yet. So we need to keep it in startup.S for some time.
Well I guess we can live with that for a while...
--
Robert Millan
The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
how) you may access your data; but nobody's threatening your freedom: we
still allow you to remove your data and not access it at all."
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] PXE support for grub2
2008-07-30 16:50 [PATCH] PXE support for grub2 Bean
2008-08-01 3:46 ` Bean
2008-08-02 10:48 ` Robert Millan
@ 2008-08-04 21:08 ` Marco Gerards
2008-08-05 3:36 ` Bean
2 siblings, 1 reply; 15+ messages in thread
From: Marco Gerards @ 2008-08-04 21:08 UTC (permalink / raw)
To: The development of GRUB 2
Hi,
Bean <bean123ch@gmail.com> writes:
> This patch add the (pxe) device that can be used to load files using
> the pxe service. It also add a user land command pxe that can be used
> to show pxe information as well as set some parameter.
Great! :-)
> To create a pxe boot image:
>
> ./grub-mkimage -d . -o core.img pxe
> cat pxeboot.img core.img > g2pxe
>
> g2pxe is the pxe boot file, copy it to tftp server, you also need to
> copy *.mod, fs.lst, command.lst, moddep.lst and grub.cfg to /boot/grub
> directory in the tftp server.
>
> To test it in qemu, copy the files to directory such as /tftp, then:
>
> qemu -boot n -tftp /tftp -bootp /g2pxe
>
> usage for pxe command:
>
> pxe info
> Show information about pxe, like block size, client ip, etc.
>
> pxe blksize size
> Set block size. tftp transfer in trunks of bytes, the size can be
> configured. The minimum size is 512, which is also the default. The
> maximum size is 1432. Normally, you can increase download speed by
> setting larger block size, but some old tftp server may not support
> it. Also, qemu doesn't support size other than 512.
>
> pxe unload
> Unload the pxe runtime environment.
Actually, I would prefer:
pxe --info
pxe --blksize=size
pxe --unload
You kinda reimplemented an argument parser. The advantage of the
build in argument parser is that it supports generation of --help
documentation and it supports tab completion.
> Please note that this patch depends on my other patch bufio, you need
> to apply that first.
>
> 2008-07-30 Bean <bean123ch@gmail.com>
>
> * boot/i386/pc/pxeboot.S: Use drive number 0x7F for pxe.
Isn't it in _start?
* boot/i386/pc/pxeboot.S (_start): Use drive number 0x7F for pxe.
> * conf/i386-pc.rmk (kernel_img_HEADERS): Add machine/pxe.h.
> (pkglib_MODULES): Add pxe.mod and pxecmd.mod.
> (pxe_mod_SOURCES): New macro.
> (pxe_mod_CFLAGS): Likewise.
> (pxe_mod_LDFLAGS): Likewise.
> (pxecmd_mod_SOURCES): Likewise.
> (pxecmd_mod_CFLAGS): Likewise.
> (pxecmd_mod_LDFLAGS): Likewise.
>
> * kern/i386/pc/startup.S (grub_pxe_scan): New function.
> (grub_pxe_call): Likewise.
>
> * kern/i386/pc/init.c (make_install_device): Set root to (pxe) for pxe boot.
>
> * include/grub/disk.h (grub_disk_dev_id): Add GRUB_DISK_DEVICE_PXE_ID.
>
> * commands/i386/pc/pxecmd.c: New file.
>
> * disk/i386/pc/pxe.c: Likewise.
>
> * include/grub/i386/pc/pxe.h: Likewise.
>
> --
> Bean
>
> diff --git a/boot/i386/pc/pxeboot.S b/boot/i386/pc/pxeboot.S
> index 7f2a143..62a4fb2 100644
> --- a/boot/i386/pc/pxeboot.S
> +++ b/boot/i386/pc/pxeboot.S
> @@ -26,7 +26,8 @@
> .globl _start; _start:
>
> /* Root drive will default to boot drive */
> - movb $0xFF, %dh
> + movb $0xFF, %dh
> + movb $0x7F, %dl
Please update the copyright year of files you change. IIRC this file
is not from this year. I often forget to mention this, but it applies
in general.
>
> /* Jump to the real world */
> ljmp $0, $0x8200
> diff --git a/commands/i386/pc/pxecmd.c b/commands/i386/pc/pxecmd.c
> new file mode 100755
> index 0000000..6bf3045
> --- /dev/null
> +++ b/commands/i386/pc/pxecmd.c
> @@ -0,0 +1,92 @@
> +/* pxe.c - command to control the pxe driver */
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2008 Free Software Foundation, Inc.
> + *
> + * GRUB 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 3 of the License, or
> + * (at your option) any later version.
> + *
> + * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <grub/normal.h>
> +#include <grub/dl.h>
> +#include <grub/arg.h>
> +#include <grub/err.h>
> +#include <grub/misc.h>
> +#include <grub/machine/pxe.h>
> +
> +static void
> +print_ip (grub_uint32_t ip)
> +{
> + int i;
> +
> + for (i = 0; i < 3; i++)
> + {
> + grub_printf ("%d.", ip & 0xFF);
> + ip >>= 8;
> + }
> + grub_printf ("%d", ip);
> +}
> +
> +static grub_err_t
> +grub_cmd_pxe (struct grub_arg_list *state __attribute__ ((unused)),
> + int argc, char **args)
> +{
> + if (! grub_pxe_pxenv)
> + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "no pxe environment");
> +
> + if ((argc == 0) || (! grub_strcmp (args[0], "info")))
> + {
> + grub_printf ("blksize : %d\n", grub_pxe_blksize);
> + grub_printf ("client ip : ");
> + print_ip (grub_pxe_your_ip);
> + grub_printf ("\nserver ip : ");
> + print_ip (grub_pxe_server_ip);
> + grub_printf ("\ngateway ip : ");
> + print_ip (grub_pxe_gateway_ip);
> + grub_printf ("\n");
> + }
> + else if (! grub_strcmp (args[0], "blksize"))
> + {
> + int size;
> +
> + if (argc < 2)
> + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no blksize specified");
> +
> + size = grub_strtoul (args[1], 0, 0);
> + if (size < GRUB_PXE_MIN_BLKSIZE)
> + size = GRUB_PXE_MIN_BLKSIZE;
> + else if (size > GRUB_PXE_MAX_BLKSIZE)
> + size = GRUB_PXE_MAX_BLKSIZE;
> +
> + grub_pxe_blksize = size;
> + }
> + else if (! grub_strcmp (args[0], "unload"))
> + {
> + grub_pxe_unload ();
> + }
> +
> + return 0;
> +}
> +
> +GRUB_MOD_INIT(pxecmd)
> +{
> + (void) mod; /* To stop warning. */
> + grub_register_command ("pxe", grub_cmd_pxe, GRUB_COMMAND_FLAG_BOTH,
> + "pxe info | blksize size | unload",
> + "Show information about PXE.", 0);
> +}
> +
> +GRUB_MOD_FINI(pxecmd)
> +{
> + grub_unregister_command ("pxe");
> +}
> diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk
> index 8617a92..59fc6a3 100644
> --- a/conf/i386-pc.rmk
> +++ b/conf/i386-pc.rmk
> @@ -50,7 +50,8 @@ kernel_img_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
> env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
> partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
> machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \
> - machine/memory.h machine/loader.h machine/vga.h machine/vbe.h machine/kernel.h
> + machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \
> + machine/kernel.h machine/pxe.h
> kernel_img_CFLAGS = $(COMMON_CFLAGS)
> kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
> kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,$(GRUB_MEMORY_MACHINE_LINK_ADDR) $(COMMON_CFLAGS)
> @@ -158,7 +159,7 @@ pkglib_MODULES = biosdisk.mod _chain.mod _linux.mod linux.mod normal.mod \
> vbe.mod vbetest.mod vbeinfo.mod video.mod gfxterm.mod \
> videotest.mod play.mod bitmap.mod tga.mod cpuid.mod serial.mod \
> ata.mod vga.mod memdisk.mod jpeg.mod png.mod pci.mod lspci.mod \
> - aout.mod _bsd.mod bsd.mod
> + aout.mod _bsd.mod bsd.mod pxe.mod pxecmd.mod
>
> # For biosdisk.mod.
> biosdisk_mod_SOURCES = disk/i386/pc/biosdisk.c
> @@ -325,4 +326,14 @@ bsd_mod_SOURCES = loader/i386/bsd_normal.c
> bsd_mod_CFLAGS = $(COMMON_CFLAGS)
> bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
>
> +# For pxe.mod
> +pxe_mod_SOURCES = disk/i386/pc/pxe.c
> +pxe_mod_CFLAGS = $(COMMON_CFLAGS)
> +pxe_mod_LDFLAGS = $(COMMON_LDFLAGS)
> +
> +# For pxecmd.mod
> +pxecmd_mod_SOURCES = commands/i386/pc/pxecmd.c
> +pxecmd_mod_CFLAGS = $(COMMON_CFLAGS)
> +pxecmd_mod_LDFLAGS = $(COMMON_LDFLAGS)
> +
> include $(srcdir)/conf/common.mk
> diff --git a/disk/i386/pc/pxe.c b/disk/i386/pc/pxe.c
> new file mode 100644
> index 0000000..ced1088
> --- /dev/null
> +++ b/disk/i386/pc/pxe.c
> @@ -0,0 +1,335 @@
> +/* pxe.c - Driver to provide access to the pxe filesystem */
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2008 Free Software Foundation, Inc.
> + *
> + * GRUB 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 3 of the License, or
> + * (at your option) any later version.
> + *
> + * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <grub/dl.h>
> +#include <grub/fs.h>
> +#include <grub/mm.h>
> +#include <grub/disk.h>
> +#include <grub/file.h>
> +#include <grub/misc.h>
> +#include <grub/bufio.h>
> +
> +#include <grub/machine/pxe.h>
> +#include <grub/machine/memory.h>
> +
> +#define SEGMENT(x) ((x) >> 4)
> +#define OFFSET(x) ((x) & 0xF)
> +#define SEGOFS(x) ((SEGMENT(x) << 16) + OFFSET(x))
> +#define LINEAR(x) (void *) (((x >> 16) <<4) + (x & 0xFFFF))
> +
> +struct grub_pxenv *grub_pxe_pxenv;
> +grub_uint32_t grub_pxe_your_ip;
> +grub_uint32_t grub_pxe_server_ip;
> +grub_uint32_t grub_pxe_gateway_ip;
> +int grub_pxe_blksize = GRUB_PXE_MIN_BLKSIZE;
> +
> +struct grub_pxe_data
> +{
> + grub_uint32_t packet_number;
> + char filename[0];
> +};
> +
> +static int
> +grub_pxe_iterate (int (*hook) (const char *name))
> +{
> + if (hook ("pxe"))
> + return 1;
> + return 0;
> +}
> +
> +static grub_err_t
> +grub_pxe_open (const char *name, grub_disk_t disk)
> +{
> + if (grub_strcmp (name, "pxe"))
> + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a pxe disk");
> +
> + disk->total_sectors = 0;
> + disk->id = (unsigned long) "pxe";
> +
> + disk->has_partitions = 0;
> + disk->data = 0;
> +
> + return GRUB_ERR_NONE;
> +}
> +
> +static void
> +grub_pxe_close (grub_disk_t disk __attribute((unused)))
> +{
> +}
> +
> +static grub_err_t
> +grub_pxe_read (grub_disk_t disk __attribute((unused)),
> + grub_disk_addr_t sector __attribute((unused)),
> + grub_size_t size __attribute((unused)),
> + char *buf __attribute((unused)))
> +{
> + return GRUB_ERR_OUT_OF_RANGE;
> +}
> +
> +static grub_err_t
> +grub_pxe_write (grub_disk_t disk __attribute((unused)),
> + grub_disk_addr_t sector __attribute((unused)),
> + grub_size_t size __attribute((unused)),
> + const char *buf __attribute((unused)))
> +{
> + return GRUB_ERR_OUT_OF_RANGE;
> +}
> +
> +static struct grub_disk_dev grub_pxe_dev =
> + {
> + .name = "pxe",
> + .id = GRUB_DISK_DEVICE_PXE_ID,
> + .iterate = grub_pxe_iterate,
> + .open = grub_pxe_open,
> + .close = grub_pxe_close,
> + .read = grub_pxe_read,
> + .write = grub_pxe_write,
> + .next = 0
> + };
> +
> +static grub_err_t
> +grub_pxefs_dir (grub_device_t device __attribute((unused)),
> + const char *path __attribute((unused)),
> + int (*hook) (const char *filename, int dir) __attribute((unused)))
> +{
> + return GRUB_ERR_NONE;
> +}
> +
> +static struct grub_fs grub_pxefs_fs_int;
> +
> +static grub_err_t
> +grub_pxefs_open (struct grub_file *file, const char *name)
> +{
> + union
> + {
> + struct grub_pxenv_tftp_get_fsize c1;
> + struct grub_pxenv_tftp_open c2;
> + } c;
> + struct grub_pxe_data *data;
> + grub_file_t file_int, bufio;
> +
> + c.c1.server_ip = grub_pxe_server_ip;
> + c.c1.gateway_ip = grub_pxe_gateway_ip;
> + grub_strcpy (c.c1.filename, name);
> + grub_pxe_call (GRUB_PXENV_TFTP_GET_FSIZE, &c.c1);
> + if (c.c1.status)
> + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
> +
> + file->size = c.c1.file_size;
> +
> + c.c2.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
> + c.c2.packet_size = grub_pxe_blksize;
> + grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &c.c2);
> + if (c.c2.status)
> + return grub_error (GRUB_ERR_BAD_FS, "open fails");
> +
> + data = grub_malloc (sizeof (struct grub_pxe_data) + grub_strlen (name) + 1);
> + if (! data)
> + return grub_errno;
> +
> + data->packet_number = 0;
> + grub_strcpy (data->filename, name);
> +
> + file_int = grub_malloc (sizeof (*file_int));
> + if (! file_int)
> + {
> + grub_free (data);
> + return grub_errno;
> + }
> +
> + file_int->data = data;
> + file_int->offset = 0;
> + file_int->device = 0;
> + file_int->size = file->size;
> + file_int->read_hook = 0;
> + file_int->fs = &grub_pxefs_fs_int;
> +
> + bufio = grub_bufio_open (file_int, grub_pxe_blksize);
> + if (! bufio)
> + {
> + grub_free (file_int);
> + grub_free (data);
> + return grub_errno;
> + }
> +
> + file->data = bufio;
> +
> + return GRUB_ERR_NONE;
> +}
> +
> +static grub_ssize_t
> +grub_pxefs_read (grub_file_t file, char *buf, grub_size_t len)
> +{
> + grub_file_t bufio;
> +
> + bufio = file->data;
> + bufio->offset = file->offset;
> +
> + return bufio->fs->read (bufio, buf, len);
> +}
> +
> +static grub_ssize_t
> +grub_pxefs_close (grub_file_t file)
> +{
> + grub_file_close ((grub_file_t) file->data);
> +
> + return grub_errno;
> +}
> +
> +static grub_ssize_t
> +grub_pxefs_read_int (grub_file_t file, char *buf, grub_size_t len)
> +{
> + struct grub_pxenv_tftp_read c;
> + struct grub_pxe_data *data;
> + grub_uint32_t pn, r;
> +
> + data = file->data;
> +
> + pn = grub_divmod64 (file->offset, grub_pxe_blksize, &r);
> + if (r)
> + return grub_error (GRUB_ERR_BAD_FS,
> + "read access must be aligned to packet size");
> +
> + if (data->packet_number > pn)
> + {
> + struct grub_pxenv_tftp_open o;
> +
> + grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &o);
> +
> + o.server_ip = grub_pxe_server_ip;
> + o.gateway_ip = grub_pxe_gateway_ip;
> + grub_strcpy (o.filename, data->filename);
> + o.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
> + o.packet_size = grub_pxe_blksize;
> + grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &o);
> + if (o.status)
> + return grub_error (GRUB_ERR_BAD_FS, "open fails");
> + data->packet_number = 0;
> + }
> +
> + c.buffer = SEGOFS (GRUB_MEMORY_MACHINE_SCRATCH_ADDR);
> + while (pn >= data->packet_number)
> + {
> + c.buffer_size = grub_pxe_blksize;
> + grub_pxe_call (GRUB_PXENV_TFTP_READ, &c);
> + if (c.status)
> + {
> + grub_error (GRUB_ERR_BAD_FS, "read fails");
> + return -1;
> + }
> + data->packet_number++;
> + }
> +
> + grub_memcpy (buf, (char *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, len);
Is it save to use this memory?
> + return len;
> +}
> +
> +static grub_err_t
> +grub_pxefs_close_int (grub_file_t file)
> +{
> + struct grub_pxenv_tftp_close c;
> +
> + grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c);
> + grub_free (file->data);
> +
> + return GRUB_ERR_NONE;
> +}
> +
> +static grub_err_t
> +grub_pxefs_label (grub_device_t device __attribute ((unused)),
> + char **label __attribute ((unused)))
> +{
> + *label = 0;
> + return GRUB_ERR_NONE;
> +}
> +
> +static struct grub_fs grub_pxefs_fs =
> + {
> + .name = "pxefs",
> + .dir = grub_pxefs_dir,
> + .open = grub_pxefs_open,
> + .read = grub_pxefs_read,
> + .close = grub_pxefs_close,
> + .label = grub_pxefs_label,
> + .next = 0
> + };
> +
> +static struct grub_fs grub_pxefs_fs_int =
> + {
> + .name = "pxefs",
> + .read = grub_pxefs_read_int,
> + .close = grub_pxefs_close_int,
> + };
> +
> +static void
> +grub_pxe_detect (void)
> +{
> + struct grub_pxenv *pxenv;
> + struct grub_pxenv_get_cached_info ci;
> + struct grub_pxenv_boot_player *bp;
> +
> + pxenv = grub_pxe_scan ();
> + if (! pxenv)
> + return;
> +
> + ci.packet_type = GRUB_PXENV_PACKET_TYPE_DHCP_ACK;
> + ci.buffer = 0;
> + ci.buffer_size = 0;
> + grub_pxe_call (GRUB_PXENV_GET_CACHED_INFO, &ci);
> + if (ci.status)
> + return;
> +
> + bp = LINEAR (ci.buffer);
> +
> + grub_pxe_your_ip = bp->your_ip;
> + grub_pxe_server_ip = bp->server_ip;
> + grub_pxe_gateway_ip = bp->gateway_ip;
> +
> + grub_pxe_pxenv = pxenv;
> +}
> +
> +void
> +grub_pxe_unload (void)
> +{
> + if (grub_pxe_pxenv)
> + {
> + grub_fs_unregister (&grub_pxefs_fs);
> + grub_disk_dev_unregister (&grub_pxe_dev);
> +
> + grub_pxe_pxenv = 0;
> + }
> +}
> +
> +GRUB_MOD_INIT(pxe)
> +{
> + (void) mod; /* To stop warning. */
> +
> + grub_pxe_detect ();
> + if (grub_pxe_pxenv)
> + {
> + grub_disk_dev_register (&grub_pxe_dev);
> + grub_fs_register (&grub_pxefs_fs);
filesystems belong in fs/
> + }
> +}
> +
> +GRUB_MOD_FINI(pxe)
> +{
> + grub_pxe_unload ();
> +}
> diff --git a/include/grub/disk.h b/include/grub/disk.h
> index 0e27892..16765d0 100644
> --- a/include/grub/disk.h
> +++ b/include/grub/disk.h
> @@ -39,6 +39,7 @@ enum grub_disk_dev_id
> GRUB_DISK_DEVICE_MEMDISK_ID,
> GRUB_DISK_DEVICE_NAND_ID,
> GRUB_DISK_DEVICE_UUID_ID,
> + GRUB_DISK_DEVICE_PXE_ID,
> };
>
> struct grub_disk;
> diff --git a/include/grub/i386/pc/pxe.h b/include/grub/i386/pc/pxe.h
> new file mode 100755
> index 0000000..43fec80
> --- /dev/null
> +++ b/include/grub/i386/pc/pxe.h
> @@ -0,0 +1,318 @@
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2008 Free Software Foundation, Inc.
> + *
> + * GRUB 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 3 of the License, or
> + * (at your option) any later version.
> + *
> + * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef GRUB_CPU_PXE_H
> +#define GRUB_CPU_PXE_H
> +
> +#include <grub/types.h>
> +
> +#define GRUB_PXENV_TFTP_OPEN 0x0020
> +#define GRUB_PXENV_TFTP_CLOSE 0x0021
> +#define GRUB_PXENV_TFTP_READ 0x0022
> +#define GRUB_PXENV_TFTP_READ_FILE 0x0023
> +#define GRUB_PXENV_TFTP_READ_FILE_PMODE 0x0024
> +#define GRUB_PXENV_TFTP_GET_FSIZE 0x0025
> +
> +#define GRUB_PXENV_UDP_OPEN 0x0030
> +#define GRUB_PXENV_UDP_CLOSE 0x0031
> +#define GRUB_PXENV_UDP_READ 0x0032
> +#define GRUB_PXENV_UDP_WRITE 0x0033
> +
> +#define GRUB_PXENV_START_UNDI 0x0000
> +#define GRUB_PXENV_UNDI_STARTUP 0x0001
> +#define GRUB_PXENV_UNDI_CLEANUP 0x0002
> +#define GRUB_PXENV_UNDI_INITIALIZE 0x0003
> +#define GRUB_PXENV_UNDI_RESET_NIC 0x0004
> +#define GRUB_PXENV_UNDI_SHUTDOWN 0x0005
> +#define GRUB_PXENV_UNDI_OPEN 0x0006
> +#define GRUB_PXENV_UNDI_CLOSE 0x0007
> +#define GRUB_PXENV_UNDI_TRANSMIT 0x0008
> +#define GRUB_PXENV_UNDI_SET_MCAST_ADDR 0x0009
> +#define GRUB_PXENV_UNDI_SET_STATION_ADDR 0x000A
> +#define GRUB_PXENV_UNDI_SET_PACKET_FILTER 0x000B
> +#define GRUB_PXENV_UNDI_GET_INFORMATION 0x000C
> +#define GRUB_PXENV_UNDI_GET_STATISTICS 0x000D
> +#define GRUB_PXENV_UNDI_CLEAR_STATISTICS 0x000E
> +#define GRUB_PXENV_UNDI_INITIATE_DIAGS 0x000F
> +#define GRUB_PXENV_UNDI_FORCE_INTERRUPT 0x0010
> +#define GRUB_PXENV_UNDI_GET_MCAST_ADDR 0x0011
> +#define GRUB_PXENV_UNDI_GET_NIC_TYPE 0x0012
> +#define GRUB_PXENV_UNDI_GET_IFACE_INFO 0x0013
> +#define GRUB_PXENV_UNDI_ISR 0x0014
> +#define GRUB_PXENV_STOP_UNDI 0x0015
> +#define GRUB_PXENV_UNDI_GET_STATE 0x0015
> +
> +#define GRUB_PXENV_UNLOAD_STACK 0x0070
> +#define GRUB_PXENV_GET_CACHED_INFO 0x0071
> +#define GRUB_PXENV_RESTART_DHCP 0x0072
> +#define GRUB_PXENV_RESTART_TFTP 0x0073
> +#define GRUB_PXENV_MODE_SWITCH 0x0074
> +#define GRUB_PXENV_START_BASE 0x0075
> +#define GRUB_PXENV_STOP_BASE 0x0076
> +
> +#define GRUB_PXENV_EXIT_SUCCESS 0x0000
> +#define GRUB_PXENV_EXIT_FAILURE 0x0001
> +
> +#define GRUB_PXENV_STATUS_SUCCESS 0x00
> +#define GRUB_PXENV_STATUS_FAILURE 0x01
> +#define GRUB_PXENV_STATUS_BAD_FUNC 0x02
> +#define GRUB_PXENV_STATUS_UNSUPPORTED 0x03
> +#define GRUB_PXENV_STATUS_KEEP_UNDI 0x04
> +#define GRUB_PXENV_STATUS_KEEP_ALL 0x05
> +#define GRUB_PXENV_STATUS_OUT_OF_RESOURCES 0x06
> +#define GRUB_PXENV_STATUS_ARP_TIMEOUT 0x11
> +#define GRUB_PXENV_STATUS_UDP_CLOSED 0x18
> +#define GRUB_PXENV_STATUS_UDP_OPEN 0x19
> +#define GRUB_PXENV_STATUS_TFTP_CLOSED 0x1A
> +#define GRUB_PXENV_STATUS_TFTP_OPEN 0x1B
> +#define GRUB_PXENV_STATUS_MCOPY_PROBLEM 0x20
> +#define GRUB_PXENV_STATUS_BIS_INTEGRITY_FAILURE 0x21
> +#define GRUB_PXENV_STATUS_BIS_VALIDATE_FAILURE 0x22
> +#define GRUB_PXENV_STATUS_BIS_INIT_FAILURE 0x23
> +#define GRUB_PXENV_STATUS_BIS_SHUTDOWN_FAILURE 0x24
> +#define GRUB_PXENV_STATUS_BIS_GBOA_FAILURE 0x25
> +#define GRUB_PXENV_STATUS_BIS_FREE_FAILURE 0x26
> +#define GRUB_PXENV_STATUS_BIS_GSI_FAILURE 0x27
> +#define GRUB_PXENV_STATUS_BIS_BAD_CKSUM 0x28
> +#define GRUB_PXENV_STATUS_TFTP_CANNOT_ARP_ADDRESS 0x30
> +#define GRUB_PXENV_STATUS_TFTP_OPEN_TIMEOUT 0x32
> +
> +#define GRUB_PXENV_STATUS_TFTP_UNKNOWN_OPCODE 0x33
> +#define GRUB_PXENV_STATUS_TFTP_READ_TIMEOUT 0x35
> +#define GRUB_PXENV_STATUS_TFTP_ERROR_OPCODE 0x36
> +#define GRUB_PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION 0x38
> +#define GRUB_PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION 0x39
> +#define GRUB_PXENV_STATUS_TFTP_TOO_MANY_PACKAGES 0x3A
> +#define GRUB_PXENV_STATUS_TFTP_FILE_NOT_FOUND 0x3B
> +#define GRUB_PXENV_STATUS_TFTP_ACCESS_VIOLATION 0x3C
> +#define GRUB_PXENV_STATUS_TFTP_NO_MCAST_ADDRESS 0x3D
> +#define GRUB_PXENV_STATUS_TFTP_NO_FILESIZE 0x3E
> +#define GRUB_PXENV_STATUS_TFTP_INVALID_PACKET_SIZE 0x3F
> +#define GRUB_PXENV_STATUS_DHCP_TIMEOUT 0x51
> +#define GRUB_PXENV_STATUS_DHCP_NO_IP_ADDRESS 0x52
> +#define GRUB_PXENV_STATUS_DHCP_NO_BOOTFILE_NAME 0x53
> +#define GRUB_PXENV_STATUS_DHCP_BAD_IP_ADDRESS 0x54
> +#define GRUB_PXENV_STATUS_UNDI_INVALID_FUNCTION 0x60
> +#define GRUB_PXENV_STATUS_UNDI_MEDIATEST_FAILED 0x61
> +#define GRUB_PXENV_STATUS_UNDI_CANNOT_INIT_NIC_FOR_MCAST 0x62
> +#define GRUB_PXENV_STATUS_UNDI_CANNOT_INITIALIZE_NIC 0x63
> +#define GRUB_PXENV_STATUS_UNDI_CANNOT_INITIALIZE_PHY 0x64
> +#define GRUB_PXENV_STATUS_UNDI_CANNOT_READ_CONFIG_DATA 0x65
> +#define GRUB_PXENV_STATUS_UNDI_CANNOT_READ_INIT_DATA 0x66
> +#define GRUB_PXENV_STATUS_UNDI_BAD_MAC_ADDRESS 0x67
> +#define GRUB_PXENV_STATUS_UNDI_BAD_EEPROM_CHECKSUM 0x68
> +#define GRUB_PXENV_STATUS_UNDI_ERROR_SETTING_ISR 0x69
> +#define GRUB_PXENV_STATUS_UNDI_INVALID_STATE 0x6A
> +#define GRUB_PXENV_STATUS_UNDI_TRANSMIT_ERROR 0x6B
> +#define GRUB_PXENV_STATUS_UNDI_INVALID_PARAMETER 0x6C
> +#define GRUB_PXENV_STATUS_BSTRAP_PROMPT_MENU 0x74
> +#define GRUB_PXENV_STATUS_BSTRAP_MCAST_ADDR 0x76
> +#define GRUB_PXENV_STATUS_BSTRAP_MISSING_LIST 0x77
> +#define GRUB_PXENV_STATUS_BSTRAP_NO_RESPONSE 0x78
> +#define GRUB_PXENV_STATUS_BSTRAP_FILE_TOO_BIG 0x79
> +#define GRUB_PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE 0xA0
> +#define GRUB_PXENV_STATUS_BINL_NO_PXE_SERVER 0xA1
> +#define GRUB_PXENV_STATUS_NOT_AVAILABLE_IN_PMODE 0xA2
> +#define GRUB_PXENV_STATUS_NOT_AVAILABLE_IN_RMODE 0xA3
> +#define GRUB_PXENV_STATUS_BUSD_DEVICE_NOT_SUPPORTED 0xB0
> +#define GRUB_PXENV_STATUS_LOADER_NO_FREE_BASE_MEMORY 0xC0
> +#define GRUB_PXENV_STATUS_LOADER_NO_BC_ROMID 0xC1
> +#define GRUB_PXENV_STATUS_LOADER_BAD_BC_ROMID 0xC2
> +#define GRUB_PXENV_STATUS_LOADER_BAD_BC_RUNTIME_IMAGE 0xC3
> +#define GRUB_PXENV_STATUS_LOADER_NO_UNDI_ROMID 0xC4
> +#define GRUB_PXENV_STATUS_LOADER_BAD_UNDI_ROMID 0xC5
> +#define GRUB_PXENV_STATUS_LOADER_BAD_UNDI_DRIVER_IMAGE 0xC6
> +#define GRUB_PXENV_STATUS_LOADER_NO_PXE_STRUCT 0xC8
> +#define GRUB_PXENV_STATUS_LOADER_NO_PXENV_STRUCT 0xC9
> +#define GRUB_PXENV_STATUS_LOADER_UNDI_START 0xCA
> +#define GRUB_PXENV_STATUS_LOADER_BC_START 0xCB
> +
> +#define GRUB_PXENV_PACKET_TYPE_DHCP_DISCOVER 1
> +#define GRUB_PXENV_PACKET_TYPE_DHCP_ACK 2
> +#define GRUB_PXENV_PACKET_TYPE_CACHED_REPLY 3
> +
> +#define GRUB_PXE_BOOTP_REQ 1
> +#define GRUB_PXE_BOOTP_REP 2
> +
> +#define GRUB_PXE_BOOTP_BCAST 0x8000
> +
> +#if 1
> +#define GRUB_PXE_BOOTP_DHCPVEND 1024 /* DHCP extended vendor field size */
> +#else
> +#define GRUB_PXE_BOOTP_DHCPVEND 312 /* DHCP standard vendor field size */
> +#endif
> +
> +#define GRUB_PXE_MIN_BLKSIZE 512
> +#define GRUB_PXE_MAX_BLKSIZE 1432
> +
> +#define GRUB_PXE_TFTP_PORT 69
> +
> +#define GRUB_PXE_VM_RFC1048 0x63825363L
> +
> +#define GRUB_PXE_ERR_LEN 0xFFFFFFFF
> +
> +#ifndef ASM_FILE
> +
> +struct grub_pxenv
> +{
> + grub_uint8_t signature[6]; /* 'PXENV+' */
> + grub_uint16_t version; /* MSB = major, LSB = minor */
> + grub_uint8_t length; /* structure length */
> + grub_uint8_t checksum; /* checksum pad */
> + grub_uint32_t rm_entry; /* SEG:OFF to PXE entry point */
> + grub_uint32_t pm_offset; /* Protected mode entry */
> + grub_uint16_t pm_selector; /* Protected mode selector */
> + grub_uint16_t stack_seg; /* Stack segment address */
> + grub_uint16_t stack_size; /* Stack segment size (bytes) */
> + grub_uint16_t bc_code_seg; /* BC Code segment address */
> + grub_uint16_t bc_code_size; /* BC Code segment size (bytes) */
> + grub_uint16_t bc_data_seg; /* BC Data segment address */
> + grub_uint16_t bc_data_size; /* BC Data segment size (bytes) */
> + grub_uint16_t undi_data_seg; /* UNDI Data segment address */
> + grub_uint16_t undi_data_size; /* UNDI Data segment size (bytes) */
> + grub_uint16_t undi_code_seg; /* UNDI Code segment address */
> + grub_uint16_t undi_code_size; /* UNDI Code segment size (bytes) */
> + grub_uint32_t pxe_ptr; /* SEG:OFF to !PXE struct */
> +} __attribute__ ((packed));
Can you GRUB-ify the comments here and below a bit?
> +struct grub_pxenv_get_cached_info
> +{
> + grub_uint16_t status;
> + grub_uint16_t packet_type;
> + grub_uint16_t buffer_size;
> + grub_uint32_t buffer;
> + grub_uint16_t buffer_limit;
> +} __attribute__ ((packed));
> +
> +#define GRUB_PXE_MAC_ADDR_LEN 16
> +
> +typedef grub_uint8_t grub_pxe_mac_addr[GRUB_PXE_MAC_ADDR_LEN];
Please don't use a tab here.
> +struct grub_pxenv_boot_player
> +{
> + grub_uint8_t opcode;
> + grub_uint8_t hw_type; /* hardware type */
> + grub_uint8_t hw_len; /* hardware addr len */
> + grub_uint8_t gate_hops; /* zero it */
> + grub_uint32_t ident; /* random number chosen by client */
> + grub_uint16_t seconds; /* seconds since did initial bootstrap */
> + grub_uint16_t flags;
> + grub_uint32_t client_ip;
> + grub_uint32_t your_ip;
> + grub_uint32_t server_ip;
> + grub_uint32_t gateway_ip;
> + grub_pxe_mac_addr mac_addr;
> + grub_uint8_t server_name[64];
> + grub_uint8_t boot_file[128];
> + union
> + {
> + grub_uint8_t d[GRUB_PXE_BOOTP_DHCPVEND]; /* raw array of vendor/dhcp options */
> + struct
> + {
> + grub_uint32_t magic; /* DHCP magic cookie */
> + grub_uint32_t flags; /* bootp flags/opcodes */
> + grub_uint8_t padding[56];
> + } v;
> + } vendor;
> +} __attribute__ ((packed));
> +
> +struct grub_pxenv_tftp_open
> +{
> + grub_uint16_t status;
> + grub_uint32_t server_ip;
> + grub_uint32_t gateway_ip;
> + grub_uint8_t filename[128];
> + grub_uint16_t tftp_port;
> + grub_uint16_t packet_size;
> +} __attribute__ ((packed));
> +
> +struct grub_pxenv_tftp_close
> +{
> + grub_uint16_t status;
> +} __attribute__ ((packed));
> +
> +struct grub_pxenv_tftp_read
> +{
> + grub_uint16_t status;
> + grub_uint16_t packet_number;
> + grub_uint16_t buffer_size;
> + grub_uint32_t buffer;
> +} __attribute__ ((packed));
> +
> +struct grub_pxenv_tftp_get_fsize
> +{
> + grub_uint16_t status;
> + grub_uint32_t server_ip;
> + grub_uint32_t gateway_ip;
> + grub_uint8_t filename[128];
> + grub_uint32_t file_size;
> +} __attribute__ ((packed));
> +
> +struct grub_pxenv_udp_open
> +{
> + grub_uint16_t status;
> + grub_uint32_t src_ip;
> +} __attribute__ ((packed));
> +
> +struct grub_pxenv_udp_close
> +{
> + grub_uint16_t status;
> +} __attribute__ ((packed));
> +
> +struct grub_pxenv_udp_write
> +{
> + grub_uint16_t status;
> + grub_uint32_t ip;
> + grub_uint32_t gateway;
> + grub_uint16_t src_port;
> + grub_uint16_t dst_port;
> + grub_uint16_t buffer_size;
> + grub_uint32_t buffer;
> +} __attribute__ ((packed));
> +
> +struct grub_pxenv_udp_read
> +{
> + grub_uint16_t status;
> + grub_uint32_t src_ip;
> + grub_uint32_t dst_ip;
> + grub_uint16_t src_port;
> + grub_uint16_t dst_port;
> + grub_uint16_t buffer_size;
> + grub_uint32_t buffer;
> +} __attribute__ ((packed));
> +
> +struct grub_pxenv_unload_stack
> +{
> + grub_uint16_t status;
> + grub_uint8_t reserved[10];
> +} __attribute__ ((packed));
> +
> +struct grub_pxenv * EXPORT_FUNC(grub_pxe_scan) (void);
> +int EXPORT_FUNC(grub_pxe_call) (int func, void * data);
> +
> +extern struct grub_pxenv *grub_pxe_pxenv;
> +extern grub_uint32_t grub_pxe_your_ip;
> +extern grub_uint32_t grub_pxe_server_ip;
> +extern grub_uint32_t grub_pxe_gateway_ip;
> +extern int grub_pxe_blksize;
> +
> +void grub_pxe_unload (void);
> +
> +#endif
> +
> +#endif /* GRUB_CPU_PXE_H */
> diff --git a/kern/i386/pc/init.c b/kern/i386/pc/init.c
> index e47cbfd..646545e 100644
> --- a/kern/i386/pc/init.c
> +++ b/kern/i386/pc/init.c
> @@ -71,14 +71,19 @@ make_install_device (void)
> if (grub_root_drive == 0xFF)
> grub_root_drive = grub_boot_drive;
>
> - grub_sprintf (dev, "(%cd%u", (grub_root_drive & 0x80) ? 'h' : 'f',
> - grub_root_drive & 0x7f);
> + if (grub_root_drive == 0x7F)
> + grub_strcpy (dev, "(pxe");
> + else
> + {
> + grub_sprintf (dev, "(%cd%u", (grub_root_drive & 0x80) ? 'h' : 'f',
> + grub_root_drive & 0x7f);
>
> - if (grub_install_dos_part >= 0)
> - grub_sprintf (dev + grub_strlen (dev), ",%u", grub_install_dos_part + 1);
> + if (grub_install_dos_part >= 0)
> + grub_sprintf (dev + grub_strlen (dev), ",%u", grub_install_dos_part + 1);
>
> - if (grub_install_bsd_part >= 0)
> - grub_sprintf (dev + grub_strlen (dev), ",%c", grub_install_bsd_part + 'a');
> + if (grub_install_bsd_part >= 0)
> + grub_sprintf (dev + grub_strlen (dev), ",%c", grub_install_bsd_part + 'a');
> + }
>
> grub_sprintf (dev + grub_strlen (dev), ")%s", grub_prefix);
> grub_strcpy (grub_prefix, dev);
> diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S
> index 75c46ad..679ad1f 100644
> --- a/kern/i386/pc/startup.S
> +++ b/kern/i386/pc/startup.S
> @@ -2053,3 +2053,102 @@ FUNCTION(grub_vbe_bios_set_palette_data)
> popl %ebx
> popl %ebp
> ret
> +
> +
> +pxe_rm_entry:
> + .long 0
> +
> +/*
> + * struct grub_pxenv *grub_pxe_scan (void);
> + */
> +FUNCTION(grub_pxe_scan)
> + pushl %ebp
> + pushl %ebx
> +
> + xorl %ebx, %ebx
> + xorl %ecx, %ecx
> +
> + call prot_to_real
> + .code16
> +
> + pushw %es
> +
> + movw $0x5650, %ax
> + int $0x1A
> + cmpw $0x564E, %ax
> + jnz 1f
> + cmpl $0x4E455850, %es:(%bx) /* PXEN(V+) */
> + jnz 1f
> + cmpw $0x201, %es:6(%bx) /* API version */
> + jb 1f
> + lesw %es:0x28(%bx), %bx /* !PXE structure */
> + cmpl $0x45585021, %es:(%bx) /* !PXE */
> + jnz 1f
> + movw %es, %cx
> + jmp 2f
> +1:
> + xorw %bx, %bx
> + xorw %cx, %cx
> +2:
> +
> + popw %es
> +
> + DATA32 call real_to_prot
> + .code32
> +
> + xorl %eax, %eax
> + leal (%eax, %ecx, 4), %ecx
> + leal (%ebx, %ecx, 4), %eax /* eax = ecx * 16 + ebx */
> +
> + orl %eax, %eax
> + jz 1f
> +
> + movl 0x10(%eax), %ecx
> + movl %ecx, pxe_rm_entry
> +
> +1:
> +
> + popl %ebx
> + popl %ebp
> + ret
> +
> +/*
> + * int grub_pxe_call (int func, void* data);
> + */
> +FUNCTION(grub_pxe_call)
> + pushl %ebp
> + movl %esp, %ebp
> + pushl %esi
> + pushl %edi
> + pushl %ebx
> +
> + movl %eax, %ecx
> + movl %edx, %eax
> + andl $0xF, %eax
> + shrl $4, %edx
> + shll $16, %edx
> + addl %eax, %edx
> + movl pxe_rm_entry, %ebx
> +
> + call prot_to_real
> + .code16
> +
> + pushl %ebx
> + pushl %edx
> + pushw %cx
> + movw %sp, %bx
> + lcall *%ss:6(%bx)
> + cld
> + addw $10, %sp
> + movw %ax, %cx
> +
> + DATA32 call real_to_prot
> + .code32
> +
> + movzwl %cx, %eax
> +
> + popl %ebx
> + popl %edi
> + popl %esi
> + popl %ebp
> + ret
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH] PXE support for grub2
2008-08-04 21:08 ` Marco Gerards
@ 2008-08-05 3:36 ` Bean
2008-08-05 8:16 ` Marco Gerards
0 siblings, 1 reply; 15+ messages in thread
From: Bean @ 2008-08-05 3:36 UTC (permalink / raw)
To: The development of GRUB 2
On Tue, Aug 5, 2008 at 5:08 AM, Marco Gerards <mgerards@xs4all.nl> wrote:
> Actually, I would prefer:
>
> pxe --info
>
> pxe --blksize=size
>
> pxe --unload
>
> You kinda reimplemented an argument parser. The advantage of the
> build in argument parser is that it supports generation of --help
> documentation and it supports tab completion.
Ok.
>>
>> /* Root drive will default to boot drive */
>> - movb $0xFF, %dh
>> + movb $0xFF, %dh
>> + movb $0x7F, %dl
>
> Please update the copyright year of files you change. IIRC this file
> is not from this year. I often forget to mention this, but it applies
> in general.
>
>
Oh, I forget that.
>> + c.buffer = SEGOFS (GRUB_MEMORY_MACHINE_SCRATCH_ADDR);
>> + while (pn >= data->packet_number)
>> + {
>> + c.buffer_size = grub_pxe_blksize;
>> + grub_pxe_call (GRUB_PXENV_TFTP_READ, &c);
>> + if (c.status)
>> + {
>> + grub_error (GRUB_ERR_BAD_FS, "read fails");
>> + return -1;
>> + }
>> + data->packet_number++;
>> + }
>> +
>> + grub_memcpy (buf, (char *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, len);
>
> Is it save to use this memory?
>
This is only used by the real mode service. Once the data is
retrieved, it's copied to another buffer.
>> +GRUB_MOD_INIT(pxe)
>> +{
>> + (void) mod; /* To stop warning. */
>> +
>> + grub_pxe_detect ();
>> + if (grub_pxe_pxenv)
>> + {
>> + grub_disk_dev_register (&grub_pxe_dev);
>> + grub_fs_register (&grub_pxefs_fs);
>
> filesystems belong in fs/
Perhaps I should place it in fs/i386/pc ?
>> +struct grub_pxenv
>> +{
>> + grub_uint8_t signature[6]; /* 'PXENV+' */
>> + grub_uint16_t version; /* MSB = major, LSB = minor */
>> + grub_uint8_t length; /* structure length */
>> + grub_uint8_t checksum; /* checksum pad */
>> + grub_uint32_t rm_entry; /* SEG:OFF to PXE entry point */
>> + grub_uint32_t pm_offset; /* Protected mode entry */
>> + grub_uint16_t pm_selector; /* Protected mode selector */
>> + grub_uint16_t stack_seg; /* Stack segment address */
>> + grub_uint16_t stack_size; /* Stack segment size (bytes) */
>> + grub_uint16_t bc_code_seg; /* BC Code segment address */
>> + grub_uint16_t bc_code_size; /* BC Code segment size (bytes) */
>> + grub_uint16_t bc_data_seg; /* BC Data segment address */
>> + grub_uint16_t bc_data_size; /* BC Data segment size (bytes) */
>> + grub_uint16_t undi_data_seg; /* UNDI Data segment address */
>> + grub_uint16_t undi_data_size; /* UNDI Data segment size (bytes) */
>> + grub_uint16_t undi_code_seg; /* UNDI Code segment address */
>> + grub_uint16_t undi_code_size; /* UNDI Code segment size (bytes) */
>> + grub_uint32_t pxe_ptr; /* SEG:OFF to !PXE struct */
>> +} __attribute__ ((packed));
>
> Can you GRUB-ify the comments here and below a bit?
What do you mean by "GRUB-ify the comments" ?
--
Bean
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH] PXE support for grub2
2008-08-05 3:36 ` Bean
@ 2008-08-05 8:16 ` Marco Gerards
2008-08-05 15:15 ` Bean
0 siblings, 1 reply; 15+ messages in thread
From: Marco Gerards @ 2008-08-05 8:16 UTC (permalink / raw)
To: The development of GRUB 2
Bean <bean123ch@gmail.com> writes:
>>> +GRUB_MOD_INIT(pxe)
>>> +{
>>> + (void) mod; /* To stop warning. */
>>> +
>>> + grub_pxe_detect ();
>>> + if (grub_pxe_pxenv)
>>> + {
>>> + grub_disk_dev_register (&grub_pxe_dev);
>>> + grub_fs_register (&grub_pxefs_fs);
>>
>> filesystems belong in fs/
>
> Perhaps I should place it in fs/i386/pc ?
I think it would make things clearer, although I am not too sure :-)
>>> +struct grub_pxenv
>>> +{
>>> + grub_uint8_t signature[6]; /* 'PXENV+' */
>>> + grub_uint16_t version; /* MSB = major, LSB = minor */
>>> + grub_uint8_t length; /* structure length */
>>> + grub_uint8_t checksum; /* checksum pad */
>>> + grub_uint32_t rm_entry; /* SEG:OFF to PXE entry point */
>>> + grub_uint32_t pm_offset; /* Protected mode entry */
>>> + grub_uint16_t pm_selector; /* Protected mode selector */
>>> + grub_uint16_t stack_seg; /* Stack segment address */
>>> + grub_uint16_t stack_size; /* Stack segment size (bytes) */
>>> + grub_uint16_t bc_code_seg; /* BC Code segment address */
>>> + grub_uint16_t bc_code_size; /* BC Code segment size (bytes) */
>>> + grub_uint16_t bc_data_seg; /* BC Data segment address */
>>> + grub_uint16_t bc_data_size; /* BC Data segment size (bytes) */
>>> + grub_uint16_t undi_data_seg; /* UNDI Data segment address */
>>> + grub_uint16_t undi_data_size; /* UNDI Data segment size (bytes) */
>>> + grub_uint16_t undi_code_seg; /* UNDI Code segment address */
>>> + grub_uint16_t undi_code_size; /* UNDI Code segment size (bytes) */
>>> + grub_uint32_t pxe_ptr; /* SEG:OFF to !PXE struct */
>>> +} __attribute__ ((packed));
>>
>> Can you GRUB-ify the comments here and below a bit?
>
> What do you mean by "GRUB-ify the comments" ?
". */
Although it is not too important for structs, I think :-)
--
Marco
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH] PXE support for grub2
2008-08-05 8:16 ` Marco Gerards
@ 2008-08-05 15:15 ` Bean
2008-08-06 6:18 ` Bean
0 siblings, 1 reply; 15+ messages in thread
From: Bean @ 2008-08-05 15:15 UTC (permalink / raw)
To: The development of GRUB 2
On Tue, Aug 5, 2008 at 4:16 PM, Marco Gerards <mgerards@xs4all.nl> wrote:
> Bean <bean123ch@gmail.com> writes:
>
>>>> +GRUB_MOD_INIT(pxe)
>>>> +{
>>>> + (void) mod; /* To stop warning. */
>>>> +
>>>> + grub_pxe_detect ();
>>>> + if (grub_pxe_pxenv)
>>>> + {
>>>> + grub_disk_dev_register (&grub_pxe_dev);
>>>> + grub_fs_register (&grub_pxefs_fs);
>>>
>>> filesystems belong in fs/
>>
>> Perhaps I should place it in fs/i386/pc ?
>
> I think it would make things clearer, although I am not too sure :-)
>
>>>> +struct grub_pxenv
>>>> +{
>>>> + grub_uint8_t signature[6]; /* 'PXENV+' */
>>>> + grub_uint16_t version; /* MSB = major, LSB = minor */
>>>> + grub_uint8_t length; /* structure length */
>>>> + grub_uint8_t checksum; /* checksum pad */
>>>> + grub_uint32_t rm_entry; /* SEG:OFF to PXE entry point */
>>>> + grub_uint32_t pm_offset; /* Protected mode entry */
>>>> + grub_uint16_t pm_selector; /* Protected mode selector */
>>>> + grub_uint16_t stack_seg; /* Stack segment address */
>>>> + grub_uint16_t stack_size; /* Stack segment size (bytes) */
>>>> + grub_uint16_t bc_code_seg; /* BC Code segment address */
>>>> + grub_uint16_t bc_code_size; /* BC Code segment size (bytes) */
>>>> + grub_uint16_t bc_data_seg; /* BC Data segment address */
>>>> + grub_uint16_t bc_data_size; /* BC Data segment size (bytes) */
>>>> + grub_uint16_t undi_data_seg; /* UNDI Data segment address */
>>>> + grub_uint16_t undi_data_size; /* UNDI Data segment size (bytes) */
>>>> + grub_uint16_t undi_code_seg; /* UNDI Code segment address */
>>>> + grub_uint16_t undi_code_size; /* UNDI Code segment size (bytes) */
>>>> + grub_uint32_t pxe_ptr; /* SEG:OFF to !PXE struct */
>>>> +} __attribute__ ((packed));
>>>
>>> Can you GRUB-ify the comments here and below a bit?
>>
>> What do you mean by "GRUB-ify the comments" ?
>
> ". */
>
> Although it is not too important for structs, I think :-)
Fixed and committed.
--
Bean
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2008-08-06 6:18 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-30 16:50 [PATCH] PXE support for grub2 Bean
2008-08-01 3:46 ` Bean
2008-08-01 3:52 ` Pavel Roskin
2008-08-01 11:32 ` Robert Millan
2008-08-01 16:21 ` Pavel Roskin
2008-08-01 16:59 ` Bean
2008-08-02 4:34 ` Bean
2008-08-02 10:48 ` Robert Millan
2008-08-02 11:20 ` Bean
2008-08-02 11:49 ` Robert Millan
2008-08-04 21:08 ` Marco Gerards
2008-08-05 3:36 ` Bean
2008-08-05 8:16 ` Marco Gerards
2008-08-05 15:15 ` Bean
2008-08-06 6:18 ` Bean
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.