Merge "lt26: enable building custom boot.elf"
diff --git a/BoardConfig.mk b/BoardConfig.mk
index 296336a..01d8e9e 100644
--- a/BoardConfig.mk
+++ b/BoardConfig.mk
@@ -60,3 +60,4 @@
 BOARD_USERDATA_PARTITION_SIZE := 2147483648
 BOARD_FLASH_BLOCK_SIZE := 131072
 
+BOARD_CUSTOM_BOOTIMAGE_MK := device/sony/lt26/custombootimg.mk
diff --git a/tools/mkelf.py b/tools/mkelf.py
new file mode 100755
index 0000000..26f4c93
--- /dev/null
+++ b/tools/mkelf.py
@@ -0,0 +1,189 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2012, Sony Mobile Communications AB
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#    * Redistributions of source code must retain the above copyright
+#      notice, this list of conditions and the following disclaimer.
+#    * Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions and the following disclaimer in
+#      the documentation and/or other materials provided with the
+#      distribution.
+#    * Neither the name of Sony Mobile Communications AB nor the names
+#      of its contributors may be used to endorse or promote products
+#      derived from this software without specific prior written
+#      permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# DESCRIPTION
+#
+#   Combine one or more files to a elf file.
+#
+# SYNOPSIS
+#
+#   mkelf.py -o elf file@addr[,ramdisk] ...
+#
+#   elf         The path to the output file
+#   file        Input file
+#   addr        ELF vaddr and paddr of this file
+#   ramdisk     Mark this segment to be presented in ATAG list as ramdisk (optional)
+#   ipl         Mark this segment to be handled by the boot code as IPL (optional)
+#   cmdline     Mark this segment to be handled by the boot code as kernel cmdline (optional)
+#
+
+import re
+import os
+import sys
+import struct
+from optparse import OptionParser
+
+# Elf definitions
+PT_NULL = 0
+PT_LOAD = 1
+PT_NOTE = 4
+
+# SEMC Elf definitions
+P_FLAGS_RAMDISK = 0x80000000
+P_FLAGS_IPL     = 0x40000000 # used for STE U8500
+P_FLAGS_CMDLINE = 0x20000000
+P_FLAGS_RPM     = 0x01000000 # used for QCT MSM8x60
+
+def fatal(message):
+    print >> sys.stderr, '%s: %s' % (os.path.basename(sys.argv[0]), message)
+    sys.exit(1)
+
+def parse_inputs(args):
+    segs = []
+    for arg in args:
+        try:
+            seg = {}
+            tokens = arg.split('@')
+            if len(tokens) != 2:
+                fatal('Incorrect format of input parameter: ' + arg)
+
+            seg['file'] = tokens[0]
+            if tokens[1] == 'cmdline':
+                seg['addr'] = '0'
+                seg['flags'] = 'cmdline'
+            else:
+                input = re.match("^(0x[0-9a-fA-F]+)(?:,(ramdisk|ipl|entry|rpm))?$", tokens[1]).groups()
+                seg['addr'] = input[0]
+                seg['flags'] = input[1]
+            segs.append(seg)
+        except AttributeError:
+            fatal("Incorrect format of input parameter: " + arg)
+    return segs
+
+def write_elf_header(elf, entry, phnum):
+    elfhdr = {
+        'e_ident': '\x7fELF\x01\x01\x01\x61',
+        'e_type': 2,
+        'e_machine': 40,
+        'e_version': 1,
+        'e_entry': long(entry, 16),
+        'e_phoff': 52,
+        'e_shoff': 0,
+        'e_flags': 0,
+        'e_ehsize': 52,
+        'e_phentsize': 32,
+        'e_phnum': phnum,
+        'e_shentsize': 0,
+        'e_shnum': 0,
+        'e_shstrndx': 0
+    }
+
+    elf.write(struct.pack('<8s8xHHLLLLLHHHHHH',
+                           elfhdr['e_ident'], elfhdr['e_type'], elfhdr['e_machine'],
+                           elfhdr['e_version'], elfhdr['e_entry'], elfhdr['e_phoff'],
+                           elfhdr['e_shoff'], elfhdr['e_flags'], elfhdr['e_ehsize'],
+                           elfhdr['e_phentsize'], elfhdr['e_phnum'], elfhdr['e_shentsize'],
+                           elfhdr['e_shnum'], elfhdr['e_shstrndx']))
+
+def write_elf_phdr(elf, seg):
+    type = PT_LOAD
+    flags = 0
+
+    if seg['flags'] == 'ramdisk':
+        flags = P_FLAGS_RAMDISK
+    elif seg['flags'] == 'ipl':
+        flags = P_FLAGS_IPL
+    elif seg['flags'] == 'cmdline':
+        flags = P_FLAGS_CMDLINE
+        type = PT_NOTE
+    elif seg['flags'] == 'rpm':
+        flags = P_FLAGS_RPM
+
+    elfphdr = {
+        'p_type': type,
+        'p_offset': seg['offset'],
+        'p_vaddr': long(seg['addr'], 16),
+        'p_paddr': long(seg['addr'], 16),
+        'p_filesz': seg['size'],
+        'p_memsz': seg['size'],
+        'p_flags': flags,
+        'p_align': 0
+    }
+
+    elf.write(struct.pack('<LLLLLLLL',
+                          elfphdr['p_type'],
+                          elfphdr['p_offset'],
+                          elfphdr['p_vaddr'],
+                          elfphdr['p_paddr'],
+                          elfphdr['p_filesz'],
+                          elfphdr['p_memsz'],
+                          elfphdr['p_flags'],
+                          elfphdr['p_align']))
+
+def main(args):
+    parser = OptionParser("usage: %prog options")
+    parser.add_option("-o", dest="outputfile", help="path to the output file")
+    (opts, args) = parser.parse_args()
+
+    if not opts.outputfile:
+        fatal("Missing -o on command line")
+    if len(args) < 1:
+        fatal("Missing input files")
+
+    offset = 4096
+    segments = []
+    for seg in parse_inputs(args):
+        size = os.path.getsize(seg['file'])
+        seg['offset'] = offset
+        seg['size'] = size
+        segments.append(seg)
+        offset += size
+
+    elf = open(opts.outputfile, 'wb')
+
+    write_elf_header(elf, segments[0]['addr'], len(segments))
+    for seg in segments:
+        write_elf_phdr(elf, seg)
+
+    for seg in segments:
+        elf.seek(seg['offset'])
+
+        f = open(seg['file'], 'rb')
+        data = f.read()
+        elf.write(data)
+        f.close()
+
+    elf.close()
+
+if __name__ == "__main__":
+    main(sys.argv[1:])
+