grub-devel
[Top][All Lists]
Advanced

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

Re: booting kernel of NetBSD (Re: UFS (FFS) support seems broken in grub


From: Bean
Subject: Re: booting kernel of NetBSD (Re: UFS (FFS) support seems broken in grub2)
Date: Mon, 28 Jan 2008 18:02:37 +0800

On Jan 28, 2008 9:54 AM, walt <address@hidden> wrote:
>
> On Mon, 2008-01-28 at 04:25 +0800, Bean wrote:
> ...
> > > > please make a small ufs image containing the netbsd kernel, i don't a
> > > > a bsd system at hand
>
> http://leaf.dragonflybsd.org/~wa1ter/ufs.gz
>
> I included a small text file (motd) to demonstrate that you can cat it
> okay, but when you try 'multiboot /netbsd' you should get the same error
> I've been describing.
>
>
> > btw, if you have time, please try the a.out loader, it should be able
> > to boot /boot/loader of freebsd, i don't know if openbsd and netbsd
> > use the same booting method.
>
> diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk
>
> Heh.  I'm assuming an .rmk file involves ruby somehow?  The bonehead
> build process that I'm using doesn't turn an .rmk into a .mk AFAICT,
> but I'd like to know how to do it.

all you need to do is do install ruby.

here is a patch for ufs, it fix the indirect block calculation problem.

        * fs/ufs.c (INODE_BLKSZ): Fix incorrect value.
        (grub_ufs_get_file_block): Fix indirect block calculation problem.


diff --git a/fs/ufs.c b/fs/ufs.c
index 25cd1fa..ebb7198 100644
--- a/fs/ufs.c
+++ b/fs/ufs.c
@@ -52,7 +52,7 @@
                            grub_le_to_cpu##bits2 (data->inode2.field))
 #define INODE_SIZE(data) INODE_ENDIAN (data,size,32,64)
 #define INODE_MODE(data) INODE_ENDIAN (data,mode,16,16)
-#define INODE_BLKSZ(data) (data->ufs_type == UFS1 ? 32 : 64)
+#define INODE_BLKSZ(data) (data->ufs_type == UFS1 ? 4 : 8)
 #define INODE_DIRBLOCKS(data,blk) INODE_ENDIAN \
                                    (data,blocks.dir_blocks[blk],32,64)
 #define INODE_INDIRBLOCKS(data,blk) INODE_ENDIAN \
@@ -205,35 +205,41 @@ grub_ufs_get_file_block (struct grub_ufs_data
*data, unsigned int blk)
 {
   struct grub_ufs_sblock *sblock = &data->sblock;
   unsigned int indirsz;
+  int log2_blksz;

   /* Direct.  */
   if (blk < GRUB_UFS_DIRBLKS)
     return INODE_DIRBLOCKS (data, blk);

+  log2_blksz = grub_le_to_cpu32 (data->sblock.log2_blksz);
+
   blk -= GRUB_UFS_DIRBLKS;

   indirsz = UFS_BLKSZ (sblock) / INODE_BLKSZ (data);
   /* Single indirect block.  */
   if (blk < indirsz)
     {
-      grub_uint32_t indir[UFS_BLKSZ (sblock)];
-      grub_disk_read (data->disk, INODE_INDIRBLOCKS (data, 0),
+      grub_uint32_t indir[UFS_BLKSZ (sblock) >> 2];
+      grub_disk_read (data->disk, INODE_INDIRBLOCKS (data, 0) << log2_blksz,
                      0, sizeof (indir), (char *) indir);
-      return indir[blk];
+      return (data->ufs_type == UFS1) ? indir[blk] : indir[blk << 1];
     }
   blk -= indirsz;

   /* Double indirect block.  */
   if (blk < UFS_BLKSZ (sblock) / indirsz)
     {
-      grub_uint32_t indir[UFS_BLKSZ (sblock)];
+      grub_uint32_t indir[UFS_BLKSZ (sblock) >> 2];

-      grub_disk_read (data->disk, INODE_INDIRBLOCKS (data, 1),
+      grub_disk_read (data->disk, INODE_INDIRBLOCKS (data, 1) << log2_blksz,
                      0, sizeof (indir), (char *) indir);
-      grub_disk_read (data->disk,  indir[blk / indirsz],
+      grub_disk_read (data->disk,
+                     (data->ufs_type == UFS1) ?
+                     indir[blk / indirsz] : indir [(blk / indirsz) << 1],
                      0, sizeof (indir), (char *) indir);

-      return indir[blk % indirsz];
+      return (data->ufs_type == UFS1) ?
+            indir[blk % indirsz] : indir[(blk % indirsz) << 1];
     }



-- 
Bean




reply via email to

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