bug-grub
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[grub #38] [PATCH] "grub" command says nothing but "cannot fit into mem


From: kabe
Subject: [grub #38] [PATCH] "grub" command says nothing but "cannot fit into memory"
Date: Tue, 04 Feb 2003 19:42:52 +0900

Reporter: address@hidden
Summary: [PATCH] "grub" command says nothing but "cannot fit into memory"
Version: 0.93
Type: software bug

Message:
"grub" command (one invoked from commandline, not the bootloader)
says nothing but ERR_WONT_FIT.

This turns out to be mbi struct incorrectly initialized to
mbi.mem_lower = mbi.mem_upper = 0,
which in turn cuz the code assumes the 
struct mmar_desc/AddrRangeDesc is packed.

gcc 2.95.2 && 2.95.3 both aligns these struct members to 8.
(Probably of the "long long" needed to be aligned to 8)

Platform: QNX 6.2
Compiler: gcc 2.95.3

If the struct was padded to 8 bytes, the second struct member
will be at offset 8, not offset 4, 
as common.c:init_bios_info() et al assumes. (comment inserted in patch)

mb_info.h:
        struct AddrRangeDesc
        {
                unsigned long size;             /*offset 0*/
                unsigned long long BaseAddr;    /*code assumes 4, actually 8*/
                ...
        }

Trapping at above location and examining the 
SECOND instance of AddrRangeSpec, i.e
((struct AddrRangeSpec*)mbi.mmap_addr)[1] will reveal weird things assigned.

Now the patch below is simply ((packed)); I'm not a AT BIOS guru
so the "correctness" of it is delegated to the maintainer.

Instead of hardcoding +4, you could use 
offsetof(struct AddrRangeDesc, BaseAddr) if the
struct don't have to be packed.
sizeof() can't be used as it'll be always 4.
*note: offsetof() is ANSI and glibc, but not necessarily portable.

Dunno why this was working for other OS.

patch:

Index: stage2/common.c
===================================================================
RCS file: /root6.1/CVSroot/grub/stage2/common.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- stage2/common.c     2003/01/31 04:41:28     1.1
+++ stage2/common.c     2003/01/31 04:50:58     1.2
@@ -185,6 +185,7 @@
       if (! *((unsigned long *) addr))
        break;
 
+               /*XXX should be "+ offsetof(struct mmar_desc, addr)"; can be +8 
if padded to 8 bytes */
       mbi.mmap_length += *((unsigned long *) addr) + 4;
       addr += *((unsigned long *) addr) + 4;
     }
Index: stage2/mb_info.h
===================================================================
RCS file: /root6.1/CVSroot/grub/stage2/mb_info.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- stage2/mb_info.h    2003/01/31 04:41:27     1.1
+++ stage2/mb_info.h    2003/01/31 04:50:58     1.2
@@ -50,7 +50,7 @@
   unsigned long Type;
   
   /* unspecified optional padding... */
-};
+} __attribute__ ((packed)) /* should be in sync with struct mmar_desc */;
 
 /* usable memory "Type", all others are reserved.  */
 #define MB_ARD_MEMORY          1
Index: stage2/shared.h
===================================================================
RCS file: /root6.1/CVSroot/grub/stage2/shared.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- stage2/shared.h     2003/01/31 04:41:27     1.1
+++ stage2/shared.h     2003/01/31 04:50:59     1.2
@@ -412,7 +412,7 @@
   unsigned long long addr;     /* Base address. */
   unsigned long long length;   /* Length in bytes. */
   unsigned long type;          /* Type of address range. */
-};
+} __attribute__ ((packed)) /* don't pad desc_len to 8bytes; there's too many 
+4s already */;
 
 /* VBE controller information.  */
 struct vbe_controller


----
Please send followups to <address@hidden>.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]