FS.FILO.Ext2: Fill Mount() procedure
diff --git a/src/fs-filo-ext2.adb b/src/fs-filo-ext2.adb
index a00e0a4..d0054da 100644
--- a/src/fs-filo-ext2.adb
+++ b/src/fs-filo-ext2.adb
@@ -1,3 +1,12 @@
+-- Derived from GRUB  --  GRand Unified Bootloader
+-- Copyright (C) 1999, 2001, 2003  Free Software Foundation, Inc.
+-- Copyright (C) 2023 secunet Security Networks AG
+--
+-- 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.
+
 with System;
 with Interfaces;
 with Interfaces.C;
@@ -13,13 +22,109 @@
    function Is_Mounted (State : T) return Boolean is (State.S >= Mounted);
    function Is_Open (State : T) return Boolean is (State.S = File_Opened);
 
+   --------------------------------------------------------------------------
+
+   SUPERBLOCK_SIZE            : constant := 1024;
+   SUPERBLOCK_BLOCKS          : constant := SUPERBLOCK_SIZE / BLOCK_SIZE;
+
+   SUPERBLOCK_MAGIC           : constant := 16#ef53#;
+   OLD_REV                    : constant := 0;
+   DYNAMIC_REV                : constant := 1;
+   FEATURE_INCOMPAT_EXTENTS   : constant := 16#0040#;
+   FEATURE_INCOMPAT_64BIT     : constant := 16#0080#;
+
    procedure Mount
      (State    : in out T;
       Part_Len : in     Partition_Length;
       Success  :    out Boolean)
    is
+      Super_Block : Buffer_Type (0 .. SUPERBLOCK_SIZE - 1) := (others => 0);
    begin
-      Success := False;
+      if Part_Len < 2 * SUPERBLOCK_SIZE then
+         Success := False;
+         return;
+      end if;
+
+      Dev.Read (Super_Block, 1 * SUPERBLOCK_SIZE, Success);
+      if not Success then
+         return;
+      end if;
+
+      if Read_LE16 (Super_Block, 14 * 4) /= 16#ef53# then
+         Success := False;
+         return;
+      end if;
+
+      State.Part_Len := Part_Len;
+      State.First_Data_Block := Block_Offset (Read_LE32 (Super_Block, 5 * 4));
+
+      declare
+         S_Log_Block_Size : constant Unsigned_32 := Read_LE32 (Super_Block, 6 * 4);
+      begin
+         if S_Log_Block_Size <= Unsigned_32 (Log_Block_Size'Last - 10) then
+            State.Block_Size_Bits := Log_Block_Size (S_Log_Block_Size + 10);
+         else
+            Success := False;
+            return;
+         end if;
+      end;
+
+      declare
+         S_Inodes_Per_Group : constant Unsigned_32 := Read_LE32 (Super_Block, 10 * 4);
+      begin
+         if S_Inodes_Per_Group in 1 .. Unsigned_32 (Positive'Last) then
+            State.Inodes_Per_Group := Positive (S_Inodes_Per_Group);
+         else
+            Success := False;
+            return;
+         end if;
+      end;
+
+      declare
+         S_Rev_Level : constant Unsigned_32 := Read_LE32 (Super_Block, 19 * 4);
+      begin
+         if S_Rev_Level >= DYNAMIC_REV then
+            declare
+               S_Inode_Size : constant Unsigned_16 := Read_LE16 (Super_Block, 22 * 4);
+            begin
+               if S_Inode_Size in
+                  Unsigned_16 (Inode_Size'First) .. Unsigned_16 (Inode_Size'Last)
+               then
+                  State.Inode_Size := Inode_Size (S_Inode_Size);
+               else
+                  Success := False;
+                  return;
+               end if;
+            end;
+         else
+            State.Inode_Size := Inode_Size'First;
+         end if;
+      end;
+
+      declare
+         S_Feature_Incompat : constant Unsigned_32 := Read_LE32 (Super_Block, 24 * 4);
+      begin
+         State.Feature_Extents := (S_Feature_Incompat and FEATURE_INCOMPAT_EXTENTS) /= 0;
+         State.Feature_64Bit     := (S_Feature_Incompat and FEATURE_INCOMPAT_64BIT) /= 0;
+         if State.Feature_64Bit then
+            declare
+               S_Desc_Size : constant Unsigned_16 := Read_LE16 (Super_Block, 63 * 4 + 2);
+            begin
+               if S_Desc_Size in
+                  Unsigned_16 (Desc_Size'First) .. Unsigned_16 (Desc_Size'Last)
+               then
+                  State.Desc_Size := Desc_Size (S_Desc_Size);
+               else
+                  Success := False;
+                  return;
+               end if;
+            end;
+         else
+            State.Desc_Size := Desc_Size'First;
+         end if;
+      end;
+
+      State.S := Mounted;
    end Mount;
 
    procedure Open
@@ -50,7 +155,9 @@
       Len := 0;
    end Read;
 
-   package C is new VFS (T => T, Initial => (S => Unmounted));
+   --------------------------------------------------------------------------
+
+   package C is new VFS (T => T, Initial => (S => Unmounted, others => <>));
 
    function C_Mount return int
    with
diff --git a/src/fs-filo-ext2.ads b/src/fs-filo-ext2.ads
index d8cc7e9..32e31fe 100644
--- a/src/fs-filo-ext2.ads
+++ b/src/fs-filo-ext2.ads
@@ -42,8 +42,22 @@
 private
    type State is (Unmounted, Mounted, File_Opened);
 
+   -- maximum block size is 64KiB (2^16):
+   subtype Log_Block_Size is Positive range 10 .. 16;
+
+   subtype Inode_Size is Positive range 128 .. Positive (Unsigned_16'Last);
+   subtype Desc_Size  is Positive range  32 .. Positive (Unsigned_16'Last);
+
    type T is record
       S : State;
+      Part_Len          : Partition_Length := 0;
+      First_Data_Block  : Block_Offset := 0;
+      Block_Size_Bits   : Log_Block_Size := 10;
+      Inodes_Per_Group  : Positive := 1;
+      Inode_Size        : Ext2.Inode_Size := Ext2.Inode_Size'First;
+      Desc_Size         : Ext2.Desc_Size := Ext2.Desc_Size'First;
+      Feature_Extents   : Boolean := False;
+      Feature_64Bit     : Boolean := False;
    end record;
 
 end FS.FILO.Ext2;
diff --git a/src/fs-filo.ads b/src/fs-filo.ads
index a3d8f31..dfd0403 100644
--- a/src/fs-filo.ads
+++ b/src/fs-filo.ads
@@ -8,6 +8,9 @@
    type Partition_Length is range 0 .. Interfaces.Unsigned_64'Last;
    subtype Partition_Offset is Partition_Length range 0 .. Partition_Length'Last - 1;
 
+   BLOCK_SIZE : constant := 512;
+   type Block_Offset is range 0 .. Partition_Offset'Last / BLOCK_SIZE;
+
    type File_Length is range 0 .. int'Last; -- Should be higher, fix FILO first
    subtype File_Offset is File_Length;