Merge lp:~jeremychang/linaro-image-tools/android into lp:linaro-image-tools/11.11

Proposed by Alexander Sack
Status: Merged
Merged at revision: 312
Proposed branch: lp:~jeremychang/linaro-image-tools/android
Merge into: lp:linaro-image-tools/11.11
Diff against target: 483 lines (+362/-4)
7 files modified
linaro-android-media-create (+158/-0)
linaro_image_tools/media_create/__init__.py (+45/-0)
linaro_image_tools/media_create/boards.py (+54/-0)
linaro_image_tools/media_create/partitions.py (+89/-3)
linaro_image_tools/media_create/rootfs.py (+7/-0)
linaro_image_tools/media_create/unpack_binary_tarball.py (+7/-0)
setup.py (+2/-1)
To merge this branch: bzr merge lp:~jeremychang/linaro-image-tools/android
Reviewer Review Type Date Requested Status
James Westby (community) Approve
Guilherme Salgado Pending
Review via email: mp+56113@code.launchpad.net

This proposal supersedes a proposal from 2011-03-30.

Description of the change

official resubmit of our EXPERIMENTAL android script ... after some initial improvement.

First step towards android support; lacks kernel/uboot support atm, becaues our distribution artifacts are still incomplete.

Please let us know if there are any blockers you want to see fixed before initial merge. Otherwise, we would prefer to wait till we have finalized the release artifacts layout etc. and then do the cleanup in one run.

To post a comment you must log in.
Revision history for this message
James Westby (james-w) wrote : Posted in a previous version of this proposal

160 +def get_android_args_parser():

I'd like that refactored so that the common options are populated
by a common function between this and the original code.

There's also some code that could be shared between the two top-level
scripts, but that's less important at this stage.

236 + def get_sfdisk_cmd(cls, should_align_boot_part=False, image_type=None):

There doesn't seem to be much code re-use in this method. Should it me a separate
method?

348 + mkfs = 'mkfs.%s' % "ext4"

I don't think that needs to be repeated every time. In fact it would be
good to have a loop over those similar calls.

369 - should_align_boot_part=should_align_boot_part)
370 + should_align_boot_part=should_align_boot_part, image_type=None)

You don't need that change. Keyword arguments have defaults in Python, so
this should work without.

414 - should_align_boot_part=False):
415 + should_align_boot_part=False, image_type=None):

Ditto

454 +def unpack_android_binary_tarball(tarball, unpack_dir, as_root=True):

I don't think this needs to be a separate function does it? -j should be auto-detected
with relatively modern versions of tar.

Overall this is pretty un-intrusive, so I think we can land it soon.

To be clear, I'd like to have this integrated in to the main linaro-media-create
script one day, but this is definitely the right approach for now.

Thanks,

James

review: Needs Fixing
Revision history for this message
Alexander Sack (asac) wrote : Posted in a previous version of this proposal

> To be clear, I'd like to have this integrated in to the main linaro-media-
> create
> script one day, but this is definitely the right approach for now.

yes thats the goal, but until all the distribution details are sorted i want to have this flagged as EXPERIMENTAL and live in a separate command.

our findings/learnings here could probably be wrapped into the hwpackv2 plan etc. to achieve something consolidated across distros. Thanks for reviewing and helping to get in!

Revision history for this message
Alexander Sack (asac) wrote : Posted in a previous version of this proposal

btw, this makes me wonder if we want to print a EXPERIMENTAL banner whenever you run this script? I want to make clear that the command line parameters as well as the distribution format will be changed and we will not keep backward compatibility for the current version here.

Revision history for this message
Guilherme Salgado (salgado) wrote : Posted in a previous version of this proposal
Download full text (11.2 KiB)

Hi Jeremy,

This looks quite good as it's not too intrusive. I just have a few
comments.

On Wed, 2011-03-30 at 16:05 +0000, Jeremy Chang wrote:
[...]
> === added file 'linaro-android-media-create'
> --- linaro-android-media-create 1970-01-01 00:00:00 +0000
> +++ linaro-android-media-create 2011-03-30 16:05:52 +0000
[...]
> +
> +# Registered as the first atexit handler as we want this to be the last
> +# handler to execute.
> +@atexit.register
> +def cleanup_tempdir():
> + """Remove TEMP_DIR with all its contents.
> +
> + Before doing so, make sure BOOT_DISK and ROOT_DISK are not mounted.
> + """
> + devnull = open('/dev/null', 'w')
> + # ignore non-zero return codes
> + for disk in BOOT_DISK, ROOT_DISK:

Don't you want this cleanup function to umount DATA_DISK and SYSTEM_DISK
as well?

> + if disk is not None:
> + try:
> + cmd_runner.run(['umount', disk],
> + stdout=devnull, stderr=devnull, as_root=True).wait()
> + except cmd_runner.SubcommandNonZeroReturnValue:
> + pass
> + # Remove TMP_DIR as root because some files written there are
> + # owned by root.
> + if TMP_DIR is not None:
> + cmd_runner.run(['rm', '-rf', TMP_DIR], as_root=True).wait()
> +
> +
> +def ensure_required_commands(args):
> + """Ensure we have the commands that we know are going to be used."""
> + required_commands = [
> + 'mkfs.vfat', 'sfdisk', 'mkimage', 'parted']
> + if not is_arm_host():
> + required_commands.append('qemu-arm-static')
> + required_commands.append('qemu-img')
> + if args.rootfs in ['ext2', 'ext3', 'ext4']:
> + required_commands.append('mkfs.%s' % args.rootfs)
> + else:
> + required_commands.append('mkfs.btrfs')
> + for command in required_commands:
> + ensure_command(command)

I don't think we should, at this point, be striving to share as much
code as we can between this and the linaro-media-create script, but this
would be trivial to share -- you can just move it to
linaro_image_tools/media_create/utils.py and then import it here and in
l-m-c.

> +
> +
> +if __name__ == '__main__':
> + parser = get_android_args_parser()
> + args = parser.parse_args()
> +
> + # If --help was specified this won't execute.
> + # Create temp dir and initialize rest of path vars.
> + TMP_DIR = tempfile.mkdtemp()
> + ROOT_DIR = os.path.join(TMP_DIR, 'root')
> + SYSTEM_DIR = os.path.join(TMP_DIR, 'system')
> + DATA_DIR = os.path.join(TMP_DIR, 'data')
> +
> + BOOT_DISK = os.path.join(TMP_DIR, 'boot-disc')
> + ROOT_DISK = os.path.join(TMP_DIR, 'root-disc')
> + SYSTEM_DISK = os.path.join(TMP_DIR, 'system-disc')
> + CACHE_DISK = os.path.join(TMP_DIR, 'cache-disc')
> + DATA_DISK = os.path.join(TMP_DIR, 'userdata-disc')
> + SDCARD_DISK = os.path.join(TMP_DIR, 'sdcard-disc')
> +
> + board_config = board_configs[args.board]
> +
> + ensure_required_commands(args)
> +
> + media = Media(args.device)
> + if media.is_block_device:
> + if not confirm_device_selection_and_ensure_it_is_ready(args.device):
> + sys.exit(1)
> + elif not args.shoul...

Revision history for this message
Jeremy Chang (jeremychang) wrote : Posted in a previous version of this proposal
Download full text (12.5 KiB)

Hi, Guilherme:
    Thanks for the comments!

On Thu, Mar 31, 2011 at 11:18 PM, Guilherme Salgado
<email address hidden> wrote:
> Hi Jeremy,
>
> This looks quite good as it's not too intrusive. I just have a few
> comments.
>
> On Wed, 2011-03-30 at 16:05 +0000, Jeremy Chang wrote:
> [...]
>> === added file 'linaro-android-media-create'
>> --- linaro-android-media-create       1970-01-01 00:00:00 +0000
>> +++ linaro-android-media-create       2011-03-30 16:05:52 +0000
> [...]
>> +
>> +# Registered as the first atexit handler as we want this to be the last
>> +# handler to execute.
>> +@atexit.register
>> +def cleanup_tempdir():
>> +    """Remove TEMP_DIR with all its contents.
>> +
>> +    Before doing so, make sure BOOT_DISK and ROOT_DISK are not mounted.
>> +    """
>> +    devnull = open('/dev/null', 'w')
>> +    # ignore non-zero return codes
>> +    for disk in BOOT_DISK, ROOT_DISK:
>
> Don't you want this cleanup function to umount DATA_DISK and SYSTEM_DISK
> as well?

    Added and pushed.

>
>> +        if disk is not None:
>> +            try:
>> +                cmd_runner.run(['umount', disk],
>> +                      stdout=devnull, stderr=devnull, as_root=True).wait()
>> +            except cmd_runner.SubcommandNonZeroReturnValue:
>> +                pass
>> +    # Remove TMP_DIR as root because some files written there are
>> +    # owned by root.
>> +    if TMP_DIR is not None:
>> +        cmd_runner.run(['rm', '-rf', TMP_DIR], as_root=True).wait()
>> +
>> +
>> +def ensure_required_commands(args):
>> +    """Ensure we have the commands that we know are going to be used."""
>> +    required_commands = [
>> +        'mkfs.vfat', 'sfdisk', 'mkimage', 'parted']
>> +    if not is_arm_host():
>> +        required_commands.append('qemu-arm-static')
>> +        required_commands.append('qemu-img')
>> +    if args.rootfs in ['ext2', 'ext3', 'ext4']:
>> +        required_commands.append('mkfs.%s' % args.rootfs)
>> +    else:
>> +        required_commands.append('mkfs.btrfs')
>> +    for command in required_commands:
>> +        ensure_command(command)
>
> I don't think we should, at this point, be striving to share as much
> code as we can between this and the linaro-media-create script, but this
> would be trivial to share -- you can just move it to
> linaro_image_tools/media_create/utils.py and then import it here and in
> l-m-c.

    This could be done, but I think could be later for now.

>
>> +
>> +
>> +if __name__ == '__main__':
>> +    parser = get_android_args_parser()
>> +    args = parser.parse_args()
>> +
>> +    # If --help was specified this won't execute.
>> +    # Create temp dir and initialize rest of path vars.
>> +    TMP_DIR = tempfile.mkdtemp()
>> +    ROOT_DIR = os.path.join(TMP_DIR, 'root')
>> +    SYSTEM_DIR = os.path.join(TMP_DIR, 'system')
>> +    DATA_DIR = os.path.join(TMP_DIR, 'data')
>> +
>> +    BOOT_DISK = os.path.join(TMP_DIR, 'boot-disc')
>> +    ROOT_DISK = os.path.join(TMP_DIR, 'root-disc')
>> +    SYSTEM_DISK = os.path.join(TMP_DIR, 'system-disc')
>> +    CACHE_DISK = os.path.join(TMP_DIR, 'cache-disc')
>> +    DATA_DISK = os.path.join(TMP_DIR, 'userdata-disc')
>> +    SDCARD_DISK = os.path.joi...

Revision history for this message
Guilherme Salgado (salgado) wrote : Posted in a previous version of this proposal
Download full text (9.2 KiB)

On Thu, 2011-03-31 at 17:24 +0000, Jeremy Chang wrote:
[...]
> >> + if disk is not None:
> >> + try:
> >> + cmd_runner.run(['umount', disk],
> >> + stdout=devnull, stderr=devnull, as_root=True).wait()
> >> + except cmd_runner.SubcommandNonZeroReturnValue:
> >> + pass
> >> + # Remove TMP_DIR as root because some files written there are
> >> + # owned by root.
> >> + if TMP_DIR is not None:
> >> + cmd_runner.run(['rm', '-rf', TMP_DIR], as_root=True).wait()
> >> +
> >> +
> >> +def ensure_required_commands(args):
> >> + """Ensure we have the commands that we know are going to be used."""
> >> + required_commands = [
> >> + 'mkfs.vfat', 'sfdisk', 'mkimage', 'parted']
> >> + if not is_arm_host():
> >> + required_commands.append('qemu-arm-static')
> >> + required_commands.append('qemu-img')
> >> + if args.rootfs in ['ext2', 'ext3', 'ext4']:
> >> + required_commands.append('mkfs.%s' % args.rootfs)
> >> + else:
> >> + required_commands.append('mkfs.btrfs')
> >> + for command in required_commands:
> >> + ensure_command(command)
> >
> > I don't think we should, at this point, be striving to share as much
> > code as we can between this and the linaro-media-create script, but this
> > would be trivial to share -- you can just move it to
> > linaro_image_tools/media_create/utils.py and then import it here and in
> > l-m-c.
>
> This could be done, but I think could be later for now.

That would be fine; I only mentioned it because it really is a trivial,
2 minute change.

> >> @@ -182,14 +191,32 @@
> >> # there should still be enough room
> >> boot_len = boot_len - boot_len % 2
> >> boot_end = boot_start + boot_len - 1
> >> - # we ignore _root_end / _root_len and return a sfdisk command to
> >> - # instruct the use of all remaining space; XXX if we had some root size
> >> - # config, we could do something more sensible
> >> - root_start, _root_end, _root_len = align_partition(
> >> - boot_end + 1, ROOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S)
> >> -
> >> - return '%s,%s,%s,*\n%s,,,-' % (
> >> - boot_start, boot_len, partition_type, root_start)
> >> +
> >> + if image_type == "ANDROID":
> >> + root_start, _root_end, _root_len = align_partition(
> >> + boot_end + 1, ROOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S)
> >> + system_start, _system_end, _system_len = align_partition(
> >> + _root_end + 1, SYSTEM_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S)
> >> + cache_start, _cache_end, _cache_len = align_partition(
> >> + _system_end + 1, CACHE_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S)
> >> + userdata_start, _userdata_end, _userdata_len = align_partition(
> >> + _cache_end + 1, USERDATA_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S)
> >> + sdcard_start, _sdcard_end, _sdcard_len = align_partition(
> >> + _userdata_end + 1, SDCARD_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S)
> >> +
> >> + return '%s,%s,...

Read more...

Revision history for this message
Jeremy Chang (jeremychang) wrote : Posted in a previous version of this proposal
Download full text (10.3 KiB)

On Fri, Apr 1, 2011 at 10:04 PM, Guilherme Salgado
<email address hidden> wrote:
> On Thu, 2011-03-31 at 17:24 +0000, Jeremy Chang wrote:
> [...]
>> >> +        if disk is not None:
>> >> +            try:
>> >> +                cmd_runner.run(['umount', disk],
>> >> +                      stdout=devnull, stderr=devnull, as_root=True).wait()
>> >> +            except cmd_runner.SubcommandNonZeroReturnValue:
>> >> +                pass
>> >> +    # Remove TMP_DIR as root because some files written there are
>> >> +    # owned by root.
>> >> +    if TMP_DIR is not None:
>> >> +        cmd_runner.run(['rm', '-rf', TMP_DIR], as_root=True).wait()
>> >> +
>> >> +
>> >> +def ensure_required_commands(args):
>> >> +    """Ensure we have the commands that we know are going to be used."""
>> >> +    required_commands = [
>> >> +        'mkfs.vfat', 'sfdisk', 'mkimage', 'parted']
>> >> +    if not is_arm_host():
>> >> +        required_commands.append('qemu-arm-static')
>> >> +        required_commands.append('qemu-img')
>> >> +    if args.rootfs in ['ext2', 'ext3', 'ext4']:
>> >> +        required_commands.append('mkfs.%s' % args.rootfs)
>> >> +    else:
>> >> +        required_commands.append('mkfs.btrfs')
>> >> +    for command in required_commands:
>> >> +        ensure_command(command)
>> >
>> > I don't think we should, at this point, be striving to share as much
>> > code as we can between this and the linaro-media-create script, but this
>> > would be trivial to share -- you can just move it to
>> > linaro_image_tools/media_create/utils.py and then import it here and in
>> > l-m-c.
>>
>>     This could be done, but I think could be later for now.
>
> That would be fine; I only mentioned it because it really is a trivial,
> 2 minute change.
>
>> >> @@ -182,14 +191,32 @@
>> >>          # there should still be enough room
>> >>          boot_len = boot_len - boot_len % 2
>> >>          boot_end = boot_start + boot_len - 1
>> >> -        # we ignore _root_end / _root_len and return a sfdisk command to
>> >> -        # instruct the use of all remaining space; XXX if we had some root size
>> >> -        # config, we could do something more sensible
>> >> -        root_start, _root_end, _root_len = align_partition(
>> >> -            boot_end + 1, ROOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S)
>> >> -
>> >> -        return '%s,%s,%s,*\n%s,,,-' % (
>> >> -            boot_start, boot_len, partition_type, root_start)
>> >> +
>> >> +        if image_type == "ANDROID":
>> >> +            root_start, _root_end, _root_len = align_partition(
>> >> +                boot_end + 1, ROOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S)
>> >> +            system_start, _system_end, _system_len = align_partition(
>> >> +                _root_end + 1, SYSTEM_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S)
>> >> +            cache_start, _cache_end, _cache_len = align_partition(
>> >> +                _system_end + 1, CACHE_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S)
>> >> +            userdata_start, _userdata_end, _userdata_len = align_partition(
>> >> +                _cache_end + 1, USERDATA_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S)
>> >> +            sdcard_start, _sdcard_end, _sdc...

Revision history for this message
Alexander Sack (asac) wrote : Posted in a previous version of this proposal

Hi salgado,

is it ok to merge the current state? we still have some changes pending wrt what artifacts we will really release and so. Jeremy and me discussed this and we think refactoring/reuse of code effort should be done in one batch before the 11.05 release.

Thanks!

Revision history for this message
Guilherme Salgado (salgado) wrote : Posted in a previous version of this proposal

On Mon, 2011-04-04 at 09:25 +0000, Alexander Sack wrote:
> Hi salgado,
>
> is it ok to merge the current state? we still have some changes
> pending wrt what artifacts we will really release and so. Jeremy and
> me discussed this and we think refactoring/reuse of code effort should
> be done in one batch before the 11.05 release.

I agree the refactoring to avoid code duplication can be done later, and
I said so in my review. The most important change I proposed was to use
separate config classes for android as that would be much cleaner but
more importantly would make for a better baseline on where to build
further android-related changes.

I'd be happy to postpone this provided that there was an XXX in the code
for it to be fixed later, but this really was a trivial change and I see
in the last merge proposal that most of what I asked for is already
done, so I see no reason why this shouldn't be done now. All that is
left to do is create the AndroidBoardConfigMixin class as I described
and move get_android_sfdisk_cmd() there (as get_sfdisk_cmd()). With
that we can then get rid of the image_type argument and the ugly change
below.

- sfdisk_cmd = board_config.get_sfdisk_cmd(
- should_align_boot_part=should_align_boot_part)
+ if image_type == "ANDROID":
+ sfdisk_cmd = board_config.get_android_sfdisk_cmd(
+ should_align_boot_part=should_align_boot_part)
+ else:
+ sfdisk_cmd = board_config.get_sfdisk_cmd(
+ should_align_boot_part=should_align_boot_part)

Revision history for this message
James Westby (james-w) wrote :

I don't see an issue with this landing in the current state
as there is very little risk to linaro-media-create from these changes.

We may want to not include it in setup.py so that you have to use it
from a bzr checkout to indicate the experimental nature?

Thanks,

James

review: Approve
Revision history for this message
Alexander Sack (asac) wrote :

merged this and dropped setup.py changes.

Revision history for this message
Guilherme Salgado (salgado) wrote :

I was asked for feedback on the previous mp and replied there, which in turn causes it to show up here. However, even though I'd be happy with just an XXX comment, it looks like my feedback was simply ignored.

Revision history for this message
Alexander Sack (asac) wrote :

salgado, it was an oversight, we definitely didn't want to ignore you. sorry. I will file a bug with your comment to get addressed soonish. If you want to go ahead and just do it, please claim the bug.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'linaro-android-media-create'
2--- linaro-android-media-create 1970-01-01 00:00:00 +0000
3+++ linaro-android-media-create 2011-04-04 09:27:32 +0000
4@@ -0,0 +1,158 @@
5+#!/usr/bin/env python
6+# Copyright (C) 2011 Linaro
7+#
8+# Author: Jeremy Chang <jeremy.chang@linaro.org>
9+#
10+# This file is part of Linaro Image Tools.
11+#
12+# Linaro Image Tools is free software: you can redistribute it and/or modify
13+# it under the terms of the GNU General Public License as published by
14+# the Free Software Foundation, either version 3 of the License, or
15+# (at your option) any later version.
16+#
17+# Linaro Image Tools is distributed in the hope that it will be useful,
18+# but WITHOUT ANY WARRANTY; without even the implied warranty of
19+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+# GNU General Public License for more details.
21+#
22+# You should have received a copy of the GNU General Public License
23+# along with Linaro Image Tools. If not, see <http://www.gnu.org/licenses/>.
24+
25+import atexit
26+import os
27+import sys
28+import tempfile
29+
30+from linaro_image_tools import cmd_runner
31+
32+from linaro_image_tools.media_create.boards import android_board_configs
33+from linaro_image_tools.media_create.check_device import (
34+ confirm_device_selection_and_ensure_it_is_ready)
35+from linaro_image_tools.media_create.hwpack import install_hwpacks
36+from linaro_image_tools.media_create.partitions import (
37+ Media,
38+ setup_partitions,
39+ setup_android_partitions,
40+ get_uuid,
41+ )
42+from linaro_image_tools.media_create.populate_boot import populate_boot
43+from linaro_image_tools.media_create.rootfs import populate_partition
44+from linaro_image_tools.media_create.unpack_binary_tarball import (
45+ unpack_android_binary_tarball
46+ )
47+from linaro_image_tools.media_create import get_android_args_parser
48+from linaro_image_tools.utils import ensure_command, is_arm_host
49+
50+
51+
52+# Just define the global variables
53+TMP_DIR = None
54+ROOTFS_DIR = None
55+BOOT_DISK = None
56+ROOT_DISK = None
57+SYSTEM_DISK = None
58+CACHE_DISK = None
59+DATA_DISK = None
60+SDCARD_DISK = None
61+
62+
63+# Registered as the first atexit handler as we want this to be the last
64+# handler to execute.
65+@atexit.register
66+def cleanup_tempdir():
67+ """Remove TEMP_DIR with all its contents.
68+
69+ Before doing so, make sure BOOT_DISK and ROOT_DISK are not mounted.
70+ """
71+ devnull = open('/dev/null', 'w')
72+ # ignore non-zero return codes
73+ for disk in BOOT_DISK, ROOT_DISK, SYSTEM_DISK, CACHE_DISK, DATA_DISK, \
74+ SDCARD_DISK:
75+ if disk is not None:
76+ try:
77+ cmd_runner.run(['umount', disk],
78+ stdout=devnull, stderr=devnull, as_root=True).wait()
79+ except cmd_runner.SubcommandNonZeroReturnValue:
80+ pass
81+ # Remove TMP_DIR as root because some files written there are
82+ # owned by root.
83+ if TMP_DIR is not None:
84+ cmd_runner.run(['rm', '-rf', TMP_DIR], as_root=True).wait()
85+
86+
87+def ensure_required_commands(args):
88+ """Ensure we have the commands that we know are going to be used."""
89+ required_commands = [
90+ 'mkfs.vfat', 'sfdisk', 'mkimage', 'parted']
91+ if not is_arm_host():
92+ required_commands.append('qemu-arm-static')
93+ required_commands.append('qemu-img')
94+ if args.rootfs in ['ext2', 'ext3', 'ext4']:
95+ required_commands.append('mkfs.%s' % args.rootfs)
96+ else:
97+ required_commands.append('mkfs.btrfs')
98+ for command in required_commands:
99+ ensure_command(command)
100+
101+
102+if __name__ == '__main__':
103+ parser = get_android_args_parser()
104+ print "===================================================================="
105+ print " linaro-android-media-create is EXPERIMENTAL "
106+ print " "
107+ print " The command line parameters as well as the distribution format will"
108+ print " be changed and we will not keep backward compatibility for the "
109+ print " current version here. "
110+ print "===================================================================="
111+ args = parser.parse_args()
112+
113+ # If --help was specified this won't execute.
114+ # Create temp dir and initialize rest of path vars.
115+ TMP_DIR = tempfile.mkdtemp()
116+ ROOT_DIR = os.path.join(TMP_DIR, 'root')
117+ SYSTEM_DIR = os.path.join(TMP_DIR, 'system')
118+ DATA_DIR = os.path.join(TMP_DIR, 'data')
119+
120+ BOOT_DISK = os.path.join(TMP_DIR, 'boot-disc')
121+ ROOT_DISK = os.path.join(TMP_DIR, 'root-disc')
122+ SYSTEM_DISK = os.path.join(TMP_DIR, 'system-disc')
123+ CACHE_DISK = os.path.join(TMP_DIR, 'cache-disc')
124+ DATA_DISK = os.path.join(TMP_DIR, 'userdata-disc')
125+ SDCARD_DISK = os.path.join(TMP_DIR, 'sdcard-disc')
126+
127+ board_config = android_board_configs[args.board]
128+
129+ ensure_required_commands(args)
130+
131+ media = Media(args.device)
132+ if media.is_block_device:
133+ if not confirm_device_selection_and_ensure_it_is_ready(args.device):
134+ sys.exit(1)
135+ elif not args.should_format_rootfs or not args.should_format_bootfs:
136+ print ("Do not use --no-boot or --no-part in conjunction with "
137+ "--image_file.")
138+ sys.exit(1)
139+ else:
140+ # All good, move on.
141+ pass
142+
143+
144+ cmd_runner.run(['mkdir', '-p', ROOT_DIR]).wait()
145+ cmd_runner.run(['mkdir', '-p', SYSTEM_DIR]).wait()
146+ cmd_runner.run(['mkdir', '-p', DATA_DIR]).wait()
147+
148+ unpack_android_binary_tarball(args.root, ROOT_DIR)
149+ unpack_android_binary_tarball(args.system, SYSTEM_DIR)
150+ unpack_android_binary_tarball(args.userdata, DATA_DIR)
151+
152+ # Create partitions
153+ boot_partition, root_partition, system_partition, cache_partition, \
154+ data_partition, sdcard_partition = setup_android_partitions( \
155+ board_config, media, args.boot_label, args.rfs_label,
156+ args.rootfs, args.should_create_partitions, args.should_format_bootfs,
157+ args.should_format_rootfs, args.should_align_boot_part)
158+
159+ populate_partition(ROOT_DIR, ROOT_DISK, root_partition)
160+ populate_partition(SYSTEM_DIR + "/system", SYSTEM_DISK, system_partition)
161+ populate_partition(DATA_DIR + "/data", DATA_DISK, data_partition)
162+ print "Done creating Linaro Android image on %s" % args.device
163
164=== modified file 'linaro_image_tools/media_create/__init__.py'
165--- linaro_image_tools/media_create/__init__.py 2011-03-23 22:25:10 +0000
166+++ linaro_image_tools/media_create/__init__.py 2011-04-04 09:27:32 +0000
167@@ -20,9 +20,11 @@
168 import argparse
169
170 from linaro_image_tools.media_create.boards import board_configs
171+from linaro_image_tools.media_create.boards import android_board_configs
172
173
174 KNOWN_BOARDS = board_configs.keys()
175+ANDROID_KNOWN_BOARDS = android_board_configs.keys()
176
177
178 class Live256MegsAction(argparse.Action):
179@@ -110,3 +112,46 @@
180 action='store_true',
181 help='Align boot partition too (might break older x-loaders).')
182 return parser
183+
184+def get_android_args_parser():
185+ """Get the ArgumentParser for the arguments given on the command line."""
186+ parser = argparse.ArgumentParser()
187+ parser.add_argument(
188+ '--mmc', required=True, dest='device', help='The storage device to use.')
189+ parser.add_argument(
190+ '--dev', required=True, dest='board', choices=ANDROID_KNOWN_BOARDS,
191+ help='Generate an SD card or image for the given board.')
192+ parser.add_argument(
193+ '--rootfs', default='ext4', choices=['ext3', 'ext4'],
194+ help='Type of filesystem to use for the rootfs')
195+ parser.add_argument(
196+ '--rfs_label', default='rootfs',
197+ help='Label to use for the root filesystem.')
198+ parser.add_argument(
199+ '--boot_label', default='boot',
200+ help='Label to use for the boot filesystem.')
201+
202+ parser.add_argument(
203+ '--system', default='system.tar.bz2', required=True,
204+ help=('The tarball containing the Android system paritition'))
205+ parser.add_argument(
206+ '--userdata', default='userdata.tar.bz2', required=True,
207+ help=('The tarball containing the Android data paritition'))
208+ parser.add_argument(
209+ '--root', default='root.tar.bz2', required=True,
210+ help=('The tarball containing the Android root partition'))
211+
212+ parser.add_argument(
213+ '--no-rootfs', dest='should_format_rootfs', action='store_false',
214+ help='Do not deploy the root filesystem.')
215+ parser.add_argument(
216+ '--no-bootfs', dest='should_format_bootfs', action='store_false',
217+ help='Do not deploy the boot filesystem.')
218+ parser.add_argument(
219+ '--no-part', dest='should_create_partitions', action='store_false',
220+ help='Reuse existing partitions on the given media.')
221+ parser.add_argument(
222+ '--align-boot-part', dest='should_align_boot_part',
223+ action='store_true',
224+ help='Align boot partition too (might break older x-loaders).')
225+ return parser
226
227=== modified file 'linaro_image_tools/media_create/boards.py'
228--- linaro_image_tools/media_create/boards.py 2011-04-01 14:18:41 +0000
229+++ linaro_image_tools/media_create/boards.py 2011-04-04 09:27:32 +0000
230@@ -168,6 +168,9 @@
231 else:
232 partition_type = '0x0E'
233
234+ BOOT_MIN_SIZE_S = align_up(50 * 1024 * 1024, SECTOR_SIZE) / SECTOR_SIZE
235+ ROOT_MIN_SIZE_S = align_up(50 * 1024 * 1024, SECTOR_SIZE) / SECTOR_SIZE
236+
237 # align on sector 63 for compatibility with broken versions of x-loader
238 # unless align_boot_part is set
239 boot_align = 63
240@@ -182,6 +185,7 @@
241 # there should still be enough room
242 boot_len = boot_len - boot_len % 2
243 boot_end = boot_start + boot_len - 1
244+
245 # we ignore _root_end / _root_len and return a sfdisk command to
246 # instruct the use of all remaining space; XXX if we had some root size
247 # config, we could do something more sensible
248@@ -191,6 +195,51 @@
249 return '%s,%s,%s,*\n%s,,,-' % (
250 boot_start, boot_len, partition_type, root_start)
251
252+ @classmethod
253+ def get_android_sfdisk_cmd(cls, should_align_boot_part=False):
254+ if cls.fat_size == 32:
255+ partition_type = '0x0C'
256+ else:
257+ partition_type = '0x0E'
258+
259+ BOOT_MIN_SIZE_S = align_up(128 * 1024 * 1024, SECTOR_SIZE) / SECTOR_SIZE
260+ ROOT_MIN_SIZE_S = align_up(128 * 1024 * 1024, SECTOR_SIZE) / SECTOR_SIZE
261+ SYSTEM_MIN_SIZE_S = align_up(256 * 1024 * 1024, SECTOR_SIZE) / SECTOR_SIZE
262+ CACHE_MIN_SIZE_S = align_up(256 * 1024 * 1024, SECTOR_SIZE) / SECTOR_SIZE
263+ USERDATA_MIN_SIZE_S = align_up(512 * 1024 * 1024, SECTOR_SIZE) / SECTOR_SIZE
264+ SDCARD_MIN_SIZE_S = align_up(512 * 1024 * 1024, SECTOR_SIZE) / SECTOR_SIZE
265+
266+ # align on sector 63 for compatibility with broken versions of x-loader
267+ # unless align_boot_part is set
268+ boot_align = 63
269+ if should_align_boot_part:
270+ boot_align = PART_ALIGN_S
271+
272+ # can only start on sector 1 (sector 0 is MBR / partition table)
273+ boot_start, boot_end, boot_len = align_partition(
274+ 1, BOOT_MIN_SIZE_S, boot_align, PART_ALIGN_S)
275+ # apparently OMAP3 ROMs require the vfat length to be an even number
276+ # of sectors (multiple of 1 KiB); decrease the length if it's odd,
277+ # there should still be enough room
278+ boot_len = boot_len - boot_len % 2
279+ boot_end = boot_start + boot_len - 1
280+
281+ root_start, _root_end, _root_len = align_partition(
282+ boot_end + 1, ROOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S)
283+ system_start, _system_end, _system_len = align_partition(
284+ _root_end + 1, SYSTEM_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S)
285+ cache_start, _cache_end, _cache_len = align_partition(
286+ _system_end + 1, CACHE_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S)
287+ userdata_start, _userdata_end, _userdata_len = align_partition(
288+ _cache_end + 1, USERDATA_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S)
289+ sdcard_start, _sdcard_end, _sdcard_len = align_partition(
290+ _userdata_end + 1, SDCARD_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S)
291+
292+ return '%s,%s,%s,*\n%s,%s,L\n%s,%s,L\n%s,-,E\n%s,%s,L\n%s,%s,L\n%s,,,-' % (
293+ boot_start, boot_len, partition_type, root_start, _root_len,
294+ system_start, _system_len, cache_start, cache_start, _cache_len,
295+ userdata_start, _userdata_len, sdcard_start)
296+
297 @classproperty
298 def bootcmd(cls):
299 """Get the bootcmd for this board.
300@@ -640,6 +689,11 @@
301 'smdkv310': SMDKV310Config,
302 }
303
304+android_board_configs = {
305+ 'beagle': BeagleConfig,
306+ 'panda': PandaConfig,
307+ }
308+
309
310 def _dd(input_file, output_file, block_size=SECTOR_SIZE, count=None, seek=None,
311 skip=None):
312
313=== modified file 'linaro_image_tools/media_create/partitions.py'
314--- linaro_image_tools/media_create/partitions.py 2011-03-24 10:10:38 +0000
315+++ linaro_image_tools/media_create/partitions.py 2011-04-04 09:27:32 +0000
316@@ -41,6 +41,58 @@
317 UDISKS = "org.freedesktop.UDisks"
318
319
320+def setup_android_partitions(board_config, media, bootfs_label,
321+ rootfs_label, rootfs_type, should_create_partitions,
322+ should_format_bootfs, should_format_rootfs,
323+ should_align_boot_part=False):
324+ cylinders = None
325+
326+ if should_create_partitions:
327+ create_partitions(
328+ board_config, media, HEADS, SECTORS, cylinders,
329+ should_align_boot_part=should_align_boot_part, image_type="ANDROID")
330+
331+ bootfs, rootfs, system, cache, data, sdcard = \
332+ get_android_partitions_for_media (media, board_config)
333+ ensure_partition_is_not_mounted(bootfs)
334+ ensure_partition_is_not_mounted(rootfs)
335+ ensure_partition_is_not_mounted(system)
336+ ensure_partition_is_not_mounted(cache)
337+ ensure_partition_is_not_mounted(data)
338+ ensure_partition_is_not_mounted(sdcard)
339+
340+ if should_format_bootfs:
341+ print "\nFormating boot partition\n"
342+ proc = cmd_runner.run(
343+ ['mkfs.vfat', '-F', str(board_config.fat_size), bootfs, '-n',
344+ bootfs_label],
345+ as_root=True)
346+ proc.wait()
347+
348+ if should_format_rootfs:
349+ print "\nFormating root partition\n"
350+ mkfs = 'mkfs.%s' % rootfs_type
351+ proc = cmd_runner.run(
352+ [mkfs, rootfs, '-L', rootfs_label],
353+ as_root=True)
354+ proc.wait()
355+
356+ ext4_partitions = {"system": system, "cache": cache, "userdata": data}
357+ for label, dev in ext4_partitions.iteritems():
358+ mkfs = 'mkfs.%s' % "ext4"
359+ proc = cmd_runner.run(
360+ [mkfs, dev, '-L', label],
361+ as_root=True)
362+ proc.wait()
363+
364+ proc = cmd_runner.run(
365+ ['mkfs.vfat', '-F', str(board_config.fat_size), sdcard, '-n',
366+ "sdcard"],
367+ as_root=True)
368+ proc.wait()
369+
370+ return bootfs, rootfs, system, cache, data, sdcard
371+
372 # I wonder if it'd make sense to convert this into a small shim which calls
373 # the appropriate function for the given type of device? I think it's still
374 # small enough that there's not much benefit in doing that, but if it grows we
375@@ -212,6 +264,35 @@
376 "Couldn't find root partition on %s" % image_file)
377 return vfat_size, vfat_offset, linux_size, linux_offset
378
379+def get_android_partitions_for_media(media, board_config):
380+ """Return the device files for all the Android partitions of media.
381+
382+ For boot we use partition number 1 plus the board's defined partition
383+ offset and for root we use partition number 2 plus the board's offset.
384+
385+ This function must only be used for block devices.
386+ """
387+ assert media.is_block_device, (
388+ "This function must only be used for block devices")
389+
390+ boot_partition = _get_device_file_for_partition_number(
391+ media.path, 1 + board_config.mmc_part_offset)
392+ root_partition = _get_device_file_for_partition_number(
393+ media.path, 2 + board_config.mmc_part_offset)
394+ system_partition = _get_device_file_for_partition_number(
395+ media.path, 3 + board_config.mmc_part_offset)
396+ cache_partition = _get_device_file_for_partition_number(
397+ media.path, 5 + board_config.mmc_part_offset)
398+ data_partition = _get_device_file_for_partition_number(
399+ media.path, 6 + board_config.mmc_part_offset)
400+ sdcard_partition = _get_device_file_for_partition_number(
401+ media.path, 7 + board_config.mmc_part_offset)
402+
403+ assert boot_partition is not None and root_partition is not None, (
404+ "Could not find boot/root partition for %s" % media.path)
405+
406+ return boot_partition, root_partition, system_partition, \
407+ cache_partition, data_partition, sdcard_partition
408
409 def get_boot_and_root_partitions_for_media(media, board_config):
410 """Return the device files for the boot and root partitions of media.
411@@ -307,7 +388,7 @@
412
413
414 def create_partitions(board_config, media, heads, sectors, cylinders=None,
415- should_align_boot_part=False):
416+ should_align_boot_part=False, image_type=None):
417 """Partition the given media according to the board requirements.
418
419 :param board_config: A BoardConfig class.
420@@ -326,8 +407,13 @@
421 ['parted', '-s', media.path, 'mklabel', 'msdos'], as_root=True)
422 proc.wait()
423
424- sfdisk_cmd = board_config.get_sfdisk_cmd(
425- should_align_boot_part=should_align_boot_part)
426+ if image_type == "ANDROID":
427+ sfdisk_cmd = board_config.get_android_sfdisk_cmd(
428+ should_align_boot_part=should_align_boot_part)
429+ else:
430+ sfdisk_cmd = board_config.get_sfdisk_cmd(
431+ should_align_boot_part=should_align_boot_part)
432+
433 run_sfdisk_commands(sfdisk_cmd, heads, sectors, cylinders, media.path)
434
435 # Sync and sleep to wait for the partition to settle.
436
437=== modified file 'linaro_image_tools/media_create/rootfs.py'
438--- linaro_image_tools/media_create/rootfs.py 2011-03-24 10:10:38 +0000
439+++ linaro_image_tools/media_create/rootfs.py 2011-04-04 09:27:32 +0000
440@@ -23,6 +23,13 @@
441
442 from linaro_image_tools import cmd_runner
443
444+def populate_partition(content_dir, root_disk, partition):
445+ os.makedirs(root_disk)
446+ cmd_runner.run(['mount', partition, root_disk], as_root=True).wait()
447+ move_contents(content_dir, root_disk)
448+ cmd_runner.run(['sync']).wait()
449+ cmd_runner.run(['umount', root_disk], as_root=True).wait()
450+
451
452 def populate_rootfs(content_dir, root_disk, partition, rootfs_type,
453 rootfs_uuid, should_create_swap, swap_size,
454
455=== modified file 'linaro_image_tools/media_create/unpack_binary_tarball.py'
456--- linaro_image_tools/media_create/unpack_binary_tarball.py 2011-03-24 10:10:38 +0000
457+++ linaro_image_tools/media_create/unpack_binary_tarball.py 2011-04-04 09:27:32 +0000
458@@ -20,6 +20,13 @@
459 from linaro_image_tools import cmd_runner
460
461
462+def unpack_android_binary_tarball(tarball, unpack_dir, as_root=True):
463+ proc = cmd_runner.run(
464+ ['tar', '--numeric-owner', '-C', unpack_dir, '-jxf', tarball],
465+ as_root=as_root)
466+ proc.wait()
467+ return proc.returncode
468+
469 def unpack_binary_tarball(tarball, unpack_dir, as_root=True):
470 proc = cmd_runner.run(
471 ['tar', '--numeric-owner', '-C', unpack_dir, '-xf', tarball],
472
473=== modified file 'setup.py'
474--- setup.py 2011-02-01 16:59:53 +0000
475+++ setup.py 2011-04-04 09:27:32 +0000
476@@ -14,5 +14,6 @@
477
478 scripts=[
479 "linaro-hwpack-create", "linaro-hwpack-install",
480- "linaro-media-create"],
481+ "linaro-media-create",
482+ "linaro-android-media-create"],
483 )

Subscribers

People subscribed via source and target branches