diff --git a/repos/os/src/server/part_blk/fsprobe.h b/repos/os/src/server/part_blk/fsprobe.h
new file mode 100644
index 0000000000..11de3af6f8
--- /dev/null
+++ b/repos/os/src/server/part_blk/fsprobe.h
@@ -0,0 +1,104 @@
+/*
+ * \brief Poor man's partition probe for known file system
+ * \author Josef Soentgen
+ * \date 2018-05-03
+ */
+
+/*
+ * Copyright (C) 2018 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU Affero General Public License version 3.
+ */
+
+#ifndef _PART_BLK__FSPROBE_H_
+#define _PART_BLK__FSPROBE_H_
+
+/* Genode includes */
+#include
+#include
+
+namespace Fs {
+
+ using namespace Genode;
+
+ using Type = Genode::String<32>;
+
+ Type probe(uint8_t *buffer, size_t len);
+
+ /**
+ * Probe for Ext2/3/4
+ */
+ Type _probe_extfs(uint8_t *p, size_t len)
+ {
+ if (len < 4096) { return Type(); }
+
+ /* super block starts a byte offset 1024 */
+ p += 0x400;
+
+ bool const found_ext_sig = p[0x38] == 0x53 && p[0x39] == 0xEF;
+
+ enum {
+ COMPAT_HAS_JOURNAL = 0x004u,
+ INCOMPAT_EXTENTS = 0x040u,
+ RO_COMPAT_METADATA_CSUM = 0x400u,
+ };
+
+ uint32_t const compat = *(uint32_t*)(p + 0x5C);
+ uint32_t const incompat = *(uint32_t*)(p + 0x60);
+ uint32_t const ro_compat = *(uint32_t*)(p + 0x64);
+
+ /* the feature flags should denote a given Ext version */
+
+ bool const ext3 = compat & COMPAT_HAS_JOURNAL;
+ bool const ext4 = ext3 && ((incompat & INCOMPAT_EXTENTS)
+ && (ro_compat & RO_COMPAT_METADATA_CSUM));
+
+ if (found_ext_sig && ext4) { return Type("Ext4"); }
+ else if (found_ext_sig && ext3) { return Type("Ext3"); }
+ else if (found_ext_sig) { return Type("Ext2"); }
+
+ return Type();
+ }
+
+ /**
+ * Probe for FAT16/32
+ */
+ Type _probe_fatfs(uint8_t *p, size_t len)
+ {
+ if (len < 512) { return Type(); }
+
+ /* at least the checks ring true when mkfs.vfat is used... */
+
+ bool const found_boot_sig = p[510] == 0x55 && p[511] == 0xAA;
+
+ bool const fat16 = p[38] == 0x28 || p[38] == 0x29;
+ bool const fat32 = (p[66] == 0x28 || p[66] == 0x29)
+ && (p[82] == 'F' && p[83] == 'A');
+
+ if (found_boot_sig && fat32) { return Type("FAT32"); }
+ if (found_boot_sig && fat16) { return Type("FAT16"); }
+
+ return Type();
+ }
+}
+
+
+Fs::Type Fs::probe(uint8_t *p, size_t len)
+{
+ /* Ext2/3/4 */
+ {
+ Type t = _probe_extfs(p, len);
+ if (t.valid()) { return t; }
+ }
+
+ /* FAT16/32 */
+ {
+ Type t = _probe_fatfs(p, len);
+ if (t.valid()) { return t; }
+ }
+
+ return Type();
+}
+
+#endif /* _PART_BLK__FSPROBE_H_ */
diff --git a/repos/os/src/server/part_blk/gpt.h b/repos/os/src/server/part_blk/gpt.h
index 63c5a8044f..38b0f576a5 100644
--- a/repos/os/src/server/part_blk/gpt.h
+++ b/repos/os/src/server/part_blk/gpt.h
@@ -20,6 +20,7 @@
#include "driver.h"
#include "partition_table.h"
+#include "fsprobe.h"
namespace {
@@ -265,6 +266,10 @@ class Gpt : public Block::Partition_table
continue;
}
+ enum { BYTES = 4096, };
+ Sector fs(driver, e->_lba_start, BYTES / driver.blk_size());
+ Fs::Type fs_type = Fs::probe(fs.addr(), BYTES);
+
xml.node("partition", [&] () {
xml.attribute("number", i + 1);
xml.attribute("name", e->name());
@@ -272,6 +277,9 @@ class Gpt : public Block::Partition_table
xml.attribute("guid", e->_guid.to_string());
xml.attribute("start", e->_lba_start);
xml.attribute("length", e->_lba_end - e->_lba_start + 1);
+ if (fs_type.valid()) {
+ xml.attribute("file_system", fs_type);
+ }
});
}
});
diff --git a/repos/os/src/server/part_blk/mbr.h b/repos/os/src/server/part_blk/mbr.h
index 1cf8cb7968..a867057708 100644
--- a/repos/os/src/server/part_blk/mbr.h
+++ b/repos/os/src/server/part_blk/mbr.h
@@ -21,6 +21,7 @@
#include
#include "partition_table.h"
+#include "fsprobe.h"
struct Mbr_partition_table : public Block::Partition_table
@@ -165,11 +166,20 @@ struct Mbr_partition_table : public Block::Partition_table
xml.attribute("type", "mbr");
_parse_mbr(mbr, [&] (int i, Partition_record *r, unsigned offset) {
+
+ enum { BYTES = 4096, };
+ Sector fs(driver, r->_lba + offset, BYTES / driver.blk_size());
+ Fs::Type fs_type = Fs::probe(fs.addr(), BYTES);
+
xml.node("partition", [&] {
xml.attribute("number", i);
xml.attribute("type", r->_type);
xml.attribute("start", r->_lba + offset);
xml.attribute("length", r->_sectors);
+
+ if (fs_type.valid()) {
+ xml.attribute("file_system", fs_type);
+ }
});
});
});