* question about adding a field into linux boot header
@ 2011-03-24 8:12 GuoMinskey
2011-03-24 8:35 ` Vladimir 'φ-coder/phcoder' Serbinenko
0 siblings, 1 reply; 3+ messages in thread
From: GuoMinskey @ 2011-03-24 8:12 UTC (permalink / raw)
To: grub-devel
[-- Attachment #1: Type: text/plain, Size: 1317 bytes --]
I want to use setup_data fields of linux boot header, but grub doesn'tsupport it. So, I cone latest grub repo (1.99) and modify grub code asfollows:
1. in include/grub/i386/linux.h,
struct linux_kernel_header {@@ -130,6 +144,8 @@ grub_uint16_t pad1; /* Unused */ grub_uint32_t cmd_line_ptr; /* Points to the kernel command line */ grub_uint32_t initrd_addr_max; /* Highest address for initrd */+ grub_uint32_t pad2[8];+ grub_uint64_t new_field; <-------------- aligned to the offset : 0x250 as linux } __attribute__ ((packed));
2. grub-core/loader/i386/linux.c
I add a command by following "initrd", but simply as follows:
static grub_err_t grub_cmd_test(cmd, argc, argv[]) { grub_printf("entering my test command\n");
... //ensure kernel is loaded struct linux_kernel_header *lh = (struct linux_kernel_header *) real_mode_mem; lh->new_field = 0x34FFFFFF; } when I boot GRUB with my command, GRUB panic in relocator. I print the kernelheader, seems the header is there ( I mean real_mode_mem). If I removed the line"lh->new_field = 0x34FFFFFF", GRUB can work.
Did I miss something if I want pass this field into linux kernel ?
thanks,-minskey
[-- Attachment #2: Type: text/html, Size: 6177 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: question about adding a field into linux boot header
2011-03-24 8:12 question about adding a field into linux boot header GuoMinskey
@ 2011-03-24 8:35 ` Vladimir 'φ-coder/phcoder' Serbinenko
0 siblings, 0 replies; 3+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2011-03-24 8:35 UTC (permalink / raw)
To: grub-devel
[-- Attachment #1: Type: text/plain, Size: 1981 bytes --]
On 24.03.2011 09:12, GuoMinskey wrote:
>
>
> I want to use setup_data fields of linux boot header, but grub doesn't
> support it. So, I cone latest grub repo (1.99) and modify grub code as
> follows:
>
>
> 1. in include/grub/i386/linux.h,
>
> struct linux_kernel_header
> {
> @@ -130,6 +144,8 @@
> grub_uint16_t pad1; /* Unused */
> grub_uint32_t cmd_line_ptr; /* Points to the kernel command line */
> grub_uint32_t initrd_addr_max; /* Highest address for initrd */
> + grub_uint32_t pad2[8];
> + grub_uint64_t new_field; <-------------- aligned to the offset
> : 0x250 as linux
> } __attribute__ ((packed));
>
>
> 2. grub-core/loader/i386/linux.c
>
> I add a command by following "initrd", but simply as follows:
>
> static grub_err_t
> grub_cmd_test(cmd, argc, argv[])
> {
> grub_printf("entering my test command\n");
>
> ... //ensure kernel is loaded
>
> struct linux_kernel_header *lh = (struct
> linux_kernel_header *) real_mode_mem;
> lh->new_field = 0x34FFFFFF;
> }
>
Could you paste the whole code in question rather than let us gues what
happens in "..." or how you set your lh variable
>
> when I boot GRUB with my command, GRUB panic in relocator.
Could you please avoid paraphrasing and give exact error?
Also please try with debug=relocator and supply the output
> I print the kernel
> header, seems the header is there ( I mean real_mode_mem). If I
> removed the line
> "lh->new_field = 0x34FFFFFF", GRUB can work.
>
> Did I miss something if I want pass this field into linux kernel ?
>
>
> thanks,
> -minskey
>
>
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>
--
Regards
Vladimir 'φ-coder/phcoder' Serbinenko
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: question about adding a field into linux boot header
@ 2011-03-29 3:29 GuoMinskey
0 siblings, 0 replies; 3+ messages in thread
From: GuoMinskey @ 2011-03-29 3:29 UTC (permalink / raw)
To: phcoder, grub-devel
[-- Attachment #1.1: Type: text/plain, Size: 3618 bytes --]
thank you for response.
Sorry for the confusion. It was my fault. I just use qemu to debug my change.It is a kernel panic. It panic so early, so that I made a mistake and consideredit as a panic in grub.
I am using grub repo (revno: 3116). Now, I can see the kernel panic message: "PANIC: early exception 08 rip 246:10 error ffffff8102b785 cr2 ffffffffff47900b"The panic message comes from linux kernel: early_idt_handlers in the filearch/x86/kernel/head_64.S.
So, it doesn't matter with grub.
/* For the Linux/i386 boot protocol version 2.03. */ struct linux_kernel_header {@@ -130,6 +146,8 @@ grub_uint16_t pad1; /* Unused */ grub_uint32_t cmd_line_ptr; /* Points to the kernel command line */ grub_uint32_t initrd_addr_max; /* Highest address for initrd */+ grub_uint32_t pad2[8];+ grub_uint64_t setup_data; } __attribute__ ((packed));And then, I tried to use setup_data field to pass an pointer (which points to a binaryblob) to Linux kernel, === modified file 'grub-core/loader/i386/linux.c'--- grub-core/loader/i386/linux.c 2011-03-09 17:38:31 +0000+++ grub-core/loader/i386/linux.c 2011-03-28 15:44:34 +0000@@ -994,7 +994,89 @@ return grub_errno; }
-static grub_command_t cmd_linux, cmd_initrd;+static grub_err_t+grub_cmd_ucode (grub_command_t cmd __attribute__ ((unused)),+ int argc, char *argv[])+{+ grub_file_t file = 0;+ grub_ssize_t size;+ grub_addr_t addr_min, addr_max;+ grub_err_t err;+ struct linux_kernel_header *lh;+ grub_relocator_chunk_t ch;+ void *ucode_mem;+ grub_addr_t ucode_mem_target;+ struct setup_data *hdr;++ if (argc == 0)+ {+ grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");+ goto fail;+ }++ if (! loaded)+ {+ grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first");+ goto fail;+ }++ grub_file_filter_disable_compression ();+ file = grub_file_open (argv[0]);+ size = grub_file_size(file);++ lh = (struct linux_kernel_header *) real_mode_mem;+ if (grub_le_to_cpu16(lh->version) < 0x0209)+ {+ grub_printf("%s:%d: header version=0x%x(<0x0209)\n",+ __FUNCTION__, __LINE__, lh->version);+ goto fail;+ }++ addr_max = grub_cpu_to_le32(lh->initrd_addr_max);+ if (addr_max > GRUB_LINUX_INITRD_MAX_ADDRESS)+ addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;+ addr_max -= 0x10000;++ if ((linux_mem_size != 0) && (linux_mem_size < addr_max))+ addr_max = linux_mem_size;+ addr_max = (addr_max - size - sizeof(*hdr)) & ~0xFFF;+ addr_min = prot_mode_target;++ grub_printf("microcode addr_min=%p, add_max=%p\n", + (void*)addr_min, (void *)addr_max);++ err = grub_relocator_alloc_chunk_align(relocator, &ch, addr_min,+ addr_max, size + sizeof(*hdr),+ 0x1000, GRUB_RELOCATOR_PREFERENCE_HIGH);+ if (err) return err;+ ucode_mem = get_virtual_current_address(ch);+ ucode_mem_target = get_physical_target_address(ch);++ if (grub_file_read(file, (unsigned char*)ucode_mem + sizeof(*hdr), size) != size)+ {+ grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");+ goto fail;+ }++ hdr = (struct setup_data *)ucode_mem;+ hdr->type = SETUP_MICROCODE;+ hdr->len = size;+ hdr->next = 0;++ lh->setup_data = ucode_mem_target;++ grub_printf("%s: header_version=0x%x, ucode_size=%d\n", __FUNCTION__,+ grub_le_to_cpu16 (lh->version), size);+ ++ fail:+ if (file)+ grub_file_close (file);++ return grub_errno;+}++static grub_command_t cmd_linux, cmd_initrd, cmd_ucode;
thanks,-minskey
[-- Attachment #1.2: Type: text/html, Size: 24212 bytes --]
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: grub.diff --]
[-- Type: text/x-patch, Size: 4235 bytes --]
=== modified file 'grub-core/loader/i386/linux.c'
--- grub-core/loader/i386/linux.c 2011-03-09 17:38:31 +0000
+++ grub-core/loader/i386/linux.c 2011-03-28 15:44:34 +0000
@@ -994,7 +994,89 @@
return grub_errno;
}
-static grub_command_t cmd_linux, cmd_initrd;
+static grub_err_t
+grub_cmd_ucode (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char *argv[])
+{
+ grub_file_t file = 0;
+ grub_ssize_t size;
+ grub_addr_t addr_min, addr_max;
+ grub_err_t err;
+ struct linux_kernel_header *lh;
+ grub_relocator_chunk_t ch;
+ void *ucode_mem;
+ grub_addr_t ucode_mem_target;
+ struct setup_data *hdr;
+
+ if (argc == 0)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
+ goto fail;
+ }
+
+ if (! loaded)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first");
+ goto fail;
+ }
+
+ grub_file_filter_disable_compression ();
+ file = grub_file_open (argv[0]);
+ size = grub_file_size(file);
+
+ lh = (struct linux_kernel_header *) real_mode_mem;
+ if (grub_le_to_cpu16(lh->version) < 0x0209)
+ {
+ grub_printf("%s:%d: header version=0x%x(<0x0209)\n",
+ __FUNCTION__, __LINE__, lh->version);
+ goto fail;
+ }
+
+ addr_max = grub_cpu_to_le32(lh->initrd_addr_max);
+ if (addr_max > GRUB_LINUX_INITRD_MAX_ADDRESS)
+ addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
+ addr_max -= 0x10000;
+
+ if ((linux_mem_size != 0) && (linux_mem_size < addr_max))
+ addr_max = linux_mem_size;
+ addr_max = (addr_max - size - sizeof(*hdr)) & ~0xFFF;
+ addr_min = prot_mode_target;
+
+ grub_printf("microcode addr_min=%p, add_max=%p\n",
+ (void*)addr_min, (void *)addr_max);
+
+ err = grub_relocator_alloc_chunk_align(relocator, &ch, addr_min,
+ addr_max, size + sizeof(*hdr),
+ 0x1000, GRUB_RELOCATOR_PREFERENCE_HIGH);
+ if (err) return err;
+ ucode_mem = get_virtual_current_address(ch);
+ ucode_mem_target = get_physical_target_address(ch);
+
+ if (grub_file_read(file, (unsigned char*)ucode_mem + sizeof(*hdr), size) != size)
+ {
+ grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
+ goto fail;
+ }
+
+ hdr = (struct setup_data *)ucode_mem;
+ hdr->type = SETUP_MICROCODE;
+ hdr->len = size;
+ hdr->next = 0;
+
+ lh->setup_data = ucode_mem_target;
+
+ grub_printf("%s: header_version=0x%x, ucode_size=%d\n", __FUNCTION__,
+ grub_le_to_cpu16 (lh->version), size);
+
+
+ fail:
+ if (file)
+ grub_file_close (file);
+
+ return grub_errno;
+}
+
+static grub_command_t cmd_linux, cmd_initrd, cmd_ucode;
GRUB_MOD_INIT(linux)
{
@@ -1002,6 +1084,8 @@
0, N_("Load Linux."));
cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
0, N_("Load initrd."));
+ cmd_ucode = grub_register_command ("microcode", grub_cmd_ucode,
+ 0, N_("Load microcode."));
my_mod = mod;
}
@@ -1009,4 +1093,5 @@
{
grub_unregister_command (cmd_linux);
grub_unregister_command (cmd_initrd);
+ grub_unregister_command (cmd_ucode);
}
=== modified file 'include/grub/i386/linux.h'
--- include/grub/i386/linux.h 2011-01-10 23:02:01 +0000
+++ include/grub/i386/linux.h 2011-03-28 09:41:12 +0000
@@ -87,6 +87,22 @@
GRUB_VIDEO_LINUX_TYPE_SIMPLE = 0x70 /* Linear framebuffer without any additional functions. */
};
+/* setup data types */
+#define SETUP_NONE 0
+#define SETUP_E820_EXT 1
+#define SETUP_DTB 2
+#define SETUP_MICROCODE 3
+
+/* extensible setup data list node */
+struct setup_data {
+ grub_uint64_t next;
+ grub_uint32_t type;
+ grub_uint32_t len;
+ grub_uint8_t data[0];
+} __attribute__ ((packed));
+
+
+
/* For the Linux/i386 boot protocol version 2.03. */
struct linux_kernel_header
{
@@ -130,6 +146,8 @@
grub_uint16_t pad1; /* Unused */
grub_uint32_t cmd_line_ptr; /* Points to the kernel command line */
grub_uint32_t initrd_addr_max; /* Highest address for initrd */
+ grub_uint32_t pad2[8];
+ grub_uint64_t setup_data;
} __attribute__ ((packed));
/* Boot parameters for Linux based on 2.6.12. This is used by the setup
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2011-03-29 3:29 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-24 8:12 question about adding a field into linux boot header GuoMinskey
2011-03-24 8:35 ` Vladimir 'φ-coder/phcoder' Serbinenko
-- strict thread matches above, loose matches on Subject: below --
2011-03-29 3:29 GuoMinskey
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.