blockmap v4.0.0-typescript-0ea0a4837bfc224c2663be2c9d3f628144385674
Blockmap
This module implements Tizen's block map format, which maps non-empty blocks or block ranges from a raw image file, making it possible to quickly & efficiently flash the image to the target block device by only reading & writing the necessary blocks.
Install via npm
$ npm install --save blockmapUsage
For detailed API documentation, see /doc.
var BlockMap = require( 'blockmap' )Parsing a Block Map
var blockMap = BlockMap.parse( xml )BlockMap {
version: '2.0',
imageSize: 821752,
blockSize: 4096,
blocksCount: 201,
mappedBlocksCount: 117,
checksum: '44e9d58de533d5eb94f8232cff22b2e6d71b15d369c2ac2af461c63164cce324',
checksumType: 'sha256',
ranges: [{
checksum: '9eaf19215d55d23de1be1fe4bed4a95bfe620a404352fd06e782738fff58e500',
start: 0,
end: 1
}, {
checksum: 'e8a26f49a71262870f8294a73f40f122d622fd70fb82bef01c0322785e9fd6b2',
start: 3,
end: 5
},
// More ranges omitted for brevity
{
checksum: 'cb732fc3f3a0f81f6a761a534201c05549c8efe4a92630ccd24241f72d7d618c',
start: 198,
end: 199
}]
}Creating a Block Map
Render a .bmap file from a parsed or otherwise constructed BlockMap:
var blockMap = BlockMap.parse( value )
var xml = blockMap.toString()Where xml would look like the following, given the block map from above:
<?xml version="1.0" encoding="UTF-8"?>
<bmap version="2.0">
<ImageSize>821752</ImageSize>
<BlockSize>4096</BlockSize>
<BlocksCount>201</BlocksCount>
<MappedBlocksCount>117</MappedBlocksCount>
<ChecksumType>sha256</ChecksumType>
<BmapFileChecksum>44e9d58de533d5eb94f8232cff22b2e6d71b15d369c2ac2af461c63164cce324</BmapFileChecksum>
<BlockMap>
<Range chksum="9eaf19215d55d23de1be1fe4bed4a95bfe620a404352fd06e782738fff58e500">0-1</Range>
<Range chksum="e8a26f49a71262870f8294a73f40f122d622fd70fb82bef01c0322785e9fd6b2">3-5</Range>
<!-- More ranges omitted for brevity -->
<Range chksum="cb732fc3f3a0f81f6a761a534201c05549c8efe4a92630ccd24241f72d7d618c">198-199</Range>
</BlockMap>
</bmap>NOTE: Regardless of input version, blockMap.toString() will always
create a .bmap in the format of the latest version (currently 2.0).
Block Map Checksum Verification
By default, checksums for mapped ranges and the bmap file itself (only version 1.3+)
will be verified when parsing or streaming. If you need to disable verification,
pass verify: false in the options:
// Disable verification of the bmap file checksum:
var blockMap = BlockMap.parse( bmap, { verify: false })// Disable range checksum verification:
var blockReadStream = BlockMap.createReadStream( '/path/to/resin-os.img', blockMap, {
verify: false,
})// Same for filter streams:
var filterStream = BlockMap.createFilterStream( blockMap, {
verify: false,
})Reading Mapped Blocks
NOTE: These examples just use fs.writeSync() in .on('readable') for brevity;
of course this should be implemented properly in a writable stream, which the readable
side (i.e. the BlockMap.ReadStream or .FilterStream) is piped to.
Use a parsed block map to read only mapped regions:
var blockMap = BlockMap.parse( fs.readFileSync( '/path/to/resin-os.bmap' ) )
var blockReadStream = new BlockMap.ReadStream( '/path/to/resin-os.img', blockMap )
// The chunk emitted will have two properties set;
// 1) chunk.buffer – the data buffer
// 2) chunk.position – the chunk's offset (or address) in bytes
// Which can then be used to write only those blocks to the target:
blockReadStream.on( 'readable', function() {
var chunk = null
while( chunk = this.read() ) {
fs.writeSync( fd, chunk.buffer, 0, chunk.buffer.length, chunk.position )
}
})
blockReadStream.once( 'end', function() {
console.log( 'Read', blockReadStream.blocksRead, 'mapped blocks' )
console.log( 'Read', blockReadStream.bytesRead, 'mapped bytes' )
console.log( 'Read', blockReadStream.rangesRead, 'mapped ranges' )
})Filtering Unmapped Blocks
Use a filter transform to filter out unmapped blocks from a stream:
var blockMap = BlockMap.parse( fs.readFileSync( '/path/to/resin-os.bmap' ) )
var readStream = fs.createReadStream( '/path/to/resin-os.img' )
var filterStream = new BlockMap.FilterStream( blockMap )
// The chunk emitted will have two properties set;
// 1) chunk.buffer – the data buffer
// 2) chunk.position – the chunk's offset (or address) in bytes
// Which can then be used to write only those blocks to the target:
filterStream.on( 'readable', function() {
var buffer = null
while( chunk = this.read() ) {
fs.writeSync( fd, chunk.buffer, 0, chunk.buffer.length, chunk.position )
}
})
// Pipe the readable stream into the block filter:
readStream.pipe( filterStream )Verifying a Flashed Device
Use a BlockMap.ReadStream to verify a flashed device image:
function verify( devicePath, blockMap, callback ) {
new BlockMap.ReadStream( devicePath, blockMap ).resume()
.once( 'error', callback )
.once( 'end', callback )
}
var blockMap = BlockMap.parse( fs.readFileSync( '/path/to/resin-os.bmap' ) )
verify( '/dev/rdisk4', blockMap, function( error ) {
if( error != null ) {
// The image didn't verify...
}
})Handling Errors
Parsing
BlockMap.parse() and blockMap.parse() will throw when
encountering invalid input, or if the checksum doesn't verify:
try {
blockMap = BlockMap.parse( value ) // OR
blockMap.parse( value )
} catch( error ) {
// ...
}Streams
If the error is due to a checksum mismatch,
the error will have a .checksum and .range property,
denoting the calculated checksum, and the range for which it occured:
var blockReadStream = new BlockMap.ReadStream( '/path/to/resin-os.img', blockMap )
blockReadStream.on( 'error', function( error ) {
if( error.checksum ) {
console.log( `Checksum mismatch for range [${error.range.start},${error.range.end}]:` )
console.log( `${error.checksum} != ${error.range.checksum}` )
}
// ...
})References
5 years ago
6 years ago
6 years ago
7 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago