WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] fat support for pygrub

To: xen-devel@xxxxxxxxxxxxxxxxxxx, xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH] fat support for pygrub
From: Aron Griffis <aron@xxxxxx>
Date: Tue, 13 Feb 2007 13:33:30 -0500
Delivery-date: Tue, 13 Feb 2007 10:40:17 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Mail-followup-to: xen-devel@xxxxxxxxxxxxxxxxxxx, xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.5.13 (2006-08-11)
This patch enables FAT support in libfsimage, so that it's available
to pygrub.  This is important for support of EFI FAT filesystems on
ia64.  

The fsimage module builds and seems to load correctly, but I'm having
a little trouble with my test setup so I haven't booted xen/ia64 with
it yet.

If anybody else wants to try it and post testing results, that would
be great.  Otherwise I'll follow up with my own testing soon.

# HG changeset patch
# User Aron Griffis <aron@xxxxxx>
# Date 1171387823 18000
# Node ID 557b50b1b9b319f98d08b9cc81e04d7de5f87c5a
# Parent  58cc327b2baec74a6b35796e53cb87b5301b7c00
Port fsys_fat.c from grub legacy.  This enables pygrub to load from EFI
FAT partitions on ia64.

Signed-off-by: Aron Griffis <aron@xxxxxx>

diff -r 58cc327b2bae -r 557b50b1b9b3 tools/libfsimage/Makefile
--- a/tools/libfsimage/Makefile Tue Feb 13 01:07:46 2007 -0500
+++ b/tools/libfsimage/Makefile Tue Feb 13 12:30:23 2007 -0500
@@ -1,7 +1,7 @@ XEN_ROOT = ../..
 XEN_ROOT = ../..
 include $(XEN_ROOT)/tools/Rules.mk
 
-SUBDIRS-y = common ufs reiserfs
+SUBDIRS-y = common ufs reiserfs fat
 SUBDIRS-y += $(shell ./check-libext2fs)
 
 .PHONY: all
diff -r 58cc327b2bae -r 557b50b1b9b3 tools/libfsimage/fat/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libfsimage/fat/Makefile     Tue Feb 13 12:30:23 2007 -0500
@@ -0,0 +1,13 @@
+XEN_ROOT = ../../..
+
+LIB_SRCS-y = fsys_fat.c
+
+FS = fat
+
+.PHONY: all
+all: fs-all
+
+.PHONY: install
+install: fs-install
+
+include $(XEN_ROOT)/tools/libfsimage/Rules.mk
diff -r 58cc327b2bae -r 557b50b1b9b3 tools/libfsimage/fat/fat.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libfsimage/fat/fat.h        Tue Feb 13 12:30:23 2007 -0500
@@ -0,0 +1,100 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2001  Free Software Foundation, Inc.
+ *
+ *  This program 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 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ *  Defines for the FAT BIOS Parameter Block (embedded in the first block
+ *  of the partition.
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+/* Note that some shorts are not aligned, and must therefore
+ * be declared as array of two bytes.
+ */
+struct fat_bpb {
+       __s8    ignored[3];     /* Boot strap short or near jump */
+       __s8    system_id[8];   /* Name - can be used to special case
+                                  partition manager volumes */
+       __u8    bytes_per_sect[2];      /* bytes per logical sector */
+       __u8    sects_per_clust;/* sectors/cluster */
+       __u8    reserved_sects[2];      /* reserved sectors */
+       __u8    num_fats;       /* number of FATs */
+       __u8    dir_entries[2]; /* root directory entries */
+       __u8    short_sectors[2];       /* number of sectors */
+       __u8    media;          /* media code (unused) */
+       __u16   fat_length;     /* sectors/FAT */
+       __u16   secs_track;     /* sectors per track */
+       __u16   heads;          /* number of heads */
+       __u32   hidden;         /* hidden sectors (unused) */
+       __u32   long_sectors;   /* number of sectors (if short_sectors == 0) */
+
+       /* The following fields are only used by FAT32 */
+       __u32   fat32_length;   /* sectors/FAT */
+       __u16   flags;          /* bit 8: fat mirroring, low 4: active fat */
+       __u8    version[2];     /* major, minor filesystem version */
+       __u32   root_cluster;   /* first cluster in root directory */
+       __u16   info_sector;    /* filesystem info sector */
+       __u16   backup_boot;    /* backup boot sector */
+       __u16   reserved2[6];   /* Unused */
+};
+
+#define FAT_CVT_U16(bytarr) (* (__u16*)(bytarr))
+
+/*
+ *  Defines how to differentiate a 12-bit and 16-bit FAT.
+ */
+
+#define FAT_MAX_12BIT_CLUST       4087 /* 4085 + 2 */
+
+/*
+ *  Defines for the file "attribute" byte
+ */
+
+#define FAT_ATTRIB_OK_MASK        0x37
+#define FAT_ATTRIB_NOT_OK_MASK    0xC8
+#define FAT_ATTRIB_DIR            0x10
+#define FAT_ATTRIB_LONGNAME       0x0F
+
+/*
+ *  Defines for FAT directory entries
+ */
+
+#define FAT_DIRENTRY_LENGTH       32
+
+#define FAT_DIRENTRY_ATTRIB(entry) \
+  (*((unsigned char *) (entry+11)))
+#define FAT_DIRENTRY_VALID(entry) \
+  ( ((*((unsigned char *) entry)) != 0) \
+    && ((*((unsigned char *) entry)) != 0xE5) \
+    && !(FAT_DIRENTRY_ATTRIB(entry) & FAT_ATTRIB_NOT_OK_MASK) )
+#define FAT_DIRENTRY_FIRST_CLUSTER(entry) \
+  ((*((unsigned short *) (entry+26)))+(*((unsigned short *) (entry+20)) << 16))
+#define FAT_DIRENTRY_FILELENGTH(entry) \
+  (*((unsigned long *) (entry+28)))
+
+#define FAT_LONGDIR_ID(entry) \
+  (*((unsigned char *) (entry)))
+#define FAT_LONGDIR_ALIASCHECKSUM(entry) \
+  (*((unsigned char *) (entry+13)))
diff -r 58cc327b2bae -r 557b50b1b9b3 tools/libfsimage/fat/fsys_fat.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libfsimage/fat/fsys_fat.c   Tue Feb 13 12:30:23 2007 -0500
@@ -0,0 +1,562 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2001,2005   Free Software Foundation, Inc.
+ *
+ *  This program 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 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <limits.h>
+#include <fsimage_grub.h>
+#include "fat.h"
+
+struct fat_superblock 
+{
+  int fat_offset;
+  int fat_length;
+  int fat_size;
+  int root_offset;
+  int root_max;
+  int data_offset;
+  
+  int num_sectors;
+  int num_clust;
+  int clust_eof_marker;
+  int sects_per_clust;
+  int sectsize_bits;
+  int clustsize_bits;
+  int root_cluster;
+  
+  int cached_fat;
+  int file_cluster;
+  int current_cluster_num;
+  int current_cluster;
+};
+
+/* pointer(s) into filesystem info buffer for DOS stuff */
+#define FAT_SUPER ( (struct fat_superblock *) \
+                   ( FSYS_BUF + 32256) )/* 512 bytes long */
+#define FAT_BUF   ( FSYS_BUF + 30208 ) /* 4 sector FAT buffer */
+#define NAME_BUF  ( FSYS_BUF + 29184 ) /* Filename buffer (833 bytes) */
+
+#define FAT_CACHE_SIZE 2048
+
+#if defined(__i386__) || defined(__x86_64__)
+
+#ifdef __amd64
+#define BSF "bsfq"
+#else
+#define BSF "bsfl"
+#endif
+static __inline__ unsigned long
+grub_log2 (unsigned long word)
+{
+  __asm__ (BSF " %1,%0"
+          : "=r" (word)
+          : "r" (word));
+  return word;
+}
+
+#elif defined(__ia64__)
+
+#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+# define ia64_popcnt(x) __builtin_popcountl(x)
+#else
+# define ia64_popcnt(x)                                     \
+  ({                                                        \
+    __u64 ia64_intri_res;                                   \
+    asm ("popcnt %0=%1" : "=r" (ia64_intri_res) : "r" (x)); \
+    ia64_intri_res;                                         \
+  })
+#endif
+
+static __inline__ unsigned long
+grub_log2 (unsigned long word)
+{
+  unsigned long result;
+
+  result = ia64_popcnt((word - 1) & ~word);
+  return result;
+}
+
+#elif defined(__powerpc__)
+
+#ifdef __powerpc64__
+#define PPC_CNTLZL "cntlzd"
+#else
+#define PPC_CNTLZL "cntlzw"
+#endif
+#define BITS_PER_LONG (sizeof(long) * 8)
+
+static __inline__ int
+__ilog2(unsigned long x)
+{
+  int lz;
+
+  asm (PPC_CNTLZL " %0,%1" : "=r" (lz) : "r" (x));
+  return BITS_PER_LONG - 1 - lz;
+}
+
+static __inline__ unsigned long
+grub_log2 (unsigned long word)
+{
+  return __ilog2(word & -word);
+}
+
+#else /* Unoptimized */
+
+static __inline__ unsigned long
+grub_log2 (unsigned long word)
+{
+  unsigned long result = 0;
+
+  while (!(word & 1UL))
+    {
+      result++;
+      word >>= 1;
+    }
+  return result;
+}
+#endif
+#define log2 grub_log2
+
+int
+fat_mount (fsi_file_t *ffi)
+{
+  struct fat_bpb bpb;
+  __u32 magic, first_fat;
+  
+  /* Read bpb */
+  if (! devread (ffi, 0, 0, sizeof (bpb), (char *) &bpb))
+    return 0;
+
+  /* Check if the number of sectors per cluster is zero here, to avoid
+     zero division.  */
+  if (bpb.sects_per_clust == 0)
+    return 0;
+  
+  FAT_SUPER->sectsize_bits = log2 (FAT_CVT_U16 (bpb.bytes_per_sect));
+  FAT_SUPER->clustsize_bits
+    = FAT_SUPER->sectsize_bits + log2 (bpb.sects_per_clust);
+  
+  /* Fill in info about super block */
+  FAT_SUPER->num_sectors = FAT_CVT_U16 (bpb.short_sectors) 
+    ? FAT_CVT_U16 (bpb.short_sectors) : bpb.long_sectors;
+  
+  /* FAT offset and length */
+  FAT_SUPER->fat_offset = FAT_CVT_U16 (bpb.reserved_sects);
+  FAT_SUPER->fat_length = 
+    bpb.fat_length ? bpb.fat_length : bpb.fat32_length;
+  
+  /* Rootdir offset and length for FAT12/16 */
+  FAT_SUPER->root_offset = 
+    FAT_SUPER->fat_offset + bpb.num_fats * FAT_SUPER->fat_length;
+  FAT_SUPER->root_max = FAT_DIRENTRY_LENGTH * FAT_CVT_U16(bpb.dir_entries);
+  
+  /* Data offset and number of clusters */
+  FAT_SUPER->data_offset = 
+    FAT_SUPER->root_offset
+    + ((FAT_SUPER->root_max - 1) >> FAT_SUPER->sectsize_bits) + 1;
+  FAT_SUPER->num_clust = 
+    2 + ((FAT_SUPER->num_sectors - FAT_SUPER->data_offset) 
+        / bpb.sects_per_clust);
+  FAT_SUPER->sects_per_clust = bpb.sects_per_clust;
+  
+  if (!bpb.fat_length)
+    {
+      /* This is a FAT32 */
+      if (FAT_CVT_U16(bpb.dir_entries))
+       return 0;
+      
+      if (bpb.flags & 0x0080)
+       {
+         /* FAT mirroring is disabled, get active FAT */
+         int active_fat = bpb.flags & 0x000f;
+         if (active_fat >= bpb.num_fats)
+           return 0;
+         FAT_SUPER->fat_offset += active_fat * FAT_SUPER->fat_length;
+       }
+      
+      FAT_SUPER->fat_size = 8;
+      FAT_SUPER->root_cluster = bpb.root_cluster;
+
+      /* Yes the following is correct.  FAT32 should be called FAT28 :) */
+      FAT_SUPER->clust_eof_marker = 0xffffff8;
+    } 
+  else 
+    {
+      if (!FAT_SUPER->root_max)
+       return 0;
+      
+      FAT_SUPER->root_cluster = -1;
+      if (FAT_SUPER->num_clust > FAT_MAX_12BIT_CLUST) 
+       {
+         FAT_SUPER->fat_size = 4;
+         FAT_SUPER->clust_eof_marker = 0xfff8;
+       } 
+      else
+       {
+         FAT_SUPER->fat_size = 3;
+         FAT_SUPER->clust_eof_marker = 0xff8;
+       }
+    }
+
+  /* Now do some sanity checks */
+  
+  if (FAT_CVT_U16(bpb.bytes_per_sect) != (1 << FAT_SUPER->sectsize_bits)
+      || FAT_CVT_U16(bpb.bytes_per_sect) != SECTOR_SIZE
+      || bpb.sects_per_clust != (1 << (FAT_SUPER->clustsize_bits
+                                      - FAT_SUPER->sectsize_bits))
+      || FAT_SUPER->num_clust <= 2
+      || (FAT_SUPER->fat_size * FAT_SUPER->num_clust / (2 * SECTOR_SIZE)
+         > FAT_SUPER->fat_length))
+    return 0;
+  
+  /* kbs: Media check on first FAT entry [ported from PUPA] */
+
+  if (!devread(ffi, FAT_SUPER->fat_offset, 0,
+               sizeof(first_fat), (char *)&first_fat))
+    return 0;
+
+  if (FAT_SUPER->fat_size == 8)
+    {
+      first_fat &= 0x0fffffff;
+      magic = 0x0fffff00;
+    }
+  else if (FAT_SUPER->fat_size == 4)
+    {
+      first_fat &= 0x0000ffff;
+      magic = 0xff00;
+    }
+  else
+    {
+      first_fat &= 0x00000fff;
+      magic = 0x0f00;
+    }
+
+  /* Ignore the 3rd bit, because some BIOSes assigns 0xF0 to the media
+     descriptor, even if it is a so-called superfloppy (e.g. an USB key).
+     The check may be too strict for this kind of stupid BIOSes, as
+     they overwrite the media descriptor.  */
+  if ((first_fat | 0x8) != (magic | bpb.media | 0x8))
+    return 0;
+
+  FAT_SUPER->cached_fat = - 2 * FAT_CACHE_SIZE;
+  return 1;
+}
+
+int
+fat_read (fsi_file_t *ffi, char *buf, int len)
+{
+  int logical_clust;
+  int offset;
+  int ret = 0;
+  int size;
+  
+  if (FAT_SUPER->file_cluster < 0)
+    {
+      /* root directory for fat16 */
+      size = FAT_SUPER->root_max - filepos;
+      if (size > len)
+       size = len;
+      if (!devread(ffi, FAT_SUPER->root_offset, filepos, size, buf))
+       return 0;
+      filepos += size;
+      return size;
+    }
+  
+  logical_clust = filepos >> FAT_SUPER->clustsize_bits;
+  offset = (filepos & ((1 << FAT_SUPER->clustsize_bits) - 1));
+  if (logical_clust < FAT_SUPER->current_cluster_num)
+    {
+      FAT_SUPER->current_cluster_num = 0;
+      FAT_SUPER->current_cluster = FAT_SUPER->file_cluster;
+    }
+  
+  while (len > 0)
+    {
+      int sector;
+      while (logical_clust > FAT_SUPER->current_cluster_num)
+       {
+         /* calculate next cluster */
+         int fat_entry = 
+           FAT_SUPER->current_cluster * FAT_SUPER->fat_size;
+         int next_cluster;
+         int cached_pos = (fat_entry - FAT_SUPER->cached_fat);
+         
+         if (cached_pos < 0 || 
+             (cached_pos + FAT_SUPER->fat_size) > 2*FAT_CACHE_SIZE)
+           {
+             FAT_SUPER->cached_fat = (fat_entry & ~(2*SECTOR_SIZE - 1));
+             cached_pos = (fat_entry - FAT_SUPER->cached_fat);
+             sector = FAT_SUPER->fat_offset
+               + FAT_SUPER->cached_fat / (2*SECTOR_SIZE);
+             if (!devread (ffi, sector, 0, FAT_CACHE_SIZE, (char*) FAT_BUF))
+               return 0;
+           }
+         next_cluster = * (unsigned long *) (FAT_BUF + (cached_pos >> 1));
+         if (FAT_SUPER->fat_size == 3)
+           {
+             if (cached_pos & 1)
+               next_cluster >>= 4;
+             next_cluster &= 0xFFF;
+           }
+         else if (FAT_SUPER->fat_size == 4)
+           next_cluster &= 0xFFFF;
+         
+         if (next_cluster >= FAT_SUPER->clust_eof_marker)
+           return ret;
+         if (next_cluster < 2 || next_cluster >= FAT_SUPER->num_clust)
+           {
+             errnum = ERR_FSYS_CORRUPT;
+             return 0;
+           }
+         
+         FAT_SUPER->current_cluster = next_cluster;
+         FAT_SUPER->current_cluster_num++;
+       }
+      
+      sector = FAT_SUPER->data_offset +
+       ((FAT_SUPER->current_cluster - 2) << (FAT_SUPER->clustsize_bits
+                                             - FAT_SUPER->sectsize_bits));
+      size = (1 << FAT_SUPER->clustsize_bits) - offset;
+      if (size > len)
+       size = len;
+      
+      disk_read_func = disk_read_hook;
+      
+      devread(ffi, sector, offset, size, buf);
+      
+      disk_read_func = NULL;
+      
+      len -= size;
+      buf += size;
+      ret += size;
+      filepos += size;
+      logical_clust++;
+      offset = 0;
+    }
+  return errnum ? 0 : ret;
+}
+
+int
+fat_dir (fsi_file_t *ffi, char *dirname)
+{
+  char *rest, ch, dir_buf[FAT_DIRENTRY_LENGTH];
+  char *filename = (char *) NAME_BUF;
+  int attrib = FAT_ATTRIB_DIR;
+#ifndef STAGE1_5
+  int do_possibilities = 0;
+#endif
+  
+  /* XXX I18N:
+   * the positions 2,4,6 etc are high bytes of a 16 bit unicode char 
+   */
+  static unsigned char longdir_pos[] = 
+  { 1, 3, 5, 7, 9, 14, 16, 18, 20, 22, 24, 28, 30 };
+  int slot = -2;
+  int alias_checksum = -1;
+  
+  FAT_SUPER->file_cluster = FAT_SUPER->root_cluster;
+  filepos = 0;
+  FAT_SUPER->current_cluster_num = INT_MAX;
+  
+  /* main loop to find desired directory entry */
+ loop:
+  
+  /* if we have a real file (and we're not just printing possibilities),
+     then this is where we want to exit */
+  
+  if (!*dirname || isspace (*dirname))
+    {
+      if (attrib & FAT_ATTRIB_DIR)
+       {
+         errnum = ERR_BAD_FILETYPE;
+         return 0;
+       }
+      
+      return 1;
+    }
+  
+  /* continue with the file/directory name interpretation */
+  
+  while (*dirname == '/')
+    dirname++;
+  
+  if (!(attrib & FAT_ATTRIB_DIR))
+    {
+      errnum = ERR_BAD_FILETYPE;
+      return 0;
+    }
+  /* Directories don't have a file size */
+  filemax = INT_MAX;
+  
+  for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++);
+  
+  *rest = 0;
+  
+# ifndef STAGE1_5
+  if (print_possibilities && ch != '/')
+    do_possibilities = 1;
+# endif
+  
+  while (1)
+    {
+      if (fat_read (ffi, dir_buf, FAT_DIRENTRY_LENGTH) != FAT_DIRENTRY_LENGTH
+         || dir_buf[0] == 0)
+       {
+         if (!errnum)
+           {
+# ifndef STAGE1_5
+             if (print_possibilities < 0)
+               {
+#if 0
+                 putchar ('\n');
+#endif
+                 return 1;
+               }
+# endif /* STAGE1_5 */
+             
+             errnum = ERR_FILE_NOT_FOUND;
+             *rest = ch;
+           }
+         
+         return 0;
+       }
+      
+      if (FAT_DIRENTRY_ATTRIB (dir_buf) == FAT_ATTRIB_LONGNAME)
+       {
+         /* This is a long filename.  The filename is build from back
+          * to front and may span multiple entries.  To bind these
+          * entries together they all contain the same checksum over
+          * the short alias.
+          *
+          * The id field tells if this is the first entry (the last
+          * part) of the long filename, and also at which offset this
+          * belongs.
+          *
+          * We just write the part of the long filename this entry
+          * describes and continue with the next dir entry.
+          */
+         int i, offset;
+         unsigned char id = FAT_LONGDIR_ID(dir_buf);
+         
+         if ((id & 0x40)) 
+           {
+             id &= 0x3f;
+             slot = id;
+             filename[slot * 13] = 0;
+             alias_checksum = FAT_LONGDIR_ALIASCHECKSUM(dir_buf);
+           } 
+         
+         if (id != slot || slot == 0
+             || alias_checksum != FAT_LONGDIR_ALIASCHECKSUM(dir_buf))
+           {
+             alias_checksum = -1;
+             continue;
+           }
+         
+         slot--;
+         offset = slot * 13;
+         
+         for (i=0; i < 13; i++)
+           filename[offset+i] = dir_buf[longdir_pos[i]];
+         continue;
+       }
+      
+      if (!FAT_DIRENTRY_VALID (dir_buf))
+       continue;
+      
+      if (alias_checksum != -1 && slot == 0)
+       {
+         int i;
+         unsigned char sum;
+         
+         slot = -2;
+         for (sum = 0, i = 0; i< 11; i++)
+           sum = ((sum >> 1) | (sum << 7)) + dir_buf[i];
+         
+         if (sum == alias_checksum)
+           {
+# ifndef STAGE1_5
+             if (do_possibilities)
+               goto print_filename;
+# endif /* STAGE1_5 */
+             
+             if (substring (dirname, filename) == 0)
+               break;
+           }
+       }
+      
+      /* XXX convert to 8.3 filename format here */
+      {
+       int i, j, c;
+       
+       for (i = 0; i < 8 && (c = filename[i] = tolower (dir_buf[i]))
+              && !isspace (c); i++);
+       
+       filename[i++] = '.';
+       
+       for (j = 0; j < 3 && (c = filename[i + j] = tolower (dir_buf[8 + j]))
+              && !isspace (c); j++);
+       
+       if (j == 0)
+         i--;
+       
+       filename[i + j] = 0;
+      }
+      
+# ifndef STAGE1_5
+      if (do_possibilities)
+       {
+       print_filename:
+         if (substring (dirname, filename) <= 0)
+           {
+             if (print_possibilities > 0)
+               print_possibilities = -print_possibilities;
+             print_a_completion (filename);
+           }
+         continue;
+       }
+# endif /* STAGE1_5 */
+      
+      if (substring (dirname, filename) == 0)
+       break;
+    }
+  
+  *(dirname = rest) = ch;
+  
+  attrib = FAT_DIRENTRY_ATTRIB (dir_buf);
+  filemax = FAT_DIRENTRY_FILELENGTH (dir_buf);
+  filepos = 0;
+  FAT_SUPER->file_cluster = FAT_DIRENTRY_FIRST_CLUSTER (dir_buf);
+  FAT_SUPER->current_cluster_num = INT_MAX;
+  
+  /* go back to main loop at top of function */
+  goto loop;
+}
+
+fsi_plugin_ops_t *
+fsi_init_plugin(int version, fsi_plugin_t *fp, const char **name)
+{
+       static fsig_plugin_ops_t ops = {
+               FSIMAGE_PLUGIN_VERSION,
+               .fpo_mount = fat_mount,
+               .fpo_dir = fat_dir,
+               .fpo_read = fat_read
+       };
+
+       *name = "fat";
+       return (fsig_init(fp, &ops));
+}

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] fat support for pygrub, Aron Griffis <=