diff --git a/base/setup/usetup/bootsup.c b/base/setup/usetup/bootsup.c
index f681829..be968ab 100644
--- a/base/setup/usetup/bootsup.c
+++ b/base/setup/usetup/bootsup.c
@@ -81,9 +81,20 @@ typedef struct _FAT32_BOOTSECTOR
 
 typedef struct _EXT2_BOOTSECTOR
 {
-    // The EXT2 bootsector is completely user-specific.
-    // No FS data is stored there.
-    UCHAR Fill[1024];
+    UCHAR		JmpBoot[3];
+    UCHAR		BootDrive;
+    ULONG		Ext2VolumeStartSector;		// Start sector of the ext2 volume
+    ULONG		Ext2BlockSize;				// Block size in sectors
+    ULONG		Ext2BlockSizeInBytes;		// Block size in bytes
+    ULONG		Ext2PointersPerBlock;		// Number of block pointers that can be contained in one block
+    ULONG		Ext2GroupDescPerBlock;		// Number of group descriptors per block
+    ULONG		Ext2FirstDataBlock;			// First data block (1 for 1024-byte blocks, 0 for bigger sizes)
+    ULONG		Ext2InodesPerGroup;			// Number of inodes per group
+    ULONG		Ext2InodesPerBlock;			// Number of inodes per block
+    UCHAR		BootCodeAndData[473];		// The remainder of the boot sector
+    UCHAR		BootPartition;
+    USHORT		BootSectorMagic;			// 0xAA55
+    UCHAR		BootCodeAndData2[512];		// Second boot sector
 } EXT2_BOOTSECTOR, *PEXT2_BOOTSECTOR;
 
 // TODO: Add more bootsector structures!
@@ -1844,13 +1855,11 @@ InstallExt2BootCodeToDisk(
     IO_STATUS_BLOCK IoStatusBlock;
     HANDLE FileHandle;
     LARGE_INTEGER FileOffset;
-//  PEXT2_BOOTSECTOR OrigBootSector;
+    PEXT2_BOOTSECTOR OrigBootSector;
     PEXT2_BOOTSECTOR NewBootSector;
-    // USHORT BackupBootSector;
 
-#if 0
     /* Allocate buffer for original bootsector */
-    OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE);
+    OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, sizeof(EXT2_BOOTSECTOR));
     if (OrigBootSector == NULL)
         return STATUS_INSUFFICIENT_RESOURCES;
 
@@ -1891,13 +1900,12 @@ InstallExt2BootCodeToDisk(
         RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
         return Status;
     }
-#endif
 
-    /* Allocate buffer for new bootsector */
+    /* Allocate buffer for new bootsector (2 sectors) */
     NewBootSector = RtlAllocateHeap(ProcessHeap, 0, sizeof(EXT2_BOOTSECTOR));
     if (NewBootSector == NULL)
     {
-        // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
+        RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
@@ -1918,11 +1926,12 @@ InstallExt2BootCodeToDisk(
                         FILE_SYNCHRONOUS_IO_NONALERT);
     if (!NT_SUCCESS(Status))
     {
-        // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
+        RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
         RtlFreeHeap(ProcessHeap, 0, NewBootSector);
         return Status;
     }
 
+    FileOffset.QuadPart = 0ULL;
     Status = NtReadFile(FileHandle,
                         NULL,
                         NULL,
@@ -1930,31 +1939,39 @@ InstallExt2BootCodeToDisk(
                         &IoStatusBlock,
                         NewBootSector,
                         sizeof(EXT2_BOOTSECTOR),
-                        NULL,
+                        &FileOffset,
                         NULL);
     NtClose(FileHandle);
     if (!NT_SUCCESS(Status))
     {
-        // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
+        RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
         RtlFreeHeap(ProcessHeap, 0, NewBootSector);
         return Status;
     }
 
-#if 0
-    /* Adjust bootsector (copy a part of the FAT32 BPB) */
-    memcpy(&NewBootSector->OemName,
-           &OrigBootSector->OemName,
-           FIELD_OFFSET(FAT32_BOOTSECTOR, BootCodeAndData) -
-           FIELD_OFFSET(FAT32_BOOTSECTOR, OemName));
-
-    NewBootSector->HiddenSectors = PartitionList->CurrentDisk->SectorsPerTrack;
-
-    /* Get the location of the backup boot sector */
-    BackupBootSector = OrigBootSector->BackupBootSector;
-
+    /* Adjust bootsector (copy old BPB) */
+    NewBootSector->BootDrive = 0xff;
+    NewBootSector->BootPartition = 0x00;
+    NewBootSector->Ext2VolumeStartSector = OrigBootSector->Ext2VolumeStartSector;
+    NewBootSector->Ext2BlockSizeInBytes = OrigBootSector->Ext2BlockSizeInBytes;
+    NewBootSector->Ext2BlockSize = OrigBootSector->Ext2BlockSize;
+    NewBootSector->Ext2PointersPerBlock = OrigBootSector->Ext2PointersPerBlock;
+    NewBootSector->Ext2GroupDescPerBlock = OrigBootSector->Ext2GroupDescPerBlock;
+    NewBootSector->Ext2FirstDataBlock = OrigBootSector->Ext2FirstDataBlock;
+    NewBootSector->Ext2InodesPerGroup = OrigBootSector->Ext2InodesPerGroup;
+    NewBootSector->Ext2InodesPerBlock = OrigBootSector->Ext2InodesPerBlock;
+    DPRINT("bootsup: NewBootSector %ld\n", sizeof(*NewBootSector));
+    DPRINT("bootsup: StartSector %ld\n", NewBootSector->Ext2VolumeStartSector);
+    DPRINT("bootsup: BlockSizeInBytes %ld\n", NewBootSector->Ext2BlockSizeInBytes);
+    DPRINT("bootsup: BlockSize %ld\n", NewBootSector->Ext2BlockSize);
+    DPRINT("bootsup: PointersPerBlock %ld\n", NewBootSector->Ext2PointersPerBlock);
+    DPRINT("bootsup: GroupDescPerBlock %ld\n", NewBootSector->Ext2GroupDescPerBlock);
+    DPRINT("bootsup: FirstDataBlock %ld\n", NewBootSector->Ext2FirstDataBlock);
+    DPRINT("bootsup: InodesPerGroup %ld\n", NewBootSector->Ext2InodesPerGroup);
+    DPRINT("bootsup: InodesPerBlock %ld\n", NewBootSector->Ext2InodesPerBlock);
+    DPRINT("bootsup: BootSectorMagic %x\n", NewBootSector->BootSectorMagic);
     /* Free the original boot sector */
-    // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
-#endif
+    RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
 
     /* Write new bootsector to RootPath */
     RtlInitUnicodeString(&Name, RootPath);
@@ -1998,30 +2015,8 @@ InstallExt2BootCodeToDisk(
         return Status;
     }
 
-    /* Write backup boot sector */
-    if ((BackupBootSector != 0x0000) && (BackupBootSector != 0xFFFF))
-    {
-        FileOffset.QuadPart = (ULONGLONG)((ULONG)BackupBootSector * SECTORSIZE);
-        Status = NtWriteFile(FileHandle,
-                             NULL,
-                             NULL,
-                             NULL,
-                             &IoStatusBlock,
-                             NewBootSector,
-                             SECTORSIZE,
-                             &FileOffset,
-                             NULL);
-        if (!NT_SUCCESS(Status))
-        {
-            DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
-            NtClose(FileHandle);
-            RtlFreeHeap(ProcessHeap, 0, NewBootSector);
-            return Status;
-        }
-    }
-
-    /* Write sector 14 */
-    FileOffset.QuadPart = 14 * SECTORSIZE;
+    /* Write sector 1 */
+    FileOffset.QuadPart = SECTORSIZE;
     Status = NtWriteFile(FileHandle,
                          NULL,
                          NULL,
@@ -2031,11 +2026,11 @@ InstallExt2BootCodeToDisk(
                          SECTORSIZE,
                          &FileOffset,
                          NULL);
+#endif
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
     }
-#endif
     NtClose(FileHandle);
 
     /* Free the new boot sector */
diff --git a/base/setup/usetup/fslist.c b/base/setup/usetup/fslist.c
index 99fe2f8..ed1f80b 100644
--- a/base/setup/usetup/fslist.c
+++ b/base/setup/usetup/fslist.c
@@ -142,7 +142,7 @@ GetFileSystem(
     }
 
     // HACK: WARNING: We cannot write on this FS yet!
-    if (PartEntry->PartitionType == PARTITION_EXT2 || PartEntry->PartitionType == PARTITION_IFS)
+    if (PartEntry->PartitionType == PARTITION_IFS)
         DPRINT1("Recognized file system %S that doesn't support write support yet!\n", FileSystemName);
 
     DPRINT1("GetFileSystem -- PartitionType: 0x%02X ; FileSystemName (guessed): %S\n",
diff --git a/base/setup/usetup/interface/usetup.c b/base/setup/usetup/interface/usetup.c
index 3808556..0e0098d 100644
--- a/base/setup/usetup/interface/usetup.c
+++ b/base/setup/usetup/interface/usetup.c
@@ -2980,7 +2980,6 @@ FormatPartitionPage(PINPUT_RECORD Ir)
                 DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType = PartEntry->PartitionType;
                 DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE;
             }
-#if 0
             else if (wcscmp(PartEntry->FileSystem->FileSystemName, L"EXT2") == 0)
             {
                 PartEntry->PartitionType = PARTITION_EXT2;
@@ -2989,6 +2988,7 @@ FormatPartitionPage(PINPUT_RECORD Ir)
                 DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType = PartEntry->PartitionType;
                 DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE;
             }
+#if 0
             else if (wcscmp(PartEntry->FileSystem->FileSystemName, L"NTFS") == 0)
             {
                 PartEntry->PartitionType = PARTITION_IFS;
@@ -3663,7 +3663,7 @@ PrepareCopyPageInfFile(HINF InfFile,
             Status = SetupCreateDirectory(PathBuffer);
             if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION)
             {
-                DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status);
+                DPRINT1("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status);
                 MUIDisplayError(ERROR_CREATE_DIR, Ir, POPUP_WAIT_ENTER);
                 return FALSE;
             }
@@ -3689,7 +3689,7 @@ PrepareCopyPageInfFile(HINF InfFile,
             Status = SetupCreateDirectory(PathBuffer);
             if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION)
             {
-                DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status);
+                DPRINT1("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status);
                 MUIDisplayError(ERROR_CREATE_DIR, Ir, POPUP_WAIT_ENTER);
                 return FALSE;
             }
diff --git a/base/setup/usetup/native/fslist.c b/base/setup/usetup/native/fslist.c
index 4d9b655..40e610b 100644
--- a/base/setup/usetup/native/fslist.c
+++ b/base/setup/usetup/native/fslist.c
@@ -5,8 +5,8 @@ NATIVE_CreateFileSystemList(
     IN PFILE_SYSTEM_LIST List)
 {
     FS_AddProvider(List, L"FAT", VfatFormat, VfatChkdsk);
-#if 0
     FS_AddProvider(List, L"EXT2", Ext2Format, Ext2Chkdsk);
+#if 0
     FS_AddProvider(List, L"NTFS", NtfsFormat, NtfsChkdsk);
 #endif
     return TRUE;
diff --git a/base/setup/usetup/partlist.c b/base/setup/usetup/partlist.c
index b047a22..a51d8f4 100644
--- a/base/setup/usetup/partlist.c
+++ b/base/setup/usetup/partlist.c
@@ -3344,8 +3344,7 @@ CheckActiveSystemPartition(
     }
     // HACK: WARNING: We cannot write on this FS yet!
     // See fslist.c:GetFileSystem()
-    if (List->OriginalSystemPartition->PartitionType == PARTITION_EXT2 ||
-        List->OriginalSystemPartition->PartitionType == PARTITION_IFS)
+    if (List->OriginalSystemPartition->PartitionType == PARTITION_IFS)
     {
         DPRINT1("Recognized file system %S that doesn't support write support yet!\n",
                 FileSystem->FileSystemName);
diff --git a/boot/bootdata/txtsetup.sif b/boot/bootdata/txtsetup.sif
index 7a86bef..8aeb876 100644
--- a/boot/bootdata/txtsetup.sif
+++ b/boot/bootdata/txtsetup.sif
@@ -67,6 +67,7 @@ ntdll.dll=,,,,,,,,,,,,2
 wmilib.sys=,,,,,,,,,,,,4
 ksecdd.sys=,,,,,,,,,,,,4
 mountmgr.sys=,,,,,,x,,,,,,4
+ext2fs.sys=,,,,,,x,,,,,,4
 
 [SystemPartitionFiles]
 
@@ -132,7 +133,7 @@ Cabinet=reactos.cab
 [SetupData]
 DefaultPath = \ReactOS
 OsLoadOptions = "/NOGUIBOOT /NODEBUG"
-DbgOsLoadOptions = "/NOGUIBOOT /KDSERIAL /DEBUGPORT=COM1 /FIRSTCHANCE"
+DbgOsLoadOptions = "/NOGUIBOOT /DEBUGPORT=COM1 /FIRSTCHANCE"
 ;DbgOsLoadOptions = "/SOS /DEBUGPORT=SCREEN"
 ;DbgOsLoadOptions = "/NOGUIBOOT /DEBUGPORT=BOCHS"
 
diff --git a/boot/freeldr/bootsect/CMakeLists.txt b/boot/freeldr/bootsect/CMakeLists.txt
index f76ac7a..b1156ad 100644
--- a/boot/freeldr/bootsect/CMakeLists.txt
+++ b/boot/freeldr/bootsect/CMakeLists.txt
@@ -2,7 +2,7 @@
 if(ARCH STREQUAL "i386" OR ARCH STREQUAL "amd64")
 
     CreateBootSectorTarget(dosmbr ${CMAKE_CURRENT_SOURCE_DIR}/dosmbr.S ${CMAKE_CURRENT_BINARY_DIR}/dosmbr.bin 7c00)
-    CreateBootSectorTarget(ext2 ${CMAKE_CURRENT_SOURCE_DIR}/ext2.S ${CMAKE_CURRENT_BINARY_DIR}/ext2.bin 0)
+    CreateBootSectorTarget(ext2 ${CMAKE_CURRENT_SOURCE_DIR}/ext2.S ${CMAKE_CURRENT_BINARY_DIR}/ext2.bin 7c00)
 
     CreateBootSectorTarget(fat ${CMAKE_CURRENT_SOURCE_DIR}/fat.S ${CMAKE_CURRENT_BINARY_DIR}/fat.bin 7c00)
     CreateBootSectorTarget(fat32 ${CMAKE_CURRENT_SOURCE_DIR}/fat32.S ${CMAKE_CURRENT_BINARY_DIR}/fat32.bin 7c00)
diff --git a/boot/freeldr/bootsect/ext2.S b/boot/freeldr/bootsect/ext2.S
index bd3119c..02a7d0a 100644
--- a/boot/freeldr/bootsect/ext2.S
+++ b/boot/freeldr/bootsect/ext2.S
@@ -8,8 +8,12 @@
 // [bp-0x10] Here we will store the number of LBA sectors read
 
 #include <asm.inc>
+#include <freeldr/include/arch/pc/x86common.h>
 .code16
 
+#define BP_REL(x) [bp+x-offset start]
+#define BP_REL_SP(x) [bp-x]
+
 SECTORS_PER_TRACK		= HEX(04)
 NUMBER_OF_HEADS			= HEX(08)
 BIOS_CHS_DRIVE_SIZE		= HEX(0C)
@@ -34,12 +38,12 @@ BootDrive:
 //SectorsPerTrack		db 63					// Moved to [bp-SECTORS_PER_TRACK]
 //NumberOfHeads			dw 16					// Moved to [bp-NUMBER_OF_HEADS]
 //BiosCHSDriveSize		dd (1024 * 1024 * 63)	// Moved to [bp-BIOS_CHS_DRIVE_SIZE]
-//LBASectorsRead			dd 0					// Moved to [bp-LBA_SECTORS_READ]
+//LBASectorsRead		dd 0					// Moved to [bp-LBA_SECTORS_READ]
 
 Ext2VolumeStartSector:
-	.long 263088				// Start sector of the ext2 volume
+	.long 63					// Start sector of the ext2 volume
 Ext2BlockSize:
-	.long 2					// Block size in sectors
+	.long 2						// Block size in sectors
 Ext2BlockSizeInBytes:
 	.long 1024					// Block size in bytes
 Ext2PointersPerBlock:
@@ -47,11 +51,11 @@ Ext2PointersPerBlock:
 Ext2GroupDescPerBlock:
 	.long 32					// Number of group descriptors per block
 Ext2FirstDataBlock:
-	.long 1					// First data block (1 for 1024-byte blocks, 0 for bigger sizes)
+	.long 1						// First data block (1 for 1024-byte blocks, 0 for bigger sizes)
 Ext2InodesPerGroup:
-	.long 2048					// Number of inodes per group
+	.long 1024					// Number of inodes per group
 Ext2InodesPerBlock:
-	.long 8					// Number of inodes per block
+	.long 8						// Number of inodes per block
 
 Ext2ReadEntireFileLoadSegment:
 	.word	0
@@ -71,17 +75,17 @@ main:
         mov sp, HEX(7b00)            // Setup a stack
 
         mov si, offset BootDrive
-		cmp byte ptr [si], HEX(0ff)	// If they have specified a boot drive then use it
+		cmp byte ptr ds:[si], HEX(0ff)	// If they have specified a boot drive then use it
 		jne GetDriveParameters
 
-        mov [si],dl				// Save the boot drive
+        mov ds:[si],dl				// Save the boot drive
 
 
 GetDriveParameters:
 		mov  ah, 8
-		mov  dl,[si]					// Get boot drive in dl
-		int  HEX(13)									// Request drive parameters from the bios
-		jnc  CalcDriveSize							// If the call succeeded then calculate the drive size
+		mov  dl,ds:[si]				// Get boot drive in dl
+		int  HEX(13)				// Request drive parameters from the bios
+		jnc  CalcDriveSize			// If the call succeeded then calculate the drive size
 
 		// If we get here then the call to the BIOS failed
 		// so just set CHS equal to the maximum addressable
@@ -95,21 +99,21 @@ CalcDriveSize:
 		mov  bl,ch								// Put the low 8-bits of the cylinder count into BL
 		mov  bh,cl								// Put the high 2-bits in BH
 		shr  bh,6								// Shift them into position, now BX contains the cylinder count
-		and  cl, HEX(3f)								// Mask off cylinder bits from sector count
+		and  cl, HEX(3f)						// Mask off cylinder bits from sector count
 		// CL now contains sectors per track and DH contains head count
 		movzx eax,dh							// Move the heads into EAX
 		movzx ebx,bx							// Move the cylinders into EBX
 		movzx ecx,cl							// Move the sectors per track into ECX
 		inc   eax								// Make it one based because the bios returns it zero based
-		mov   [bp-NUMBER_OF_HEADS],eax		// Save number of heads
-		mov   [bp-SECTORS_PER_TRACK],ecx	// Save number of sectors per track
+		mov   dword ptr BP_REL_SP(NUMBER_OF_HEADS),eax	// Save number of heads
+		mov   dword ptr BP_REL_SP(SECTORS_PER_TRACK),ecx	// Save number of sectors per track
 		inc   ebx								// Make the cylinder count one based also
 		mul   ecx								// Multiply heads with the sectors per track, result in edx:eax
 		mul   ebx								// Multiply the cylinders with (heads * sectors) [stored in edx:eax already]
 
 		// We now have the total number of sectors as reported
 		// by the bios in eax, so store it in our variable
-		mov   [bp-BIOS_CHS_DRIVE_SIZE],eax
+		mov   dword ptr BP_REL_SP(BIOS_CHS_DRIVE_SIZE),eax
 
 
 LoadExtraBootCode:
@@ -119,7 +123,7 @@ LoadExtraBootCode:
 		xor  eax,eax
 		inc  eax								// Read logical sector 1, EAX now = 1
 		mov  cx,1								// Read one sector
-		mov  bx, HEX(7e00)							// Read sector to [0000:7e00h]
+		mov  bx, HEX(7e00)						// Read sector to [0000:7e00h]
 		call ReadSectors
 
 		jmp  LoadRootDirectory
@@ -133,8 +137,8 @@ LoadExtraBootCode:
 Ext2ReadGroupDesc:
 		shl   eax,5										// Group = (Group * sizeof(GROUP_DESCRIPTOR) /* 32 */)
 		xor   edx,edx
-		div   dword ptr [bp+Ext2GroupDescPerBlock]		// Group = (Group / Ext2GroupDescPerBlock)
-		add   eax, dword ptr [bp+Ext2FirstDataBlock]	// Group = Group + Ext2FirstDataBlock + 1
+		div   dword ptr BP_REL(Ext2GroupDescPerBlock)	// Group = (Group / Ext2GroupDescPerBlock)
+		add   eax, dword ptr BP_REL(Ext2FirstDataBlock)	// Group = Group + Ext2FirstDataBlock + 1
 		inc   eax										// EAX now has the group descriptor block number
 														// EDX now has the group descriptor offset in the block
 
@@ -154,7 +158,7 @@ Ext2ReadGroupDesc:
 // Reads ext2 block into ES:[BX]
 // EAX has logical block number to read
 Ext2ReadBlock:
-		mov   ecx, dword ptr [bp+Ext2BlockSize]
+		mov   ecx, dword ptr BP_REL(Ext2BlockSize)
 		mul   ecx
 		jmp   ReadSectors
 
@@ -165,11 +169,14 @@ Ext2ReadBlock:
 Ext2ReadInode:
 		dec   eax										// Inode = Inode - 1
 		xor   edx,edx
-		div   dword ptr [bp+Ext2InodesPerGroup]		// Inode = (Inode / Ext2InodesPerGroup)
-		mov   ebx,eax									// EBX now has the inode group number
-		mov   eax,edx
-		xor   edx,edx
-		div   dword ptr [bp+Ext2InodesPerBlock]		// Inode = (Inode / Ext2InodesPerBlock)
+		div   dword ptr BP_REL(Ext2InodesPerGroup)		// Inode = (Inode / Ext2InodesPerGroup)
+		push  edx										// Push remainder of the division
+		mul   dword ptr BP_REL(Ext2InodesPerGroup)		// Group = Group * Ext2InodesPerGroup
+		mul   dword ptr BP_REL(Ext2InodesPerBlock)		// Group = Group * Ext2InodesPerBlock
+		mov   ebx,eax									// EBX now has the inode group block number
+		pop   eax										// Pop reminder in eax
+		// xor   edx,edx									// Skip 
+		div   dword ptr BP_REL(Ext2InodesPerBlock)		// Inode = (Inode / Ext2InodesPerBlock)
 		shl   edx,7										// FIXME: InodeOffset *= 128 (make the array index a byte offset)
 														// EAX now has the inode offset block number from inode table
 														// EDX now has the inode offset in the block
@@ -179,7 +186,9 @@ Ext2ReadInode:
 		push  edx
 		push  eax
 		mov   eax,ebx
+		push  ebx
 		call  Ext2ReadGroupDesc
+		pop   ebx
 
 		// Group descriptor has been read, now
 		// grab the inode table block number from it
@@ -187,7 +196,8 @@ Ext2ReadInode:
 		pop   es
 		mov   di, HEX(8008)
 		pop   eax										// Restore inode offset block number from stack
-		add   eax, es:[di]							// Add the inode table start block
+		add   eax, ebx									// Add the group start block number
+		add   eax, es:[di]								// Add the inode table start block
 
 		// Adjust the read offset so that the
 		// inode we want is read to 6000:8000
@@ -206,8 +216,8 @@ Ext2ReadInode:
 // EAX has logical sector number to read
 // CX has number of sectors to read
 ReadSectors:
-        add  eax, dword ptr [bp+Ext2VolumeStartSector]	// Add the start of the volume
-		cmp  eax, [bp-BIOS_CHS_DRIVE_SIZE]		// Check if they are reading a sector outside CHS range
+        add  eax, dword ptr BP_REL(Ext2VolumeStartSector)	// Add the start of the volume
+		cmp  eax, dword ptr BP_REL_SP(BIOS_CHS_DRIVE_SIZE)	// Check if they are reading a sector outside CHS range
 		jae  ReadSectorsLBA						// Yes - go to the LBA routine
 												// If at all possible we want to use LBA routines because
 												// They are optimized to read more than 1 sector per read
@@ -217,7 +227,7 @@ ReadSectors:
 CheckInt13hExtensions:							// Now check if this computer supports extended reads
 		mov  ah, HEX(41)						// AH = 41h
 		mov  bx, HEX(55aa)						// BX = 55AAh
-		mov  dl, byte ptr [bp+BootDrive]					// DL = drive (80h-FFh)
+		mov  dl, byte ptr BP_REL(BootDrive)		// DL = drive (80h-FFh)
 		int  HEX(13)							// IBM/MS INT 13 Extensions - INSTALLATION CHECK
 		jc   ReadSectorsCHS						// CF set on error (extensions not supported)
 		cmp  bx, HEX(0aa55)						// BX = AA55h if installed
@@ -230,13 +240,13 @@ CheckInt13hExtensions:							// Now check if this computer supports extended rea
 ReadSectorsLBA:
 		pushad									// Save logical sector number & sector count
 
-		cmp  cx, 64							// Since the LBA calls only support 0x7F sectors at a time we will limit ourselves to 64
+		cmp  cx, 64								// Since the LBA calls only support 0x7F sectors at a time we will limit ourselves to 64
 		jbe  ReadSectorsSetupDiskAddressPacket	// If we are reading less than 65 sectors then just do the read
 		mov  cx,64								// Otherwise read only 64 sectors on this loop iteration
 
 ReadSectorsSetupDiskAddressPacket:
-		mov  [bp-LBA_SECTORS_READ],cx
-		mov  word ptr [bp-LBA_SECTORS_READ+2],0
+		mov  word ptr BP_REL_SP(LBA_SECTORS_READ),cx
+		mov  word ptr BP_REL_SP(LBA_SECTORS_READ+2),0
 		data32 push 0
 		push eax								// Put 64-bit logical block address on stack
 		push es									// Put transfer segment on stack
@@ -246,9 +256,9 @@ ReadSectorsSetupDiskAddressPacket:
 		mov  si,sp								// Setup disk address packet on stack
 
 
-        mov  dl, byte ptr [bp+BootDrive]					// Drive number
-		mov  ah, HEX(42)								// Int 13h, AH = 42h - Extended Read
-		int  HEX(13)								// Call BIOS
+        mov  dl, byte ptr BP_REL(BootDrive)		// Drive number
+		mov  ah, HEX(42)						// Int 13h, AH = 42h - Extended Read
+		int  HEX(13)							// Call BIOS
 		jc   PrintDiskError						// If the read failed then abort
 
 		add  sp, 16								// Remove disk address packet from stack
@@ -256,7 +266,7 @@ ReadSectorsSetupDiskAddressPacket:
 		popad									// Restore sector count & logical sector number
 
 		push bx
-		mov  ebx, [bp-LBA_SECTORS_READ]
+		mov  ebx, dword ptr BP_REL_SP(LBA_SECTORS_READ)
         add  eax,ebx							// Increment sector to read
 		shl  ebx,5
         mov  dx,es
@@ -264,7 +274,7 @@ ReadSectorsSetupDiskAddressPacket:
         mov  es,dx
 		pop  bx
 
-		sub  cx,[bp-LBA_SECTORS_READ]
+		sub  cx,word ptr BP_REL_SP(LBA_SECTORS_READ)
         jnz  ReadSectorsLBA						// Read next sector
 
         ret
@@ -279,15 +289,15 @@ ReadSectorsCHS:
 ReadSectorsCHSLoop:
         pushad
         xor   edx,edx
-		mov   ecx, [bp-SECTORS_PER_TRACK]
+		mov   ecx, dword ptr BP_REL_SP(SECTORS_PER_TRACK)
 		div   ecx									// Divide logical by SectorsPerTrack
         inc   dl									// Sectors numbering starts at 1 not 0
 		mov   cl,dl									// Sector in CL
 		mov   edx,eax
 		shr   edx,16
-        div   word ptr [bp-NUMBER_OF_HEADS]		// Divide logical by number of heads
+        div   word ptr BP_REL_SP(NUMBER_OF_HEADS)	// Divide logical by number of heads
         mov   dh,dl									// Head in DH
-        mov   dl, byte ptr [bp+BootDrive]				// Drive number in DL
+        mov   dl, byte ptr BP_REL(BootDrive)		// Drive number in DL
         mov   ch,al									// Cylinder in CX
         ror   ah,2									// Low 8 bits of cylinder in CH, high 2 bits
                 									//  in CL shifted to bits 6 & 7
@@ -318,12 +328,12 @@ ReadSectorsCHSLoop:
 // Displays a disk error message
 // And reboots
 PrintDiskError:
-        mov  si,msgDiskError			// Bad boot disk message
-        call PutChars					// Display it
+        mov  si,offset msgDiskError			// Bad boot disk message
+        call PutChars						// Display it
 
 Reboot:
-        mov  si,msgAnyKey				// Press any key message
-        call PutChars					// Display it
+        mov  si,offset msgAnyKey			// Press any key message
+        call PutChars						// Display it
         xor ax,ax
         int HEX(16)							// Wait for a keypress
         int HEX(19)							// Reboot
@@ -349,11 +359,11 @@ Done:
 
 
 msgDiskError:
-    .ascii "Disk error", NUL
+    .ascii "Err", NUL
 // Sorry, need the space...
 //msgAnyKey			db 'Press any key to restart',0
 msgAnyKey:
-    .ascii "Press key", NUL
+    .ascii "Key", NUL
 
 //    times 509-($-$$) db 0   // Pad to 509 bytes
     .org 509
@@ -388,14 +398,14 @@ LoadRootDirectory:
 		push eax
 
 		// Now that the inode has been read in load
-		// the root directory file data to 0000:8000
+		// the root directory file data to 0000:F800
 		call Ext2ReadEntireFile
 
-		// Since the root directory was loaded to 0000:8000
-		// then add 8000h to the root directory's size
+		// Since the root directory was loaded to 0000:F800
+		// then add F800h to the root directory's size
 		pop  eax
-		mov  edx, HEX(8000)					// Set EDX to the current offset in the root directory
-		add  eax,edx					// Initially add 8000h to the size of the root directory
+		mov  edx, HEX(F800)				// Set EDX to the current offset in the root directory
+		add  eax,edx					// Initially add F800h to the size of the root directory
 
 SearchRootDirectory:
 		push edx						// Save current offset in root directory
@@ -410,9 +420,9 @@ SearchRootDirectory:
 		mov  es,ax
 		mov  di,dx
 		push di							// Save the start of the directory entry
-		add  di, 8					// Add the offset to the filename
-		mov  si,filename
-		mov  cl,11
+		add  di, 8						// Add the offset to the filename
+		mov  si,offset msgFreeLdr		// Filename is contained in the message
+		mov  cx,11						// In first 11 bytes
 		repe cmpsb						// Compare the file names
 		pop  di
 		pop  eax
@@ -437,53 +447,66 @@ FoundFile:
 		pop  es
 		pop  di							// These were saved earlier
 
-		mov  cx, es:[di]					// Get the file mode so we can make sure it's a regular file
+		mov  cx, es:[di]				// Get the file mode so we can make sure it's a regular file
 		and  ch,EXT2_S_IFMT				// Mask off everything but the file type
 		cmp  ch,EXT2_S_IFREG			// Make sure it's a regular file
 		je   LoadFreeLoader
 		jmp  PrintRegFileError
 
 LoadFreeLoader:
-        mov  si,msgLoading				// "Loading FreeLoader..." message
-        call PutChars					// Display it
+		mov  si,offset msgLoading		// "Loading FreeLoader..." message
+		call PutChars					// Display it
 
-		call Ext2ReadEntireFile			// Read freeldr.sys to 0000:8000
+		call Ext2ReadEntireFile			// Read freeldr.sys to 0000:F800
 
-        mov  dl, byte ptr [bp+BootDrive]
-		mov  dh, byte ptr [bp+BootPartition]
-		push 0						// push segment (0x0000)
-		mov eax, [HEX(8000) + HEX(0A8)]	// load the RVA of the EntryPoint into eax
-		add eax, HEX(8000)				// RVA -> VA
-		push ax						// push offset
-		retf						// Transfer control to FreeLoader
+		mov  dl, byte ptr BP_REL(BootDrive)
+		mov  dh, byte ptr BP_REL(BootPartition)
+		/* Transfer execution to the bootloader */
+		ljmp16 0, FREELDR_BASE
 
 
 
 
 
-// Reads ext2 file data into [0000:8000]
+// Reads ext2 file data into [0000:F800]
 // This function assumes that the file's
 // inode has been read in to 6000:8000 *and*
 // ES:DI points to 6000:8000
 // This will load all the blocks up to
 // and including the double-indirect pointers.
 // This should be sufficient because it
-// allows for ~64MB which is much bigger
+// allows for ~64MB file which is much bigger
 // than we need for a boot loader.
+// Problem is that space in memory is "only"
+// 0000:F800-6000:8000 which is 362,496 bytes
+// 0000:F800 is the start address for freeldr
+// 6000:8000 is the space where inode data is read
+// 7000:0000-7000:8000 temporary data (indirect
+// list pointers that point to the actual sectors)
+// 7000:8000-8000:0000 temporary data (indirect
+// sector data to be moved to proper memory location)
+// MSVC currently produces 376,832 bytes
+// GCC  currently produces 346,112 bytes
+// for freeldr.sys so basically we either
+// have to "optimize" for space MSVC or
+// free some space by moving data reads up
+// (for example to 8000:0000 and 8000:8000)
+// I think at 9000:0000 something else starts
+// and we will have 460,800 bytes in memory
 Ext2ReadEntireFile:
 
 		// Reset the load segment
-		mov word ptr [bp+Ext2ReadEntireFileLoadSegment], HEX(800)
+		mov word ptr BP_REL(Ext2ReadEntireFileLoadSegment), FREELDR_BASE / 16
 
 		// Now we must calculate how
 		// many blocks to read in
 		// We will do this by rounding the
 		// file size up to the next block
 		// size and then dividing by the block size
-		mov  eax, dword ptr [bp+Ext2BlockSizeInBytes]		// Get the block size in bytes
+		mov  eax, dword ptr BP_REL(Ext2BlockSizeInBytes)	// Get the block size in bytes
 		push eax
 		dec  eax											// Ext2BlockSizeInBytes -= 1
-		add  eax, es:[di+4]							// Add the file size
+		add  eax, es:[di+4]									// Add the file size
 		xor  edx,edx
 		pop  ecx											// Divide by the block size in bytes
 		div  ecx											// EAX now contains the number of blocks to load
@@ -496,10 +519,10 @@ Ext2ReadEntireFile:
 
 Ext2ReadEntireFile2:
 		// Save the indirect & double indirect pointers
-		mov  edx, es:[di+ HEX(58)]							// Get indirect pointer
-		mov dword ptr [bp+Ext2InodeIndirectPointer], edx			// Save indirect pointer
-		mov  edx, es:[di+ HEX(5c)]							// Get double indirect pointer
-		mov dword ptr [bp+Ext2InodeDoubleIndirectPointer],edx	// Save double indirect pointer
+		mov  edx, dword ptr es:[di+ HEX(58)]						// Get indirect pointer
+		mov dword ptr BP_REL(Ext2InodeIndirectPointer), edx			// Save indirect pointer
+		mov  edx, dword ptr es:[di+ HEX(5c)]						// Get double indirect pointer
+		mov dword ptr BP_REL(Ext2InodeDoubleIndirectPointer),edx	// Save double indirect pointer
 
 		// Now copy the direct pointers to 7000:0000
 		// so that we can call Ext2ReadDirectBlocks
@@ -529,8 +552,8 @@ Ext2ReadEntireFile2:
 		// Now we have read all the direct blocks in
 		// the inode. So now we have to read the indirect
 		// block and read all it's direct blocks
-		push eax											// Save the total block count
-		mov  eax, dword ptr [bp+Ext2InodeIndirectPointer]	// Get the indirect block pointer
+		push eax												// Save the total block count
+		mov  eax, dword ptr BP_REL(Ext2InodeIndirectPointer)	// Get the indirect block pointer
 		push HEX(7000)
 		pop  es
 		xor  bx,bx											// Set the load address to 7000:0000
@@ -539,7 +562,7 @@ Ext2ReadEntireFile2:
 		// Now we have all the block pointers from the
 		// indirect block in the right location so read them in
 		pop  eax											// Restore the total block count
-		mov  ecx, dword ptr [bp+Ext2PointersPerBlock]		// Get the number of block pointers that one block contains
+		mov  ecx, dword ptr BP_REL(Ext2PointersPerBlock)	// Get the number of block pointers that one block contains
 		call Ext2ReadDirectBlockList
 
 		// Check to see if we actually have
@@ -552,8 +575,8 @@ Ext2ReadEntireFile2:
 		// we have to read the double indirect block
 		// and read all it's indirect blocks
 		// (whew, it's a good thing I don't support triple indirect blocks)
-		mov dword ptr [bp+Ext2BlocksLeftToRead],eax				// Save the total block count
-		mov eax, dword ptr [bp+Ext2InodeDoubleIndirectPointer]	// Get the double indirect block pointer
+		mov dword ptr BP_REL(Ext2BlocksLeftToRead),eax				// Save the total block count
+		mov eax, dword ptr BP_REL(Ext2InodeDoubleIndirectPointer)	// Get the double indirect block pointer
 		push HEX(7800)
 		pop  es
 		push es												// Save an extra copy of this value on the stack
@@ -576,10 +599,10 @@ Ext2ReadIndirectBlock:
 
 		// Now we have all the block pointers from the
 		// indirect block in the right location so read them in
-		mov  eax, dword ptr [bp+Ext2BlocksLeftToRead]		// Restore the total block count
-		mov  ecx, dword ptr [bp+Ext2PointersPerBlock]		// Get the number of block pointers that one block contains
+		mov  eax, dword ptr BP_REL(Ext2BlocksLeftToRead)		// Restore the total block count
+		mov  ecx, dword ptr BP_REL(Ext2PointersPerBlock)		// Get the number of block pointers that one block contains
 		call Ext2ReadDirectBlockList
-		mov  dword ptr [bp+Ext2BlocksLeftToRead],eax				// Save the total block count
+		mov  dword ptr BP_REL(Ext2BlocksLeftToRead),eax			// Save the total block count
 		pop  di
 		pop  es
 
@@ -622,17 +645,17 @@ Ext2ReadDirectBlocks:
 
 Ext2ReadDirectBlocksLoop:
 		mov  eax,es:[di]									// Get direct block pointer from array
-		add  di, 4										// Update DI for next array index
+		add  di, 4											// Update DI for next array index
 
 		push cx												// Save number of direct blocks left
 		push es												// Save array segment
 		push di												// Save array offset
-		mov  es,[bp+Ext2ReadEntireFileLoadSegment]
+		mov  es, word ptr BP_REL(Ext2ReadEntireFileLoadSegment)
 		xor  bx,bx											// Setup load address for next read
 
 		call Ext2ReadBlock									// Read the block (this updates ES for the next read)
 
-		mov  [bp+Ext2ReadEntireFileLoadSegment],es		// Save updated ES
+		mov  word ptr BP_REL(Ext2ReadEntireFileLoadSegment),es		// Save updated ES
 
 		pop  di												// Restore the array offset
 		pop  es												// Restore the array segment
@@ -650,21 +673,21 @@ Ext2ReadDirectBlocksLoop:
 // Displays a file not found error message
 // And reboots
 PrintFileNotFound:
-        mov  si,msgFreeLdr      // FreeLdr not found message
+        mov  si,offset msgFreeLdr      // FreeLdr not found message
 		jmp short DisplayItAndReboot
 
 // Displays a file size is 0 error
 // And reboots
 PrintFileSizeError:
-        mov  si,msgFileSize     // Error message
+        mov  si,offset msgFileSize     // Error message
 		jmp short DisplayItAndReboot
 
 // Displays a file is not a regular file error
 // And reboots
 PrintRegFileError:
-        mov  si,msgRegFile      // Error message
+        mov  si,offset msgRegFile      // Error message
 DisplayItAndReboot:
-        call PutChars           // Display it
+        call PutChars                  // Display it
 		jmp  Reboot
 
 msgFreeLdr:
@@ -672,9 +695,7 @@ msgFreeLdr:
 msgFileSize:
     .ascii "File size 0", NUL
 msgRegFile:
-    .ascii "freeldr.sys isnt a regular file", NUL
-filename:
-    .ascii "freeldr.sys"
+    .ascii "freeldr.sys isn't a regular file", NUL
 msgLoading:
     .ascii "Loading...", NUL
 
diff --git a/boot/freeldr/freeldr/include/fs/ext2.h b/boot/freeldr/freeldr/include/fs/ext2.h
index c320000..2bf9af7 100644
--- a/boot/freeldr/freeldr/include/fs/ext2.h
+++ b/boot/freeldr/freeldr/include/fs/ext2.h
@@ -231,7 +231,7 @@ typedef struct
     ULONGLONG    FileSize;        // File size
     ULONGLONG    FilePointer;        // File pointer
     ULONG*        FileBlockList;        // File block list
-    UCHAR        DriveNumber;        // Drive number of open file
+    ULONG        DeviceId;        // Drive number of open file
     EXT2_INODE    Inode;            // File's inode
 } EXT2_FILE_INFO, * PEXT2_FILE_INFO;
 
diff --git a/boot/freeldr/freeldr/lib/fs/ext2.c b/boot/freeldr/freeldr/lib/fs/ext2.c
index 3428bd4..277dd5c 100644
--- a/boot/freeldr/freeldr/lib/fs/ext2.c
+++ b/boot/freeldr/freeldr/lib/fs/ext2.c
@@ -23,11 +23,11 @@
 
 DBG_DEFAULT_CHANNEL(FILESYSTEM);
 
-BOOLEAN    Ext2OpenVolume(UCHAR DriveNumber, ULONGLONG VolumeStartSector, ULONGLONG PartitionSectorCount);
+BOOLEAN    Ext2OpenVolume(ULONG DeviceId);
 PEXT2_FILE_INFO    Ext2OpenFile(PCSTR FileName);
 BOOLEAN    Ext2LookupFile(PCSTR FileName, PEXT2_FILE_INFO Ext2FileInfoPointer);
 BOOLEAN    Ext2SearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PEXT2_DIR_ENTRY DirectoryEntry);
-BOOLEAN    Ext2ReadVolumeSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer);
+BOOLEAN    Ext2ReadVolumeSectors(ULONG DeviceId, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer);
 
 BOOLEAN    Ext2ReadFileBig(PEXT2_FILE_INFO Ext2FileInfo, ULONGLONG BytesToRead, ULONGLONG* BytesRead, PVOID Buffer);
 BOOLEAN    Ext2ReadSuperBlock(VOID);
@@ -53,7 +53,7 @@ GEOMETRY        Ext2DiskGeometry;                // Ext2 file system disk geomet
 PEXT2_SUPER_BLOCK    Ext2SuperBlock = NULL;            // Ext2 file system super block
 PEXT2_GROUP_DESC    Ext2GroupDescriptors = NULL;    // Ext2 file system group descriptors
 
-UCHAR                    Ext2DriveNumber = 0;            // Ext2 file system drive number
+UCHAR                    Ext2DeviceId = 0;            // Ext2 file system device id
 ULONGLONG                Ext2VolumeStartSector = 0;        // Ext2 file system starting sector
 ULONG                    Ext2BlockSizeInBytes = 0;        // Block size in bytes
 ULONG                    Ext2BlockSizeInSectors = 0;        // Block size in sectors
@@ -69,25 +69,16 @@ ULONG                    Ext2GroupDescPerBlock = 0;        // Number of group de
 #define TAG_EXT_SUPER_BLOCK 'StxE'
 #define TAG_EXT_GROUP_DESC 'GtxE'
 
-BOOLEAN DiskGetBootVolume(PUCHAR DriveNumber, PULONGLONG StartSector, PULONGLONG SectorCount, int *FsType)
+BOOLEAN Ext2OpenVolume(ULONG DeviceId)
 {
-    *DriveNumber = 0;
-    *StartSector = 0;
-    *SectorCount = 0;
-    *FsType = 0;
-    return FALSE;
-}
 
-BOOLEAN Ext2OpenVolume(UCHAR DriveNumber, ULONGLONG VolumeStartSector, ULONGLONG PartitionSectorCount)
-{
-
-    TRACE("Ext2OpenVolume() DriveNumber = 0x%x VolumeStartSector = %d\n", DriveNumber, VolumeStartSector);
+    TRACE("Ext2OpenVolume() DeviceId = 0x%lx\n", DeviceId);
 
     // Store the drive number and start sector
-    Ext2DriveNumber = DriveNumber;
-    Ext2VolumeStartSector = VolumeStartSector;
+    Ext2DeviceId = DeviceId;
+    Ext2VolumeStartSector = 0;
 
-    if (!MachDiskGetDriveGeometry(DriveNumber, &Ext2DiskGeometry))
+    if (!MachDiskGetDriveGeometry(DeviceId, &Ext2DiskGeometry))
     {
         return FALSE;
     }
@@ -95,10 +86,12 @@ BOOLEAN Ext2OpenVolume(UCHAR DriveNumber, ULONGLONG VolumeStartSector, ULONGLONG
     //
     // Initialize the disk cache for this drive
     //
+#ifdef USE_CACHE
     if (!CacheInitializeDrive(DriveNumber))
     {
         return FALSE;
     }
+#endif
 
     // Read in the super block
     if (!Ext2ReadSuperBlock())
@@ -295,7 +288,7 @@ BOOLEAN Ext2LookupFile(PCSTR FileName, PEXT2_FILE_INFO Ext2FileInfoPointer)
     }
 
     // Set the drive number
-    Ext2FileInfoPointer->DriveNumber = Ext2DriveNumber;
+    Ext2FileInfoPointer->DeviceId = Ext2DeviceId;
 
     // If it's a regular file or a regular symbolic link
     // then get the block pointer list otherwise it must
@@ -561,19 +554,27 @@ BOOLEAN Ext2ReadFileBig(PEXT2_FILE_INFO Ext2FileInfo, ULONGLONG BytesToRead, ULO
     return TRUE;
 }
 
-BOOLEAN Ext2ReadVolumeSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
+BOOLEAN Ext2ReadVolumeSectors(ULONG DeviceId, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
 {
-    //GEOMETRY    DiskGeometry;
-    //BOOLEAN        ReturnValue;
-    //if (!DiskGetDriveGeometry(DriveNumber, &DiskGeometry))
-    //{
-    //    return FALSE;
-    //}
-    //ReturnValue = MachDiskReadLogicalSectors(DriveNumber, SectorNumber + Ext2VolumeStartSector, SectorCount, DiskReadBuffer);
-    //RtlCopyMemory(Buffer, DiskReadBuffer, SectorCount * DiskGeometry.BytesPerSector);
-    //return ReturnValue;
-
-    return CacheReadDiskSectors(DriveNumber, SectorNumber + Ext2VolumeStartSector, SectorCount, Buffer);
+#ifdef USE_CACHE
+    return CacheReadDiskSectors(DeviceId, SectorNumber + Ext2VolumeStartSector, SectorCount, Buffer);
+#else
+    LARGE_INTEGER Position;
+    ULONG Count, BytesToRead = SectorCount * Ext2DiskGeometry.BytesPerSector;
+    ARC_STATUS Status;
+
+    Position.HighPart = 0;
+    Position.LowPart = SectorNumber * Ext2DiskGeometry.BytesPerSector;
+    Status = ArcSeek(DeviceId, &Position, SeekAbsolute);
+    if (Status != ESUCCESS)
+        return FALSE;
+    Status = ArcRead(DeviceId, Buffer, BytesToRead, &Count);
+    if (Status != ESUCCESS || Count != BytesToRead)
+        return FALSE;
+
+    // Return success
+    return TRUE;
+#endif
 }
 
 BOOLEAN Ext2ReadSuperBlock(VOID)
@@ -607,11 +608,10 @@ BOOLEAN Ext2ReadSuperBlock(VOID)
 
     // Now try to read the super block
     // If this fails then abort
-    if (!MachDiskReadLogicalSectors(Ext2DriveNumber, Ext2VolumeStartSector, 8, DiskReadBuffer))
+    if (!Ext2ReadVolumeSectors(Ext2DeviceId, Ext2VolumeStartSector+2, 2, Ext2SuperBlock))
     {
         return FALSE;
     }
-    RtlCopyMemory(Ext2SuperBlock, ((PUCHAR)DiskReadBuffer + 1024), 1024);
 
     TRACE("Dumping super block:\n");
     TRACE("total_inodes: %d\n", Ext2SuperBlock->total_inodes);
@@ -796,7 +796,7 @@ BOOLEAN Ext2ReadDirectory(ULONG Inode, PVOID* DirectoryBuffer, PEXT2_INODE Inode
 
     // Fill in file info struct so we can call Ext2ReadFileBig()
     RtlZeroMemory(&DirectoryFileInfo, sizeof(EXT2_FILE_INFO));
-    DirectoryFileInfo.DriveNumber = Ext2DriveNumber;
+    DirectoryFileInfo.DeviceId = Ext2DeviceId;
     DirectoryFileInfo.FileBlockList = Ext2ReadBlockPointerList(InodePointer);
     DirectoryFileInfo.FilePointer = 0;
     DirectoryFileInfo.FileSize = Ext2GetInodeFileSize(InodePointer);
@@ -859,7 +859,7 @@ BOOLEAN Ext2ReadBlock(ULONG BlockNumber, PVOID Buffer)
         return TRUE;
     }
 
-    return Ext2ReadVolumeSectors(Ext2DriveNumber, (ULONGLONG)BlockNumber * Ext2BlockSizeInSectors, Ext2BlockSizeInSectors, Buffer);
+    return Ext2ReadVolumeSectors(Ext2DeviceId, (ULONGLONG)BlockNumber * Ext2BlockSizeInSectors, Ext2BlockSizeInSectors, Buffer);
 }
 
 /*
@@ -1319,18 +1319,8 @@ const DEVVTBL* Ext2Mount(ULONG DeviceId)
     //
     // Check if SuperBlock is valid. If yes, return Ext2 function table
     //
-    if (SuperBlock.magic == EXT2_MAGIC)
+    if (SuperBlock.magic == EXT2_MAGIC && Ext2OpenVolume(DeviceId))
     {
-        //
-        // Compatibility hack as long as FS is not using underlying device DeviceId
-        //
-        UCHAR DriveNumber;
-        ULONGLONG StartSector;
-        ULONGLONG SectorCount;
-        int Type;
-        if (!DiskGetBootVolume(&DriveNumber, &StartSector, &SectorCount, &Type))
-            return NULL;
-        Ext2OpenVolume(DriveNumber, StartSector, SectorCount);
         return &Ext2FuncTable;
     }
     else
diff --git a/drivers/filesystems/ext2/CMakeLists.txt b/drivers/filesystems/ext2/CMakeLists.txt
index 94b077b..6d0bdb7 100644
--- a/drivers/filesystems/ext2/CMakeLists.txt
+++ b/drivers/filesystems/ext2/CMakeLists.txt
@@ -118,4 +118,4 @@ if(NOT USE_CLANG_CL)
     add_pch(ext2fs inc/ext2fs.h SOURCE)
 endif()
 
-add_cd_file(TARGET ext2fs DESTINATION reactos/system32/drivers FOR all)
+add_cd_file(TARGET ext2fs DESTINATION reactos/system32/drivers NO_CAB FOR all)
diff --git a/drivers/filesystems/ext2/src/ext3/generic.c b/drivers/filesystems/ext2/src/ext3/generic.c
index 377f11f..e8f4a13 100644
--- a/drivers/filesystems/ext2/src/ext3/generic.c
+++ b/drivers/filesystems/ext2/src/ext3/generic.c
@@ -904,6 +904,9 @@ Ext2SaveBuffer( IN PEXT2_IRP_CONTEXT    IrpContext,
             _SEH2_TRY {
                 RtlCopyMemory(bh->b_data + delta, buf, len);
                 mark_buffer_dirty(bh);
+#ifdef __REACTOS__
+                sync_dirty_buffer(bh);
+#endif
             } _SEH2_FINALLY {
                 fini_bh(&bh);
             } _SEH2_END;
diff --git a/drivers/filesystems/ext2/src/memory.c b/drivers/filesystems/ext2/src/memory.c
index 8915dfe..e1dfca3 100644
--- a/drivers/filesystems/ext2/src/memory.c
+++ b/drivers/filesystems/ext2/src/memory.c
@@ -218,6 +218,9 @@ Ext2UnlinkFcb(IN PEXT2_FCB Fcb)
         if (IsMcbSpecialFile(Mcb) ||
             IsFileDeleted(Mcb)) {
 
+            DEBUG(DL_ERR, ("Ext2FreeFcb: Fcb (%p) to be unlinked and erased: %wZ.\n",
+                    Fcb, &Mcb->FullName));
+
             ASSERT(!IsRoot(Fcb));
             Ext2RemoveMcb(Vcb, Mcb);
             Mcb->Fcb = NULL;
@@ -2183,19 +2186,28 @@ Ext2PerformRegistryVolumeParams(IN PEXT2_VCB Vcb)
             goto errorout;
         }
 
+#if 1
+doitagain:
+#endif
         /* set Vcb settings from Ext2Global */
         if (IsFlagOn(Ext2Global->Flags, EXT2_SUPPORT_WRITING)) {
             if (Vcb->IsExt3fs) {
                 if (IsFlagOn(Ext2Global->Flags, EXT3_FORCE_WRITING)) {
                     ClearLongFlag(Vcb->Flags, VCB_READ_ONLY);
                 } else {
+                    DEBUG(DL_ERR, ("%d: No force writing\n", __LINE__));
                     SetLongFlag(Vcb->Flags, VCB_READ_ONLY);
                 }
             } else {
                 ClearLongFlag(Vcb->Flags, VCB_READ_ONLY);
             }
         } else {
+            DEBUG(DL_ERR, ("%d: write not enabled\n", __LINE__));
             SetLongFlag(Vcb->Flags, VCB_READ_ONLY);
+#if 1
+            SetLongFlag(Ext2Global->Flags, EXT2_SUPPORT_WRITING);
+            goto doitagain;
+#endif
         }
 
         /* set the default codepage */
diff --git a/ntoskrnl/cc/pin.c b/ntoskrnl/cc/pin.c
index 0241927..ba4c03a 100644
--- a/ntoskrnl/cc/pin.c
+++ b/ntoskrnl/cc/pin.c
@@ -241,12 +241,19 @@ CcSetDirtyPinnedData (
     IN PVOID Bcb,
     IN PLARGE_INTEGER Lsn)
 {
+    NTSTATUS Status;
     PINTERNAL_BCB iBcb = Bcb;
 
     CCTRACE(CC_API_DEBUG, "Bcb=%p Lsn=%p\n",
         Bcb, Lsn);
 
     iBcb->Dirty = TRUE;
+
+    Status = CcWriteVirtualAddress(iBcb->Vacb);
+    if (NT_SUCCESS(Status))
+    {
+        iBcb->Dirty = FALSE;
+    }
 }
 
 
