From d094ff995f318b638cff46d3825d5b7e8738aa42 Mon Sep 17 00:00:00 2001 From: Boris Mulder Date: Thu, 18 May 2017 11:12:11 +0200 Subject: [PATCH] part_blk: added optional partitions report --- repos/os/run/part_blk.inc | 20 +++++- repos/os/src/server/part_blk/README | 19 +++++ repos/os/src/server/part_blk/gpt.h | 26 +++++++ repos/os/src/server/part_blk/main.cc | 22 ++++-- repos/os/src/server/part_blk/mbr.h | 69 ++++++++++++------- .../os/src/server/part_blk/partition_table.h | 6 +- 6 files changed, 126 insertions(+), 36 deletions(-) diff --git a/repos/os/run/part_blk.inc b/repos/os/run/part_blk.inc index 44e9cd89d..2d0bcdc3d 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 bd1742c1d..2dbe595ac 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 455b8deca..63c5a8044 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 61d7f2191..64eb282b8 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 7790a2a4d..1cf8cb796 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 e8c2b7d62..2bcd4f7c5 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;