diff --git a/repos/os/run/part_blk.inc b/repos/os/run/part_blk.inc
index 44e9cd89d4..2d0bcdc3d2 100644
--- a/repos/os/run/part_blk.inc
+++ b/repos/os/run/part_blk.inc
@@ -13,6 +13,7 @@ build {
drivers/timer
server/rom_blk
server/part_blk
+ server/report_rom
test/blk/cli
}
@@ -36,8 +37,8 @@ if { ![file exists $img_path] } then {
exec parted -s $img_path mkpart logical fat32 12288s 20479s
} else {
exec parted -s $img_path mklabel gpt
- exec parted -s $img_path mkpart 1 fat32 2048s 4095s
- exec parted -s $img_path mkpart 2 fat32 4096s 20446s
+ exec parted -s $img_path mkpart one fat32 2048s 4095s
+ exec parted -s $img_path mkpart two fat32 4096s 20446s
}
}
@@ -82,12 +83,14 @@ append config {
if { $mode == "mbr" } {
append config {
+
}
} else {
append config {
+
}
@@ -95,6 +98,14 @@ if { $mode == "mbr" } {
append config {
+
+
+
+
+
+
+
+
@@ -117,7 +128,10 @@ install_config $config
# Boot modules
#
-append boot_modules { core ld.lib.so init timer rom_blk part_blk test-blk-cli }
+append boot_modules {
+ core ld.lib.so init timer
+ rom_blk part_blk test-blk-cli report_rom
+}
append boot_modules $img_file
build_boot_image $boot_modules
diff --git a/repos/os/src/server/part_blk/README b/repos/os/src/server/part_blk/README
index bd1742c1d0..2dbe595ac4 100644
--- a/repos/os/src/server/part_blk/README
+++ b/repos/os/src/server/part_blk/README
@@ -24,6 +24,24 @@ configuration section looking for 'policy' tags.
XML Syntax:
!
+part_blk supports partition reporting, which can be enabled via the
+ configuration node. See below for an example. The report
+looks like follows (for MBR resp. GPT).
+
+!
+!
+!
+!
+!
+!
+!
+!
+!
+!
+
+
Usage
-----
@@ -46,6 +64,7 @@ Configuration snippet with two clients and an (hypothetical) IDE driver:
!
!
+!
!
!
!
diff --git a/repos/os/src/server/part_blk/gpt.h b/repos/os/src/server/part_blk/gpt.h
index 455b8decab..63c5a8044f 100644
--- a/repos/os/src/server/part_blk/gpt.h
+++ b/repos/os/src/server/part_blk/gpt.h
@@ -251,6 +251,32 @@ class Gpt : public Block::Partition_table
" blocks) type: '", e->_type.to_string(),
"' name: '", e->name(), "'");
}
+
+ /* Report the partitions */
+ if (reporter.enabled())
+ {
+ Genode::Reporter::Xml_generator xml(reporter, [&] () {
+ xml.attribute("type", "gpt");
+
+ for (int i = 0; i < MAX_PARTITIONS; i++) {
+ Gpt_entry *e = (entries + i);
+
+ if (!e->valid()){
+ continue;
+ }
+
+ xml.node("partition", [&] () {
+ xml.attribute("number", i + 1);
+ xml.attribute("name", e->name());
+ xml.attribute("type", e->_type.to_string());
+ xml.attribute("guid", e->_guid.to_string());
+ xml.attribute("start", e->_lba_start);
+ xml.attribute("length", e->_lba_end - e->_lba_start + 1);
+ });
+ }
+ });
+ }
+
}
public:
diff --git a/repos/os/src/server/part_blk/main.cc b/repos/os/src/server/part_blk/main.cc
index 61d7f2191e..64eb282b8e 100644
--- a/repos/os/src/server/part_blk/main.cc
+++ b/repos/os/src/server/part_blk/main.cc
@@ -33,11 +33,12 @@ class Main
Block::Partition_table & _table();
Genode::Env & _env;
- Genode::Heap _heap { _env.ram(), _env.rm() };
- Block::Driver _driver { _env, _heap };
- Mbr_partition_table _mbr { _heap, _driver };
- Gpt _gpt { _heap, _driver };
- Block::Root _root { _env, _heap, _driver, _table() };
+ Genode::Heap _heap { _env.ram(), _env.rm() };
+ Block::Driver _driver { _env, _heap };
+ Genode::Reporter _reporter { _env, "partitions" };
+ Mbr_partition_table _mbr { _heap, _driver, _reporter };
+ Gpt _gpt { _heap, _driver, _reporter };
+ Block::Root _root { _env, _heap, _driver, _table() };
public:
@@ -62,12 +63,21 @@ Block::Partition_table & Main::_table()
bool valid_mbr = false;
bool valid_gpt = false;
bool use_gpt = false;
+ bool report = false;
+
+ Genode::Attached_rom_dataspace config(_env, "config");
try {
- Genode::Attached_rom_dataspace config(_env, "config");
use_gpt = config.xml().attribute_value("use_gpt", false);
} catch(...) {}
+ try {
+ report = config.xml().sub_node("report").attribute_value
+ ("partitions", false);
+ if (report)
+ _reporter.enabled(true);
+ } catch(...) {}
+
if (use_gpt)
try { valid_gpt = _gpt.parse(); } catch (...) { }
diff --git a/repos/os/src/server/part_blk/mbr.h b/repos/os/src/server/part_blk/mbr.h
index 7790a2a4d6..1cf8cb7968 100644
--- a/repos/os/src/server/part_blk/mbr.h
+++ b/repos/os/src/server/part_blk/mbr.h
@@ -49,7 +49,7 @@ struct Mbr_partition_table : public Block::Partition_table
Genode::uint32_t _sectors; /* number of sectors */
bool valid() { return _type != INVALID; }
- bool extented() { return _type == EXTENTED_CHS
+ bool extended() { return _type == EXTENTED_CHS
|| _type == EXTENTED_LBA; }
bool protective() { return _type == PROTECTIVE; }
} __attribute__((packed));
@@ -78,7 +78,8 @@ struct Mbr_partition_table : public Block::Partition_table
Block::Partition *_part_list[MAX_PARTITIONS]; /* contains pointers to valid
partitions or 0 */
- void _parse_extented(Partition_record *record)
+ template
+ void _parse_extended(Partition_record *record, FUNC const &f)
{
Partition_record *r = record;
unsigned lba = r->_lba;
@@ -96,12 +97,7 @@ struct Mbr_partition_table : public Block::Partition_table
* partition is relative to the lba of the current EBR */
Partition_record *logical = &(ebr->_records[0]);
if (logical->valid() && nr < MAX_PARTITIONS) {
- _part_list[nr++] = new (&heap)
- Block::Partition(logical->_lba + lba, logical->_sectors);
-
- Genode::log("Partition ", nr - 1, ": LBA ", logical->_lba + lba,
- " (", (unsigned int)logical->_sectors, " blocks) type ",
- Genode::Hex(logical->_type, Genode::Hex::OMIT_PREFIX));
+ f(nr++, logical, lba);
}
/*
@@ -114,12 +110,9 @@ struct Mbr_partition_table : public Block::Partition_table
} while (r->valid());
}
- void _parse_mbr(Mbr *mbr)
+ template
+ void _parse_mbr(Mbr *mbr, FUNC const &f)
{
- /* no partition table, use whole disc as partition 0 */
- if (!(mbr->valid()))
- _part_list[0] = new (&heap)
- Block::Partition(0, driver.blk_cnt() - 1);
for (int i = 0; i < 4; i++) {
Partition_record *r = &(mbr->_records[i]);
@@ -127,21 +120,14 @@ struct Mbr_partition_table : public Block::Partition_table
if (!r->valid())
continue;
- Genode::log("Partition ", i + 1, ": LBA ",
- (unsigned int) r->_lba, " (",
- (unsigned int) r->_sectors, " blocks) type: ",
- Genode::Hex(r->_type, Genode::Hex::OMIT_PREFIX));
-
if (r->protective())
throw Protective_mbr_found();
- if (r->extented()) {
- _parse_extented(r);
- continue;
- }
+ f(i + 1, r, 0);
- _part_list[i + 1] = new (&heap)
- Block::Partition(r->_lba, r->_sectors);
+ if (r->extended()) {
+ _parse_extended(r, f);
+ }
}
}
@@ -155,7 +141,40 @@ struct Mbr_partition_table : public Block::Partition_table
bool parse()
{
Sector s(driver, 0, 1);
- _parse_mbr(s.addr());
+ Mbr *mbr = s.addr();
+
+ /* no partition table, use whole disc as partition 0 */
+ if (!(mbr->valid()))
+ _part_list[0] = new (&heap)
+ Block::Partition(0, driver.blk_cnt() - 1);
+
+ _parse_mbr(mbr, [&] (int i, Partition_record *r, unsigned offset) {
+ Genode::log("Partition ", i, ": LBA ",
+ (unsigned int) r->_lba + offset, " (",
+ (unsigned int) r->_sectors, " blocks) type: ",
+ Genode::Hex(r->_type, Genode::Hex::OMIT_PREFIX));
+ if (!r->extended())
+ _part_list[i] = new (&heap)
+ Block::Partition(r->_lba + offset, r->_sectors);
+ });
+
+ /* Report the partitions */
+ if (reporter.enabled())
+ {
+ Genode::Reporter::Xml_generator xml(reporter, [&] () {
+ xml.attribute("type", "mbr");
+
+ _parse_mbr(mbr, [&] (int i, Partition_record *r, unsigned offset) {
+ xml.node("partition", [&] {
+ xml.attribute("number", i);
+ xml.attribute("type", r->_type);
+ xml.attribute("start", r->_lba + offset);
+ xml.attribute("length", r->_sectors);
+ });
+ });
+ });
+ }
+
for (unsigned num = 0; num < MAX_PARTITIONS; num++)
if (_part_list[num])
return true;
diff --git a/repos/os/src/server/part_blk/partition_table.h b/repos/os/src/server/part_blk/partition_table.h
index e8c2b7d62c..2bcd4f7c51 100644
--- a/repos/os/src/server/part_blk/partition_table.h
+++ b/repos/os/src/server/part_blk/partition_table.h
@@ -18,6 +18,7 @@
#include
#include
#include
+#include
#include "driver.h"
@@ -72,9 +73,10 @@ struct Block::Partition_table
Genode::Heap & heap;
Driver & driver;
+ Genode::Reporter & reporter;
- Partition_table(Genode::Heap & h, Driver & d)
- : heap(h), driver(d) {}
+ Partition_table(Genode::Heap & h, Driver & d, Genode::Reporter & r)
+ : heap(h), driver(d), reporter(r) {}
virtual Partition *partition(int num) = 0;