part_blk: added optional partitions report

This commit is contained in:
Boris Mulder
2017-05-18 11:12:11 +02:00
committed by Christian Helmuth
parent 6299f4a7df
commit d094ff995f
6 changed files with 126 additions and 36 deletions

View File

@ -13,6 +13,7 @@ build {
drivers/timer drivers/timer
server/rom_blk server/rom_blk
server/part_blk server/part_blk
server/report_rom
test/blk/cli test/blk/cli
} }
@ -36,8 +37,8 @@ if { ![file exists $img_path] } then {
exec parted -s $img_path mkpart logical fat32 12288s 20479s exec parted -s $img_path mkpart logical fat32 12288s 20479s
} else { } else {
exec parted -s $img_path mklabel gpt exec parted -s $img_path mklabel gpt
exec parted -s $img_path mkpart 1 fat32 2048s 4095s exec parted -s $img_path mkpart one fat32 2048s 4095s
exec parted -s $img_path mkpart 2 fat32 4096s 20446s exec parted -s $img_path mkpart two fat32 4096s 20446s
} }
} }
@ -82,12 +83,14 @@ append config {
if { $mode == "mbr" } { if { $mode == "mbr" } {
append config { append config {
<config> <config>
<report partitions="yes"/>
<policy label_prefix="test-part1" partition="6"/> <policy label_prefix="test-part1" partition="6"/>
<policy label_prefix="test-part2" partition="1"/> <policy label_prefix="test-part2" partition="1"/>
</config>} </config>}
} else { } else {
append config { append config {
<config use_gpt="yes"> <config use_gpt="yes">
<report partitions="yes"/>
<policy label_prefix="test-part1" partition="2"/> <policy label_prefix="test-part1" partition="2"/>
<policy label_prefix="test-part2" partition="1"/> <policy label_prefix="test-part2" partition="1"/>
</config>} </config>}
@ -95,6 +98,14 @@ if { $mode == "mbr" } {
append config { append config {
</start> </start>
<start name="report_rom">
<provides>
<service name="Report"/>
<service name="ROM"/>
</provides>
<resource name="RAM" quantum="5M" />
<config verbose="yes"/>
</start>
<start name="test-part1"> <start name="test-part1">
<binary name="test-blk-cli"/> <binary name="test-blk-cli"/>
<resource name="RAM" quantum="5M" /> <resource name="RAM" quantum="5M" />
@ -117,7 +128,10 @@ install_config $config
# Boot modules # 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 append boot_modules $img_file
build_boot_image $boot_modules build_boot_image $boot_modules

View File

@ -24,6 +24,24 @@ configuration section looking for 'policy' tags.
XML Syntax: XML Syntax:
! <policy labal="<program name>" parition="<partition number>" /> ! <policy labal="<program name>" parition="<partition number>" />
part_blk supports partition reporting, which can be enabled via the
<report> configuration node. See below for an example. The report
looks like follows (for MBR resp. GPT).
! <partitions type="mbr">
! <partition number="1" type="12" start="2048" length="2048"/>
! <partition number="2" type="15" start="4096" length="16384"/>
! <partition number="5" type="12" start="6144" length="4096"/>
! <partition number="6" type="12" start="12288" length="8192"/>
! </partitions>
! <partitions type="gpt">
! <partition number="1" name="one" type="ebd0a0a2-b9e5-4433-87c0-68b6b72699c7"
! guid="5f4061cc-8d4a-4e6f-ad15-10b881b79aee" start="2048" length="2048"/>
! <partition number="2" name="two" type="ebd0a0a2-b9e5-4433-87c0-68b6b72699c7"
! guid="87199a83-d0f4-4a01-b9e3-6516a8579d61" start="4096" length="16351"/>
! </partitions>
Usage Usage
----- -----
@ -46,6 +64,7 @@ Configuration snippet with two clients and an (hypothetical) IDE driver:
! <!-- allow program 'test-part1' to access logical partition '6', while program ! <!-- allow program 'test-part1' to access logical partition '6', while program
! 'test-part2' receives access to primary partition 1 --> ! 'test-part2' receives access to primary partition 1 -->
! <config> ! <config>
! <report partitions="yes"/>
! <policy label_prefix="test-part1" partition="6"/> ! <policy label_prefix="test-part1" partition="6"/>
! <policy label_prefix="test-part2" partition="1"/> ! <policy label_prefix="test-part2" partition="1"/>
! </config> ! </config>

View File

@ -251,6 +251,32 @@ class Gpt : public Block::Partition_table
" blocks) type: '", e->_type.to_string(), " blocks) type: '", e->_type.to_string(),
"' name: '", e->name(), "'"); "' 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: public:

View File

@ -33,11 +33,12 @@ class Main
Block::Partition_table & _table(); Block::Partition_table & _table();
Genode::Env & _env; Genode::Env & _env;
Genode::Heap _heap { _env.ram(), _env.rm() }; Genode::Heap _heap { _env.ram(), _env.rm() };
Block::Driver _driver { _env, _heap }; Block::Driver _driver { _env, _heap };
Mbr_partition_table _mbr { _heap, _driver }; Genode::Reporter _reporter { _env, "partitions" };
Gpt _gpt { _heap, _driver }; Mbr_partition_table _mbr { _heap, _driver, _reporter };
Block::Root _root { _env, _heap, _driver, _table() }; Gpt _gpt { _heap, _driver, _reporter };
Block::Root _root { _env, _heap, _driver, _table() };
public: public:
@ -62,12 +63,21 @@ Block::Partition_table & Main::_table()
bool valid_mbr = false; bool valid_mbr = false;
bool valid_gpt = false; bool valid_gpt = false;
bool use_gpt = false; bool use_gpt = false;
bool report = false;
Genode::Attached_rom_dataspace config(_env, "config");
try { try {
Genode::Attached_rom_dataspace config(_env, "config");
use_gpt = config.xml().attribute_value("use_gpt", false); use_gpt = config.xml().attribute_value("use_gpt", false);
} catch(...) {} } catch(...) {}
try {
report = config.xml().sub_node("report").attribute_value
("partitions", false);
if (report)
_reporter.enabled(true);
} catch(...) {}
if (use_gpt) if (use_gpt)
try { valid_gpt = _gpt.parse(); } catch (...) { } try { valid_gpt = _gpt.parse(); } catch (...) { }

View File

@ -49,7 +49,7 @@ struct Mbr_partition_table : public Block::Partition_table
Genode::uint32_t _sectors; /* number of sectors */ Genode::uint32_t _sectors; /* number of sectors */
bool valid() { return _type != INVALID; } bool valid() { return _type != INVALID; }
bool extented() { return _type == EXTENTED_CHS bool extended() { return _type == EXTENTED_CHS
|| _type == EXTENTED_LBA; } || _type == EXTENTED_LBA; }
bool protective() { return _type == PROTECTIVE; } bool protective() { return _type == PROTECTIVE; }
} __attribute__((packed)); } __attribute__((packed));
@ -78,7 +78,8 @@ struct Mbr_partition_table : public Block::Partition_table
Block::Partition *_part_list[MAX_PARTITIONS]; /* contains pointers to valid Block::Partition *_part_list[MAX_PARTITIONS]; /* contains pointers to valid
partitions or 0 */ partitions or 0 */
void _parse_extented(Partition_record *record) template <typename FUNC>
void _parse_extended(Partition_record *record, FUNC const &f)
{ {
Partition_record *r = record; Partition_record *r = record;
unsigned lba = r->_lba; 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 is relative to the lba of the current EBR */
Partition_record *logical = &(ebr->_records[0]); Partition_record *logical = &(ebr->_records[0]);
if (logical->valid() && nr < MAX_PARTITIONS) { if (logical->valid() && nr < MAX_PARTITIONS) {
_part_list[nr++] = new (&heap) f(nr++, logical, lba);
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));
} }
/* /*
@ -114,12 +110,9 @@ struct Mbr_partition_table : public Block::Partition_table
} while (r->valid()); } while (r->valid());
} }
void _parse_mbr(Mbr *mbr) template <typename FUNC>
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++) { for (int i = 0; i < 4; i++) {
Partition_record *r = &(mbr->_records[i]); Partition_record *r = &(mbr->_records[i]);
@ -127,21 +120,14 @@ struct Mbr_partition_table : public Block::Partition_table
if (!r->valid()) if (!r->valid())
continue; 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()) if (r->protective())
throw Protective_mbr_found(); throw Protective_mbr_found();
if (r->extented()) { f(i + 1, r, 0);
_parse_extented(r);
continue;
}
_part_list[i + 1] = new (&heap) if (r->extended()) {
Block::Partition(r->_lba, r->_sectors); _parse_extended(r, f);
}
} }
} }
@ -155,7 +141,40 @@ struct Mbr_partition_table : public Block::Partition_table
bool parse() bool parse()
{ {
Sector s(driver, 0, 1); Sector s(driver, 0, 1);
_parse_mbr(s.addr<Mbr *>()); Mbr *mbr = s.addr<Mbr *>();
/* 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++) for (unsigned num = 0; num < MAX_PARTITIONS; num++)
if (_part_list[num]) if (_part_list[num])
return true; return true;

View File

@ -18,6 +18,7 @@
#include <base/env.h> #include <base/env.h>
#include <base/log.h> #include <base/log.h>
#include <block_session/client.h> #include <block_session/client.h>
#include <os/reporter.h>
#include "driver.h" #include "driver.h"
@ -72,9 +73,10 @@ struct Block::Partition_table
Genode::Heap & heap; Genode::Heap & heap;
Driver & driver; Driver & driver;
Genode::Reporter & reporter;
Partition_table(Genode::Heap & h, Driver & d) Partition_table(Genode::Heap & h, Driver & d, Genode::Reporter & r)
: heap(h), driver(d) {} : heap(h), driver(d), reporter(r) {}
virtual Partition *partition(int num) = 0; virtual Partition *partition(int num) = 0;