]> code.delx.au - refind/commitdiff
Btrfs driver & check for valid loader before adding to menu.
authorsrs5694 <srs5694@users.sourceforge.net>
Sat, 22 Jun 2013 22:46:37 +0000 (18:46 -0400)
committersrs5694 <srs5694@users.sourceforge.net>
Sat, 22 Jun 2013 22:46:37 +0000 (18:46 -0400)
Make.common
NEWS.txt
filesystems/Make.tiano
filesystems/Makefile
filesystems/fsw_core.c
filesystems/fsw_core.h
filesystems/fsw_ext2.c
filesystems/fsw_ext4.c
mok/simple_file.c
refind/main.c

index 0d994e598131655c0458b45de1d08528affeff5b..55755e214c4e6d26dc7f4d8e9dbf8146ed231c0f 100644 (file)
@@ -3,16 +3,16 @@
 # Common make rules for building with gnu-efi
 #
 
-EFIINC          = /usr/include/efi
-GNUEFILIB       = /usr/lib64
-EFILIB          = /usr/lib64
-EFICRT0         = /usr/lib64
+#EFIINC          = /usr/include/efi
+#GNUEFILIB       = /usr/lib64
+#EFILIB          = /usr/lib64
+#EFICRT0         = /usr/lib64
 
 # Comment out above and uncomment below if using locally-compiled GNU-EFI....
-#EFIINC          = /usr/local/include/efi
-#GNUEFILIB       = /usr/local/lib
-#EFILIB          = /usr/local/lib
-#EFICRT0         = /usr/local/lib
+EFIINC          = /usr/local/include/efi
+GNUEFILIB       = /usr/local/lib
+EFILIB          = /usr/local/lib
+EFICRT0         = /usr/local/lib
 
 HOSTARCH        = $(shell uname -m | sed s,i[3456789]86,ia32,)
 ARCH            := $(HOSTARCH)
@@ -24,7 +24,7 @@ DEBUGFLAGS      = -Wall
 #CFLAGS          = $(ARCH3264) $(OPTIMFLAGS) -fpic -fshort-wchar $(DEBUGFLAGS)
 CFLAGS          = $(ARCH3264) $(OPTIMFLAGS) -fno-stack-protector -fpic -fshort-wchar -mno-red-zone $(DEBUGFLAGS)
 ASFLAGS         = $(ARCH3264)
-LDFLAGS         = -nostdlib -znocombreloc
+LDFLAGS         = -nostdlib -znocombreloc -zdefs
 
 prefix          = /usr/bin/
 CC              = $(prefix)gcc
index 1b9a439832b4f77bb6d44e094fe76f675f3eeda6..e9cd6a02b6235b428dc7d103682c5eafd676afa6 100644 (file)
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -1,3 +1,8 @@
+0.6.13 (?/??/2013):
+-------------------
+
+
+
 0.6.12 (6/18/2013):
 -------------------
 
index 64266cd8cd5bef83ee70a6dbbccd0a01f2896537..b9ad0a87aeb7e26d785482198433cff15d856e58 100644 (file)
@@ -14,7 +14,7 @@ ifeq ($(ARCH),ia64)
 endif
 
 ifeq ($(ARCH),ia32)
-  ARCH_C_FLAGS = -m32 -malign-double
+  ARCH_C_FLAGS = -m32 -malign-double -g
   ARCHDIR = Ia32
   UC_ARCH = IA32
   FILENAME_CODE = ia32
index cf600670f43f5998469b8eec74b7cd70eeca4e82..4aa838e2c19aa63a396548be1ec8b3a14eba687c 100644 (file)
@@ -8,8 +8,8 @@
 
 INSTALL_DIR = /boot/efi/EFI/refind/drivers
 
-FILESYSTEMS = ext2 ext4 reiserfs iso9660 hfs
-FILESYSTEMS_GNUEFI = ext2_gnuefi ext4_gnuefi reiserfs_gnuefi iso9660_gnuefi hfs_gnuefi
+FILESYSTEMS = ext2 ext4 reiserfs iso9660 hfs btrfs
+FILESYSTEMS_GNUEFI = ext2_gnuefi ext4_gnuefi reiserfs_gnuefi iso9660_gnuefi hfs_gnuefi btrfs_gnuefi
 TEXTFILES = $(FILESYSTEMS:=*.txt)
 
 # Build the drivers with TianoCore EDK2.....
@@ -36,6 +36,10 @@ hfs:
        rm -f fsw_efi.obj
        +make DRIVERNAME=hfs -f Make.tiano
 
+btrfs:
+       rm -f fsw_efi.obj
+       +make DRIVERNAME=btrfs -f Make.tiano
+
 # Build the drivers with GNU-EFI....
 
 gnuefi: $(FILESYSTEMS_GNUEFI)
@@ -62,6 +66,10 @@ hfs_gnuefi:
        rm -f fsw_efi.o
        +make DRIVERNAME=hfs -f Make.gnuefi
 
+btrfs_gnuefi:
+       rm -f fsw_efi.o
+       +make DRIVERNAME=btrfs -f Make.gnuefi
+
 # utility rules
 
 clean:
index 64d70d7f50bc1b104cc3b2621f03fb9af97213b6..dbc71983b17d55ab3ed6f2af067a13ae99c23ba1 100644 (file)
@@ -190,6 +190,21 @@ fsw_status_t fsw_block_get(struct VOLSTRUCTNAME *vol, fsw_u32 phys_bno, fsw_u32
     if (cache_level > MAX_CACHE_LEVEL)
         cache_level = MAX_CACHE_LEVEL;
 
+    if (vol->bcache_size > 0 && vol->bcache == NULL) {
+       /* driver set the initial cache size */
+        status = fsw_alloc(vol->bcache_size * sizeof(struct fsw_blockcache), &vol->bcache);
+       if(status)
+           return status;
+       for( i = 0; i < vol->bcache_size; i++) {
+            vol->bcache[i].refcount = 0;
+            vol->bcache[i].cache_level = 0;
+            vol->bcache[i].phys_bno = (fsw_u32)FSW_INVALID_BNO;
+            vol->bcache[i].data = NULL;
+       }
+       i = 0;
+       goto miss;
+    }
+
     // check block cache
     for (i = 0; i < vol->bcache_size; i++) {
         if (vol->bcache[i].phys_bno == phys_bno) {
@@ -243,6 +258,7 @@ fsw_status_t fsw_block_get(struct VOLSTRUCTNAME *vol, fsw_u32 phys_bno, fsw_u32
         vol->bcache_size = new_bcache_size;
     }
     vol->bcache[i].phys_bno = (fsw_u32)FSW_INVALID_BNO;
+miss:
 
     // read the data
     if (vol->bcache[i].data == NULL) {
@@ -322,7 +338,7 @@ static void fsw_dnode_register(struct fsw_volume *vol, struct fsw_dnode *dno)
  * behaves in the same way as fsw_dnode_create.
  */
 
-fsw_status_t fsw_dnode_create_root(struct fsw_volume *vol, fsw_u32 dnode_id, struct fsw_dnode **dno_out)
+fsw_status_t fsw_dnode_create_root_with_tree(struct fsw_volume *vol, fsw_u64 tree_id, fsw_u64 dnode_id, struct fsw_dnode **dno_out)
 {
     fsw_status_t    status;
     struct fsw_dnode *dno;
@@ -335,6 +351,7 @@ fsw_status_t fsw_dnode_create_root(struct fsw_volume *vol, fsw_u32 dnode_id, str
     // fill the structure
     dno->vol = vol;
     dno->parent = NULL;
+    dno->tree_id = tree_id;
     dno->dnode_id = dnode_id;
     dno->type = FSW_DNODE_TYPE_DIR;
     dno->refcount = 1;
@@ -347,6 +364,10 @@ fsw_status_t fsw_dnode_create_root(struct fsw_volume *vol, fsw_u32 dnode_id, str
     return FSW_SUCCESS;
 }
 
+fsw_status_t fsw_dnode_create_root(struct fsw_volume *vol, fsw_u64 dnode_id, struct fsw_dnode **dno_out)
+{
+       return fsw_dnode_create_root_with_tree( vol, 0, dnode_id, dno_out);
+}
 /**
  * Create a new dnode representing a file system object. This function is called by
  * the file system driver in response to directory lookup or read requests. Note that
@@ -365,7 +386,7 @@ fsw_status_t fsw_dnode_create_root(struct fsw_volume *vol, fsw_u32 dnode_id, str
  * that must be released by the caller with fsw_dnode_release.
  */
 
-fsw_status_t fsw_dnode_create(struct fsw_dnode *parent_dno, fsw_u32 dnode_id, int type,
+fsw_status_t fsw_dnode_create_with_tree(struct fsw_dnode *parent_dno, fsw_u64 tree_id, fsw_u64 dnode_id, int type,
                               struct fsw_string *name, struct fsw_dnode **dno_out)
 {
     fsw_status_t    status;
@@ -374,7 +395,7 @@ fsw_status_t fsw_dnode_create(struct fsw_dnode *parent_dno, fsw_u32 dnode_id, in
 
     // check if we already have a dnode with the same id
     for (dno = vol->dnode_head; dno; dno = dno->next) {
-        if (dno->dnode_id == dnode_id) {
+        if (dno->dnode_id == dnode_id && dno->tree_id == tree_id) {
             fsw_dnode_retain(dno);
             *dno_out = dno;
             return FSW_SUCCESS;
@@ -390,6 +411,7 @@ fsw_status_t fsw_dnode_create(struct fsw_dnode *parent_dno, fsw_u32 dnode_id, in
     dno->vol = vol;
     dno->parent = parent_dno;
     fsw_dnode_retain(dno->parent);
+    dno->tree_id = tree_id;
     dno->dnode_id = dnode_id;
     dno->type = type;
     dno->refcount = 1;
@@ -405,6 +427,12 @@ fsw_status_t fsw_dnode_create(struct fsw_dnode *parent_dno, fsw_u32 dnode_id, in
     return FSW_SUCCESS;
 }
 
+fsw_status_t fsw_dnode_create(struct fsw_dnode *parent_dno, fsw_u64 dnode_id, int type,
+                              struct fsw_string *name, struct fsw_dnode **dno_out)
+{
+       return fsw_dnode_create_with_tree(parent_dno, 0, dnode_id, type, name, dno_out);
+}
+
 /**
  * Increases the reference count of a dnode. This must be balanced with
  * fsw_dnode_release calls. Note that some dnode functions return a retained
index 56eb58b8912a777bc19a669b167c632f60c48209..d8267e4ae3e5f9cbb9ccca776ec613360abcc2a9 100644 (file)
@@ -267,7 +267,8 @@ struct fsw_dnode {
     struct DNODESTRUCTNAME *parent; //!< Parent directory dnode
     struct fsw_string name;         //!< Name of this item in the parent directory
 
-    fsw_u32     dnode_id;           //!< Unique id number (usually the inode number)
+    fsw_u64     tree_id;            //!< Unique id number (usually the btrfs subvolume)
+    fsw_u64     dnode_id;           //!< Unique id number (usually the inode number)
     int         type;               //!< Type of the dnode - file, dir, symlink, special
     fsw_u64     size;               //!< Data size in bytes
 
@@ -419,8 +420,11 @@ void         fsw_block_release(struct VOLSTRUCTNAME *vol, fsw_u32 phys_bno, void
  */
 /*@{*/
 
-fsw_status_t fsw_dnode_create_root(struct VOLSTRUCTNAME *vol, fsw_u32 dnode_id, struct DNODESTRUCTNAME **dno_out);
-fsw_status_t fsw_dnode_create(struct DNODESTRUCTNAME *parent_dno, fsw_u32 dnode_id, int type,
+fsw_status_t fsw_dnode_create_root(struct VOLSTRUCTNAME *vol, fsw_u64 dnode_id, struct DNODESTRUCTNAME **dno_out);
+fsw_status_t fsw_dnode_create(struct DNODESTRUCTNAME *parent_dno, fsw_u64 dnode_id, int type,
+                              struct fsw_string *name, struct DNODESTRUCTNAME **dno_out);
+fsw_status_t fsw_dnode_create_root_with_tree(struct VOLSTRUCTNAME *vol, fsw_u64 tree_id, fsw_u64 dnode_id, struct DNODESTRUCTNAME **dno_out);
+fsw_status_t fsw_dnode_create_with_tree(struct DNODESTRUCTNAME *parent_dno, fsw_u64 tree_id, fsw_u64 dnode_id, int type,
                               struct fsw_string *name, struct DNODESTRUCTNAME **dno_out);
 void         fsw_dnode_retain(struct fsw_dnode *dno);
 void         fsw_dnode_release(struct fsw_dnode *dno);
index a6e88bfbd962438e31b3337f38e064b3b2eec8ab..1b68b9977f4ca9607a1c6da8cd06f5e39c907835 100644 (file)
@@ -204,8 +204,8 @@ static fsw_status_t fsw_ext2_dnode_fill(struct fsw_ext2_volume *vol, struct fsw_
     FSW_MSG_DEBUG((FSW_MSGSTR("fsw_ext2_dnode_fill: inode %d\n"), dno->g.dnode_id));
 
     // read the inode block
-    groupno = (dno->g.dnode_id - 1) / vol->sb->s_inodes_per_group;
-    ino_in_group = (dno->g.dnode_id - 1) % vol->sb->s_inodes_per_group;
+    groupno = (fsw_u32) (dno->g.dnode_id - 1) / vol->sb->s_inodes_per_group;
+    ino_in_group = (fsw_u32) (dno->g.dnode_id - 1) % vol->sb->s_inodes_per_group;
     ino_bno = vol->inotab_bno[groupno] +
         ino_in_group / (vol->g.phys_blocksize / vol->inode_size);
     ino_index = ino_in_group % (vol->g.phys_blocksize / vol->inode_size);
index 42f136d763f0cfec7bb7ee4e80649860751e2506..0beaa4d80b68638786b076bbe89b8a36fd1b347a 100644 (file)
@@ -279,8 +279,8 @@ static fsw_status_t fsw_ext4_dnode_fill(struct fsw_ext4_volume *vol, struct fsw_
 
 
     // read the inode block
-    groupno = (dno->g.dnode_id - 1) / vol->sb->s_inodes_per_group;
-    ino_in_group = (dno->g.dnode_id - 1) % vol->sb->s_inodes_per_group;
+    groupno = (fsw_u32) (dno->g.dnode_id - 1) / vol->sb->s_inodes_per_group;
+    ino_in_group = (fsw_u32) (dno->g.dnode_id - 1) % vol->sb->s_inodes_per_group;
     ino_bno = vol->inotab_bno[groupno] +
         ino_in_group / (vol->g.phys_blocksize / vol->inode_size);
     ino_index = ino_in_group % (vol->g.phys_blocksize / vol->inode_size);
index 0637305345563eae10e570d499ec280e942259f8..263593f1e157bed8effc7bed1e7b31467fc383d3 100644 (file)
@@ -8,7 +8,7 @@
 #include "../include/refit_call_wrapper.h"
 
 #include "simple_file.h"
-#include "execute.h"    /* for generate_path() */
+//#include "execute.h"    /* for generate_path() */
 
 static EFI_GUID IMAGE_PROTOCOL = LOADED_IMAGE_PROTOCOL;
 static EFI_GUID SIMPLE_FS_PROTOCOL = SIMPLE_FILE_SYSTEM_PROTOCOL;
@@ -43,6 +43,57 @@ simple_file_open_by_handle(EFI_HANDLE device, CHAR16 *name, EFI_FILE **file, UIN
    return efi_status;
 }
 
+// generate_path() from shim by Matthew J. Garrett
+static
+EFI_STATUS
+generate_path(CHAR16* name, EFI_LOADED_IMAGE *li, EFI_DEVICE_PATH **path, CHAR16 **PathName)
+{
+        unsigned int pathlen;
+        EFI_STATUS efi_status = EFI_SUCCESS;
+        CHAR16 *devpathstr = DevicePathToStr(li->FilePath),
+                *found = NULL;
+        int i;
+
+        for (i = 0; i < StrLen(devpathstr); i++) {
+                if (devpathstr[i] == '/')
+                        devpathstr[i] = '\\';
+                if (devpathstr[i] == '\\')
+                        found = &devpathstr[i];
+        }
+        if (!found) {
+                pathlen = 0;
+        } else {
+                while (*(found - 1) == '\\')
+                        --found;
+                *found = '\0';
+                pathlen = StrLen(devpathstr);
+        }
+
+        if (name[0] != '\\')
+                pathlen++;
+
+        *PathName = AllocatePool((pathlen + 1 + StrLen(name))*sizeof(CHAR16));
+
+        if (!*PathName) {
+                Print(L"Failed to allocate path buffer\n");
+                efi_status = EFI_OUT_OF_RESOURCES;
+                goto error;
+        }
+
+        StrCpy(*PathName, devpathstr);
+
+        if (name[0] != '\\')
+                StrCat(*PathName, L"\\");
+        StrCat(*PathName, name);
+
+        *path = FileDevicePath(li->DeviceHandle, *PathName);
+
+error:
+        FreePool(devpathstr);
+
+        return efi_status;
+} // generate_path()
+
 EFI_STATUS
 simple_file_open(EFI_HANDLE image, CHAR16 *name, EFI_FILE **file, UINT64 mode)
 {
index 2e4e0d4f7f6976d1b861b565051904d0881fdf8f..b6029b99e658f7e0e498e4b0debd443cf49cb1f0 100644 (file)
@@ -144,7 +144,7 @@ static VOID AboutrEFInd(VOID)
 
     if (AboutMenu.EntryCount == 0) {
         AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
-        AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.6.12");
+        AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.6.12.1");
         AddMenuInfoLine(&AboutMenu, L"");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012-2013 Roderick W. Smith");
@@ -383,7 +383,7 @@ static EFI_STATUS RebootIntoFirmware(VOID) {
 // EFI OS loader functions
 //
 
-static VOID StartLoader(IN LOADER_ENTRY *Entry)
+static VOID StartLoader(LOADER_ENTRY *Entry)
 {
     UINTN ErrorInStep = 0;
 
@@ -1161,6 +1161,38 @@ static BOOLEAN IsSymbolicLink(REFIT_VOLUME *Volume, CHAR16 *Path, EFI_FILE_INFO
    return (DirEntry->FileSize != FileSize2);
 } // BOOLEAN IsSymbolicLink()
 
+// Returns TRUE if this file is a valid EFI loader file, and is proper ARCH
+static BOOLEAN IsValidLoader(REFIT_VOLUME *Volume, CHAR16 *FileName) {
+#if defined (EFIX64)
+#define EFI_STUB_ARCH   0x8664
+#else
+#define EFI_STUB_ARCH   0x14c
+#endif
+#define FAT_ARCH        0x0ef1fab9 /* ID for Apple "fat" binary */
+    EFI_STATUS      Status;
+    EFI_FILE_HANDLE FileHandle;
+    CHAR8           Header[512];
+    UINTN           Size = sizeof(Header);
+    BOOLEAN         IsValid;
+
+    Status = refit_call5_wrapper(Volume->RootDir->Open, Volume->RootDir, &FileHandle, FileName, EFI_FILE_MODE_READ, 0);
+    if (EFI_ERROR(Status))
+       return 0;
+
+    Status = refit_call3_wrapper(FileHandle->Read, FileHandle, &Size, Header);
+    refit_call1_wrapper(FileHandle->Close, FileHandle);
+
+    IsValid = !EFI_ERROR(Status) &&
+              Size == sizeof(Header) &&
+              ((Header[0] == 'M' && Header[1] == 'Z' &&
+               (Size = *(UINT32 *)&Header[0x3c]) < 0x180 &&
+               Header[Size] == 'P' && Header[Size+1] == 'E' &&
+               Header[Size+2] == 0 && Header[Size+3] == 0 &&
+               *(UINT16 *)&Header[Size+4] == EFI_STUB_ARCH) ||
+              (*(UINT32 *)&Header == FAT_ARCH));
+    return IsValid;
+} // BOOLEAN IsValidLoader()
+
 // Scan an individual directory for EFI boot loader files and, if found,
 // add them to the list. Exception: Ignores FALLBACK_FULLNAME, which is picked
 // up in ScanEfiFiles(). Sorts the entries within the loader directory so that
@@ -1196,6 +1228,12 @@ static BOOLEAN ScanLoaderDir(IN REFIT_VOLUME *Volume, IN CHAR16 *Path, IN CHAR16
           else
              SPrint(FileName, 255, L"\\%s", DirEntry->FileName);
           CleanUpPathNameSlashes(FileName);
+
+          if( /* (!StriSubCmp(L"vmlinuz", DirEntry->FileName) ||
+              !StriSubCmp(L"bzImage", DirEntry->FileName)) && */
+              !IsValidLoader(Volume, FileName))
+             continue;
+
           NewLoader = AllocateZeroPool(sizeof(struct LOADER_LIST));
           if (NewLoader != NULL) {
              NewLoader->FileName = StrDuplicate(FileName);