Skip to content

Enforce sector alignmnent for managed bootloader builds #5818

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jan 30, 2018

Conversation

sarahmarshy
Copy link
Contributor

These changes will align application start and end addresses to sector boundaries when building a managed bootloader application.

Changes have been made to arm_pack_manager to store sector information in index.json. This required regenerating the index. The list of tuples for sector start, and size are stored in the sectors key for each target in index.json. With the release of PDSC version 1.4.0, changes were made to PDSC tags for memory, so this required additional modifications to arm_pack_manager to find ROM/RAM size from PDSC files. See XML format for memory in PDSC files here.

@theotherjimmy

algo_bin = algo_itr.next()
flm_file = algo_bin.read()
return PackFlashAlgo(flm_file).sector_sizes
except:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this exception be more specific? even except Exception would be better (this catches OOM and Control-C right now)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this exception be more specific? even except Exception would be better (this catches OOM and Control-C right now)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

excepts Exception in new commit.

target_size = size
if (target_size < 0):
raise ConfigException("No valid sector found")
sector_num = (address - target_start)//target_size
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add spaces around the // operator? I prefer that style.

if (target_size < 0):
raise ConfigException("No valid sector found")
sector_num = (address - target_start)//target_size
return target_start + (sector_num*target_size)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this logic will not work well when the next sector after the current one is differently sized compared to current sector. This happens in ST parts for sure.

Could you add spaces around the * operator?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you give an example? I tried this on Odin, and it worked.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That statement assumed that the sector list was a list of all of the sectors.

@@ -540,7 +556,7 @@ def regions(self):
raise ConfigException(
"Bootloader build requested but no bootlader configuration")

def _generate_booloader_build(self, target_overrides, rom_start, rom_size):
def _generate_bootloader_build(self, target_overrides, rom_start, rom_size, sectors):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 For the typo correction. Do we have to pass sectors in? Could this function also do self.sectors?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call.

yield Region("application", rom_start + start, rom_size - start,
True, None)
if start > rom_size:
raise ConfigException("Not enough memory on device to fit all "
"application regions")
@staticmethod
def _align_on_sector(address, sectors):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be named _sector_round_up or _sector_ceiling? This way I know which direction it rounds the address passed in.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this is actually floor/round_down?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. It is.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then I don't think the code using it is correct. You cannot round down the end of the bootloader, that must be rounded up.

target_start = -1
for (start, size) in sectors:
if address < start:
break
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this just rounds up, could it return start here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. The list of sectors is not a list of all possible sectors. It is a list of tuples with (start of block, size of sectors in that block). Maybe I should have made that more clear.

yield Region("application", rom_start + start, rom_size - start,
True, None)
if start > rom_size:
raise ConfigException("Not enough memory on device to fit all "
"application regions")
@staticmethod
def _align_on_sector(address, sectors):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found an odd corner case where this function reports an incorrect address:

_align_on_sector(address = 1, sectors = [(0, 1)]) == 1

it should raise ConfigException

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it shouldn't. Sectors = (0, 1) implies the start address for this block is 0 and there are size 1 sectors from 0 to the end of ROM. So an address of 1 is already sector aligned.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, so the sectors list is formatted a little differently then.

yield Region("bootloader", rom_start + start, part_size, False,
start = Config._align_on_sector(rom_start + start, sectors) - rom_start
offset = start + rom_start
part_size = Config._align_on_sector(offset + part_size, sectors) - offset
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This rounds down the part size, correct? This needs to round up.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rounding down might truncate the bootloader.

filename)
start += part_size
if 'target.restrict_size' in target_overrides:
new_size = int(target_overrides['target.restrict_size'], 0)
yield Region("application", rom_start + start, new_size, True, None)
start = Config._align_on_sector(rom_start + start, sectors) - rom_start
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also rounds down, correct? I think it should round up.

start += new_size
yield Region("post_application", rom_start +start, rom_size - start,
start = Config._align_on_sector(rom_start + start, sectors) - rom_start
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this round up/down is needed. start should already be sector aligned (call 4 lines up)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, it has size added to it now, which might put the new address in a different block with different sector sizes.

False, None)
else:
start = Config._align_on_sector(rom_start + start, sectors) - rom_start
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably round up.

@sarahmarshy sarahmarshy force-pushed the bootloader-align-sectors branch 3 times, most recently from 1386549 to ab137d8 Compare January 12, 2018 15:24
@sarahmarshy
Copy link
Contributor Author

@theotherjimmy, can you review again?

@@ -540,7 +558,7 @@ def regions(self):
raise ConfigException(
"Bootloader build requested but no bootlader configuration")

def _generate_booloader_build(self, target_overrides, rom_start, rom_size):
def _generate_bootloader_build(self, target_overrides, rom_start, rom_size):
start = 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you plan on changing this to be the address of the start of ROM, could you instead assign that here? Doing otherwise can be confusing.

if 'target.restrict_size' in target_overrides:
new_size = int(target_overrides['target.restrict_size'], 0)
yield Region("application", rom_start + start, new_size, True, None)
new_size = Config._align_floor(start + new_size, self.sectors) - start
Copy link
Contributor

@theotherjimmy theotherjimmy Jan 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If bootloader_img is not present, then start will be 0, and incorrect if rom_start is not 0.

Alternatively, You are mixing types for start. It begins life as an offset, and changes to an address in the if 'target.bootloader_img' in target_overrides: branch. This leads to start being either an offset or address in this block, which assumes that start is an address.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@theotherjimmy, the latest commit should fix this. Good catch.

algo_bin = algo_itr.next()
flm_file = algo_bin.read()
return PackFlashAlgo(flm_file).sector_sizes
except:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this exception be more specific? even except Exception would be better (this catches OOM and Control-C right now)

@0xc0170
Copy link
Contributor

0xc0170 commented Jan 24, 2018

/morph build

@mbed-ci
Copy link

mbed-ci commented Jan 24, 2018

Build : SUCCESS

Build number : 938
Build artifacts/logs : http://mbed-os.s3-website-eu-west-1.amazonaws.com/?prefix=builds/5818/

Triggering tests

/morph test
/morph uvisor-test
/morph export-build

@mbed-ci
Copy link

mbed-ci commented Jan 24, 2018

@theotherjimmy
Copy link
Contributor

That export build looks like something went horribly wrong. @cmonr, @studavekar Are we currently experiencing a hiccup in the export CI?

@cmonr
Copy link
Contributor

cmonr commented Jan 24, 2018

Well, we weren't until now... This failure mode is known and we've been monitoring it all week.

@cmonr
Copy link
Contributor

cmonr commented Jan 24, 2018

Fortunately, it looks like this instance was isolated. Holding off on restarting the build until morph test completes.

@cmonr
Copy link
Contributor

cmonr commented Jan 25, 2018

/morph build

@mbed-ci
Copy link

mbed-ci commented Jan 25, 2018

Build : SUCCESS

Build number : 956
Build artifacts/logs : http://mbed-os.s3-website-eu-west-1.amazonaws.com/?prefix=builds/5818/

Triggering tests

/morph test
/morph uvisor-test
/morph export-build

@mbed-ci
Copy link

mbed-ci commented Jan 25, 2018

@0xc0170
Copy link
Contributor

0xc0170 commented Jan 26, 2018

/morph export-build

@0xc0170
Copy link
Contributor

0xc0170 commented Jan 26, 2018

@sarahmarshy Can you review the failure, looks related, and only for iar/uvision

@mbed-ci
Copy link

mbed-ci commented Jan 26, 2018

@studavekar
Copy link
Contributor

studavekar commented Jan 26, 2018

The deployed tools on build node are fixed. This PR adds in a additional python module and will make changes to install requirements.txt into virtualenv.

@cmonr
Copy link
Contributor

cmonr commented Jan 26, 2018

@sarahmarshy Could you rebase this, so we can rerun tests?

@sarahmarshy sarahmarshy force-pushed the bootloader-align-sectors branch from 5e2a321 to 695dc00 Compare January 26, 2018 19:24
@sarahmarshy
Copy link
Contributor Author

@cmonr rebased.

@cmonr
Copy link
Contributor

cmonr commented Jan 26, 2018

/morph build

@cmonr
Copy link
Contributor

cmonr commented Jan 26, 2018

Holding off on build until CI machines are updated with needed python module.

@cmonr
Copy link
Contributor

cmonr commented Jan 26, 2018

/morph build

@mbed-ci
Copy link

mbed-ci commented Jan 26, 2018

Build : SUCCESS

Build number : 980
Build artifacts/logs : http://mbed-os.s3-website-eu-west-1.amazonaws.com/?prefix=builds/5818/

Triggering tests

/morph test
/morph uvisor-test
/morph export-build

@mbed-ci
Copy link

mbed-ci commented Jan 27, 2018

@0xc0170
Copy link
Contributor

0xc0170 commented Jan 29, 2018

/morph test

@mbed-ci
Copy link

mbed-ci commented Jan 30, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants