diff options
| author | Tom Zanussi <tom.zanussi@intel.com> | 2012-01-24 00:25:45 -0600 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2012-03-22 19:21:15 +0000 |
| commit | 1e40e8a2306cac37e0dccfdc042a3d39c5cd9159 (patch) | |
| tree | 592c5716f9cf482ab585877a482d52043d192e8d /scripts/lib/bsp/kernel.py | |
| parent | cd8182e6892986d73a1f0252d38682b9d5c07b22 (diff) | |
| download | poky-1e40e8a2306cac37e0dccfdc042a3d39c5cd9159.tar.gz | |
yocto-bsp: add kernel interface
Yocto BSP kernel-related functions, for interacting with the kernel
tools and implementing the machinery behind the 'yocto-kernel'
command.
Signed-off-by: Tom Zanussi <tom.zanussi@intel.com>
Diffstat (limited to 'scripts/lib/bsp/kernel.py')
| -rw-r--r-- | scripts/lib/bsp/kernel.py | 723 |
1 files changed, 723 insertions, 0 deletions
diff --git a/scripts/lib/bsp/kernel.py b/scripts/lib/bsp/kernel.py new file mode 100644 index 0000000000..b4e7fbf062 --- /dev/null +++ b/scripts/lib/bsp/kernel.py | |||
| @@ -0,0 +1,723 @@ | |||
| 1 | # ex:ts=4:sw=4:sts=4:et | ||
| 2 | # -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- | ||
| 3 | # | ||
| 4 | # Copyright (c) 2012, Intel Corporation. | ||
| 5 | # All rights reserved. | ||
| 6 | # | ||
| 7 | # This program is free software; you can redistribute it and/or modify | ||
| 8 | # it under the terms of the GNU General Public License version 2 as | ||
| 9 | # published by the Free Software Foundation. | ||
| 10 | # | ||
| 11 | # This program is distributed in the hope that it will be useful, | ||
| 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | # GNU General Public License for more details. | ||
| 15 | # | ||
| 16 | # You should have received a copy of the GNU General Public License along | ||
| 17 | # with this program; if not, write to the Free Software Foundation, Inc., | ||
| 18 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | # | ||
| 20 | # DESCRIPTION | ||
| 21 | # This module implements the kernel-related functions used by | ||
| 22 | # 'yocto-kernel' to manage kernel config items and patches for Yocto | ||
| 23 | # BSPs. | ||
| 24 | # | ||
| 25 | # AUTHORS | ||
| 26 | # Tom Zanussi <tom.zanussi (at] intel.com> | ||
| 27 | # | ||
| 28 | |||
| 29 | import sys | ||
| 30 | import os | ||
| 31 | import shutil | ||
| 32 | from tags import * | ||
| 33 | import glob | ||
| 34 | |||
| 35 | |||
| 36 | def find_bblayers(scripts_path): | ||
| 37 | """ | ||
| 38 | Find and return a sanitized list of the layers found in BBLAYERS. | ||
| 39 | """ | ||
| 40 | bblayers_conf = os.path.join(scripts_path, "../build/conf/bblayers.conf") | ||
| 41 | |||
| 42 | layers = [] | ||
| 43 | |||
| 44 | f = open(bblayers_conf, "r") | ||
| 45 | lines = f.readlines() | ||
| 46 | bblayers_lines = [] | ||
| 47 | in_bblayers = False | ||
| 48 | for line in lines: | ||
| 49 | line = line.strip() | ||
| 50 | if line.strip().startswith("BBLAYERS"): | ||
| 51 | bblayers_lines.append(line) | ||
| 52 | in_bblayers = True | ||
| 53 | quotes = line.strip().count('"') | ||
| 54 | if quotes > 1: | ||
| 55 | break | ||
| 56 | continue | ||
| 57 | if in_bblayers: | ||
| 58 | bblayers_lines.append(line) | ||
| 59 | if line.strip().endswith("\""): | ||
| 60 | break | ||
| 61 | else: | ||
| 62 | continue | ||
| 63 | |||
| 64 | for i, line in enumerate(bblayers_lines): | ||
| 65 | if line.strip().endswith("\\"): | ||
| 66 | bblayers_lines[i] = line.strip().replace('\\', '') | ||
| 67 | |||
| 68 | bblayers_line = " ".join(bblayers_lines) | ||
| 69 | |||
| 70 | start_quote = bblayers_line.find("\"") | ||
| 71 | if start_quote == -1: | ||
| 72 | print "Invalid BBLAYERS found in %s, exiting" % bblayers_conf | ||
| 73 | sys.exit(1) | ||
| 74 | |||
| 75 | start_quote += 1 | ||
| 76 | end_quote = bblayers_line.find("\"", start_quote) | ||
| 77 | if end_quote == -1: | ||
| 78 | print "Invalid BBLAYERS found in %s, exiting" % bblayers_conf | ||
| 79 | sys.exit(1) | ||
| 80 | |||
| 81 | bblayers_line = bblayers_line[start_quote:end_quote] | ||
| 82 | layers = bblayers_line.split() | ||
| 83 | |||
| 84 | f.close() | ||
| 85 | |||
| 86 | return layers | ||
| 87 | |||
| 88 | |||
| 89 | def find_meta_layer(scripts_path): | ||
| 90 | """ | ||
| 91 | Find and return the meta layer in BBLAYERS. | ||
| 92 | """ | ||
| 93 | layers = find_bblayers(scripts_path) | ||
| 94 | |||
| 95 | for layer in layers: | ||
| 96 | if layer.endswith("meta"): | ||
| 97 | return layer | ||
| 98 | |||
| 99 | return None | ||
| 100 | |||
| 101 | |||
| 102 | def find_bsp_layer(scripts_path, machine): | ||
| 103 | """ | ||
| 104 | Find and return a machine's BSP layer in BBLAYERS. | ||
| 105 | """ | ||
| 106 | layers = find_bblayers(scripts_path) | ||
| 107 | |||
| 108 | for layer in layers: | ||
| 109 | if machine in layer: | ||
| 110 | return layer | ||
| 111 | |||
| 112 | print "Unable to find the BSP layer for machine %s." % machine | ||
| 113 | print "Please make sure it is listed in bblayers.conf" | ||
| 114 | sys.exit(1) | ||
| 115 | |||
| 116 | |||
| 117 | def gen_choices_str(choices): | ||
| 118 | """ | ||
| 119 | Generate a numbered list of choices from a list of choices for | ||
| 120 | display to the user. | ||
| 121 | """ | ||
| 122 | choices_str = "" | ||
| 123 | |||
| 124 | for i, choice in enumerate(choices): | ||
| 125 | choices_str += "\t" + str(i + 1) + ") " + choice + "\n" | ||
| 126 | |||
| 127 | return choices_str | ||
| 128 | |||
| 129 | |||
| 130 | def read_config_items(scripts_path, machine): | ||
| 131 | """ | ||
| 132 | Find and return a list of config items (CONFIG_XXX) in a machine's | ||
| 133 | user-defined config fragment [user-config.cfg]. | ||
| 134 | """ | ||
| 135 | config_items = [] | ||
| 136 | |||
| 137 | layer = find_bsp_layer(scripts_path, machine) | ||
| 138 | cfg = os.path.join(layer, "recipes-kernel/linux/files/user-config.cfg") | ||
| 139 | |||
| 140 | f = open(cfg, "r") | ||
| 141 | lines = f.readlines() | ||
| 142 | for line in lines: | ||
| 143 | s = line.strip() | ||
| 144 | if s: | ||
| 145 | config_items.append(s) | ||
| 146 | f.close() | ||
| 147 | |||
| 148 | return config_items | ||
| 149 | |||
| 150 | |||
| 151 | def write_config_items(scripts_path, machine, config_items): | ||
| 152 | """ | ||
| 153 | Write (replace) the list of config items (CONFIG_XXX) in a | ||
| 154 | machine's user-defined config fragment [user-config.cfg]. | ||
| 155 | """ | ||
| 156 | layer = find_bsp_layer(scripts_path, machine) | ||
| 157 | cfg = os.path.join(layer, "recipes-kernel/linux/files/user-config.cfg") | ||
| 158 | |||
| 159 | f = open(cfg, "w") | ||
| 160 | for item in config_items: | ||
| 161 | f.write(item + "\n") | ||
| 162 | f.close() | ||
| 163 | |||
| 164 | kernel_contents_changed(scripts_path, machine) | ||
| 165 | |||
| 166 | |||
| 167 | def yocto_kernel_config_list(scripts_path, machine): | ||
| 168 | """ | ||
| 169 | Display the list of config items (CONFIG_XXX) in a machine's | ||
| 170 | user-defined config fragment [user-config.cfg]. | ||
| 171 | """ | ||
| 172 | config_items = read_config_items(scripts_path, machine) | ||
| 173 | |||
| 174 | print "The current set of machine-specific kernel config items for %s is:" % machine | ||
| 175 | print gen_choices_str(config_items) | ||
| 176 | |||
| 177 | |||
| 178 | def map_choice(choice_str, array): | ||
| 179 | """ | ||
| 180 | Match the text of a choice with a list of choices, returning the | ||
| 181 | index of the match, or -1 if not found. | ||
| 182 | """ | ||
| 183 | for i, item in enumerate(array): | ||
| 184 | if choice_str == array[i]: | ||
| 185 | return i | ||
| 186 | |||
| 187 | return -1 | ||
| 188 | |||
| 189 | |||
| 190 | def yocto_kernel_config_rm(scripts_path, machine): | ||
| 191 | """ | ||
| 192 | Display the list of config items (CONFIG_XXX) in a machine's | ||
| 193 | user-defined config fragment [user-config.cfg], prompt the user | ||
| 194 | for one or more to remove, and remove them. | ||
| 195 | """ | ||
| 196 | config_items = read_config_items(scripts_path, machine) | ||
| 197 | |||
| 198 | print "Specify the kernel config items to remove:" | ||
| 199 | input = raw_input(gen_choices_str(config_items)) | ||
| 200 | rm_choices = input.split() | ||
| 201 | rm_choices.sort() | ||
| 202 | |||
| 203 | removed = [] | ||
| 204 | |||
| 205 | for choice in reversed(rm_choices): | ||
| 206 | try: | ||
| 207 | idx = int(choice) - 1 | ||
| 208 | except ValueError: | ||
| 209 | print "Invalid choice (%s), exiting" % choice | ||
| 210 | sys.exit(1) | ||
| 211 | if idx < 0 or idx >= len(config_items): | ||
| 212 | print "Invalid choice (%d), exiting" % (idx + 1) | ||
| 213 | sys.exit(1) | ||
| 214 | removed.append(config_items.pop(idx)) | ||
| 215 | |||
| 216 | write_config_items(scripts_path, machine, config_items) | ||
| 217 | |||
| 218 | print "Removed items:" | ||
| 219 | for r in removed: | ||
| 220 | print "\t%s" % r | ||
| 221 | |||
| 222 | |||
| 223 | def yocto_kernel_config_add(scripts_path, machine, config_items): | ||
| 224 | """ | ||
| 225 | Add one or more config items (CONFIG_XXX) to a machine's | ||
| 226 | user-defined config fragment [user-config.cfg]. | ||
| 227 | """ | ||
| 228 | new_items = [] | ||
| 229 | |||
| 230 | for item in config_items: | ||
| 231 | if not item.startswith("CONFIG") or (not "=y" in item and not "=m" in item): | ||
| 232 | print "Invalid config item (%s), exiting" % item | ||
| 233 | sys.exit(1) | ||
| 234 | new_items.append(item) | ||
| 235 | |||
| 236 | cur_items = read_config_items(scripts_path, machine) | ||
| 237 | cur_items.extend(new_items) | ||
| 238 | |||
| 239 | write_config_items(scripts_path, machine, cur_items) | ||
| 240 | |||
| 241 | print "Added items:" | ||
| 242 | for n in new_items: | ||
| 243 | print "\t%s" % n | ||
| 244 | |||
| 245 | |||
| 246 | def find_current_kernel(bsp_layer, machine): | ||
| 247 | """ | ||
| 248 | Determine the kernel and version currently being used in the BSP. | ||
| 249 | """ | ||
| 250 | machine_conf = os.path.join(bsp_layer, "conf/machine/" + machine + ".conf") | ||
| 251 | |||
| 252 | preferred_kernel = preferred_kernel_version = preferred_version_varname = None | ||
| 253 | |||
| 254 | f = open(machine_conf, "r") | ||
| 255 | lines = f.readlines() | ||
| 256 | for line in lines: | ||
| 257 | if line.strip().startswith("PREFERRED_PROVIDER_virtual/kernel"): | ||
| 258 | preferred_kernel = line.split()[-1] | ||
| 259 | preferred_kernel = preferred_kernel.replace('\"','') | ||
| 260 | preferred_version_varname = "PREFERRED_VERSION_" + preferred_kernel | ||
| 261 | if preferred_version_varname and line.strip().startswith(preferred_version_varname): | ||
| 262 | preferred_kernel_version = line.split()[-1] | ||
| 263 | preferred_kernel_version = preferred_kernel_version.replace('\"','') | ||
| 264 | preferred_kernel_version = preferred_kernel_version.replace('%','') | ||
| 265 | |||
| 266 | if preferred_kernel and preferred_kernel_version: | ||
| 267 | return preferred_kernel + "_" + preferred_kernel_version | ||
| 268 | |||
| 269 | |||
| 270 | def find_bsp_kernel_src_uri(scripts_path, machine, start_end_only = False): | ||
| 271 | """ | ||
| 272 | Parse the SRC_URI append in the kernel .bbappend, returing a list | ||
| 273 | of individual components, and the start/end positions of the | ||
| 274 | SRC_URI statement, so it can be regenerated in the same position. | ||
| 275 | If start_end_only is True, don't return the list of elements, only | ||
| 276 | the start and end positions. | ||
| 277 | |||
| 278 | Returns (SRC_URI start line, SRC_URI end_line, list of split | ||
| 279 | SRC_URI items). | ||
| 280 | |||
| 281 | If no SRC_URI, start line = -1. | ||
| 282 | |||
| 283 | NOTE: this and all the src_uri functions are temporary and | ||
| 284 | deprecated and will be removed, but are needed until the | ||
| 285 | equivalent .scc mechanism works. i.e. for now we unfortunately | ||
| 286 | can't get around putting patches in the SRC_URI. | ||
| 287 | """ | ||
| 288 | layer = find_bsp_layer(scripts_path, machine) | ||
| 289 | |||
| 290 | kernel = find_current_kernel(layer, machine) | ||
| 291 | if not kernel: | ||
| 292 | print "Couldn't determine the kernel for this BSP, exiting." | ||
| 293 | sys.exit(1) | ||
| 294 | |||
| 295 | kernel_bbappend = os.path.join(layer, "recipes-kernel/linux/" + kernel + ".bbappend") | ||
| 296 | |||
| 297 | f = open(kernel_bbappend, "r") | ||
| 298 | src_uri_line = "" | ||
| 299 | in_src_uri = False | ||
| 300 | lines = f.readlines() | ||
| 301 | first_line = last_line = -1 | ||
| 302 | quote_start = quote_end = -1 | ||
| 303 | for n, line in enumerate(lines): | ||
| 304 | line = line.strip() | ||
| 305 | if line.startswith("SRC_URI"): | ||
| 306 | first_line = n | ||
| 307 | in_src_uri = True | ||
| 308 | if in_src_uri: | ||
| 309 | src_uri_line += line | ||
| 310 | if quote_start == -1: | ||
| 311 | idx = line.find("\"") | ||
| 312 | if idx != -1: | ||
| 313 | quote_start = idx + 1 | ||
| 314 | idx = line.find("\"", quote_start) | ||
| 315 | quote_start = 0 # set to 0 for all but first line | ||
| 316 | if idx != -1: | ||
| 317 | quote_end = idx | ||
| 318 | last_line = n | ||
| 319 | break | ||
| 320 | |||
| 321 | if first_line == -1: # no SRC_URI, which is fine too | ||
| 322 | return (-1, -1, None) | ||
| 323 | if quote_start == -1: | ||
| 324 | print "Bad kernel SRC_URI (missing opening quote), exiting." | ||
| 325 | sys.exit(1) | ||
| 326 | if quote_end == -1: | ||
| 327 | print "Bad SRC_URI (missing closing quote), exiting." | ||
| 328 | sys.exit(1) | ||
| 329 | if start_end_only: | ||
| 330 | return (first_line, last_line, None) | ||
| 331 | |||
| 332 | idx = src_uri_line.find("\"") | ||
| 333 | src_uri_line = src_uri_line[idx + 1:] | ||
| 334 | idx = src_uri_line.find("\"") | ||
| 335 | src_uri_line = src_uri_line[:idx] | ||
| 336 | |||
| 337 | src_uri = src_uri_line.split() | ||
| 338 | for i, item in enumerate(src_uri): | ||
| 339 | idx = item.find("\\") | ||
| 340 | if idx != -1: | ||
| 341 | src_uri[i] = item[idx + 1:] | ||
| 342 | |||
| 343 | if not src_uri[len(src_uri) - 1]: | ||
| 344 | src_uri.pop() | ||
| 345 | |||
| 346 | for i, item in enumerate(src_uri): | ||
| 347 | idx = item.find(SRC_URI_FILE) | ||
| 348 | if idx == -1: | ||
| 349 | print "Bad SRC_URI (invalid item, %s), exiting." % item | ||
| 350 | sys.exit(1) | ||
| 351 | src_uri[i] = item[idx + len(SRC_URI_FILE):] | ||
| 352 | |||
| 353 | return (first_line, last_line, src_uri) | ||
| 354 | |||
| 355 | |||
| 356 | def find_patches(src_uri): | ||
| 357 | """ | ||
| 358 | Filter out the top-level patches from the SRC_URI. | ||
| 359 | """ | ||
| 360 | patches = [] | ||
| 361 | for item in src_uri: | ||
| 362 | if item.endswith(".patch") and "/" not in item: | ||
| 363 | patches.append(item) | ||
| 364 | return patches | ||
| 365 | |||
| 366 | |||
| 367 | def read_patch_items(scripts_path, machine): | ||
| 368 | """ | ||
| 369 | Find and return a list of patch items in a machine's user-defined | ||
| 370 | patch list [user-patches.scc]. | ||
| 371 | """ | ||
| 372 | patch_items = [] | ||
| 373 | |||
| 374 | layer = find_bsp_layer(scripts_path, machine) | ||
| 375 | patches = os.path.join(layer, "recipes-kernel/linux/files/user-patches.scc") | ||
| 376 | |||
| 377 | f = open(patches, "r") | ||
| 378 | lines = f.readlines() | ||
| 379 | for line in lines: | ||
| 380 | s = line.strip() | ||
| 381 | if s: | ||
| 382 | fields = s.split() | ||
| 383 | if not fields[0] == "patch": | ||
| 384 | continue | ||
| 385 | patch_items.append(fields[1]) | ||
| 386 | f.close() | ||
| 387 | |||
| 388 | return patch_items | ||
| 389 | |||
| 390 | |||
| 391 | def write_patch_items(scripts_path, machine, patch_items): | ||
| 392 | """ | ||
| 393 | Write (replace) the list of patches in a machine's user-defined | ||
| 394 | patch list [user-patches.scc]. | ||
| 395 | """ | ||
| 396 | layer = find_bsp_layer(scripts_path, machine) | ||
| 397 | |||
| 398 | patches = os.path.join(layer, "recipes-kernel/linux/files/user-patches.scc") | ||
| 399 | |||
| 400 | f = open(patches, "w") | ||
| 401 | for item in patch_items: | ||
| 402 | pass | ||
| 403 | # this currently breaks do_patch, but is really what we want | ||
| 404 | # once this works, we can remove all the src_uri stuff | ||
| 405 | # f.write("patch " + item + "\n") | ||
| 406 | f.close() | ||
| 407 | |||
| 408 | kernel_contents_changed(scripts_path, machine) | ||
| 409 | |||
| 410 | |||
| 411 | def yocto_kernel_patch_list(scripts_path, machine): | ||
| 412 | """ | ||
| 413 | Display the list of patches in a machine's user-defined patch list | ||
| 414 | [user-patches.scc]. | ||
| 415 | """ | ||
| 416 | (start_line, end_line, src_uri) = find_bsp_kernel_src_uri(scripts_path, machine) | ||
| 417 | patches = find_patches(src_uri) | ||
| 418 | |||
| 419 | print "The current set of machine-specific patches for %s is:" % machine | ||
| 420 | print gen_choices_str(patches) | ||
| 421 | |||
| 422 | |||
| 423 | def yocto_kernel_patch_rm(scripts_path, machine): | ||
| 424 | """ | ||
| 425 | Remove one or more patches from a machine's user-defined patch | ||
| 426 | list [user-patches.scc]. | ||
| 427 | """ | ||
| 428 | (start_line, end_line, src_uri) = find_bsp_kernel_src_uri(scripts_path, machine) | ||
| 429 | patches = find_patches(src_uri) | ||
| 430 | |||
| 431 | print "Specify the patches to remove:" | ||
| 432 | input = raw_input(gen_choices_str(patches)) | ||
| 433 | rm_choices = input.split() | ||
| 434 | rm_choices.sort() | ||
| 435 | |||
| 436 | removed = [] | ||
| 437 | |||
| 438 | layer = find_bsp_layer(scripts_path, machine) | ||
| 439 | src_uri_dir = os.path.join(layer, "recipes-kernel/linux/files") | ||
| 440 | |||
| 441 | for choice in reversed(rm_choices): | ||
| 442 | try: | ||
| 443 | idx = int(choice) - 1 | ||
| 444 | except ValueError: | ||
| 445 | print "Invalid choice (%s), exiting" % choice | ||
| 446 | sys.exit(1) | ||
| 447 | if idx < 0 or idx >= len(patches): | ||
| 448 | print "Invalid choice (%d), exiting" % (idx + 1) | ||
| 449 | sys.exit(1) | ||
| 450 | src_uri_patch = os.path.join(src_uri_dir, patches[idx]) | ||
| 451 | if os.path.isfile(src_uri_patch): | ||
| 452 | os.remove(src_uri_patch) | ||
| 453 | idx = map_choice(patches[idx], src_uri) | ||
| 454 | removed.append(src_uri.pop(idx)) | ||
| 455 | |||
| 456 | write_patch_items(scripts_path, machine, patches) | ||
| 457 | write_kernel_src_uri(scripts_path, machine, src_uri) | ||
| 458 | |||
| 459 | print "Removed patches:" | ||
| 460 | for r in removed: | ||
| 461 | print "\t%s" % r | ||
| 462 | |||
| 463 | |||
| 464 | def yocto_kernel_patch_add(scripts_path, machine, patches): | ||
| 465 | """ | ||
| 466 | Add one or more patches to a machine's user-defined patch list | ||
| 467 | [user-patches.scc]. | ||
| 468 | """ | ||
| 469 | (start_line, end_line, src_uri) = find_bsp_kernel_src_uri(scripts_path, machine) | ||
| 470 | src_uri_patches = find_patches(src_uri) | ||
| 471 | |||
| 472 | for patch in patches: | ||
| 473 | if os.path.basename(patch) in src_uri_patches: | ||
| 474 | print "Couldn't add patch (%s) since it's already been added" % os.path.basename(patch) | ||
| 475 | sys.exit(1) | ||
| 476 | |||
| 477 | layer = find_bsp_layer(scripts_path, machine) | ||
| 478 | src_uri_dir = os.path.join(layer, "recipes-kernel/linux/files") | ||
| 479 | |||
| 480 | new_patches = [] | ||
| 481 | |||
| 482 | for patch in patches: | ||
| 483 | if not os.path.isfile(patch): | ||
| 484 | print "Couldn't find patch (%s), exiting" % patch | ||
| 485 | sys.exit(1) | ||
| 486 | basename = os.path.basename(patch) | ||
| 487 | src_uri_patch = os.path.join(src_uri_dir, basename) | ||
| 488 | shutil.copyfile(patch, src_uri_patch) | ||
| 489 | new_patches.append(basename) | ||
| 490 | |||
| 491 | cur_items = read_patch_items(scripts_path, machine) | ||
| 492 | cur_items.extend(new_patches) | ||
| 493 | write_patch_items(scripts_path, machine, cur_items) | ||
| 494 | |||
| 495 | (unused, unused, src_uri) = find_bsp_kernel_src_uri(scripts_path, machine) | ||
| 496 | src_uri.extend(new_patches) | ||
| 497 | write_kernel_src_uri(scripts_path, machine, src_uri) | ||
| 498 | |||
| 499 | print "Added patches:" | ||
| 500 | for n in new_patches: | ||
| 501 | print "\t%s" % n | ||
| 502 | |||
| 503 | |||
| 504 | def write_uri_lines(ofile, src_uri): | ||
| 505 | """ | ||
| 506 | Write URI elements to output file ofile. | ||
| 507 | """ | ||
| 508 | ofile.write("SRC_URI += \" \\\n") | ||
| 509 | for item in src_uri: | ||
| 510 | ofile.write("\t%s%s \\\n" % (SRC_URI_FILE, item)) | ||
| 511 | ofile.write("\t\"\n") | ||
| 512 | |||
| 513 | |||
| 514 | def inc_pr(line): | ||
| 515 | """ | ||
| 516 | Add 1 to the PR value in the given bbappend PR line. For the PR | ||
| 517 | lines in kernel .bbappends after modifications. | ||
| 518 | """ | ||
| 519 | idx = line.find("\"") | ||
| 520 | |||
| 521 | pr_str = line[idx:] | ||
| 522 | pr_str = pr_str.replace('\"','') | ||
| 523 | fields = pr_str.split('.') | ||
| 524 | fields[1] = str(int(fields[1]) + 1) | ||
| 525 | pr_str = "\"" + '.'.join(fields) + "\"\n" | ||
| 526 | |||
| 527 | idx2 = line.find("\"", idx + 1) | ||
| 528 | line = line[:idx] + pr_str | ||
| 529 | |||
| 530 | return line | ||
| 531 | |||
| 532 | |||
| 533 | def kernel_contents_changed(scripts_path, machine): | ||
| 534 | """ | ||
| 535 | Do what we need to do to notify the system that the kernel | ||
| 536 | recipe's contents have changed. | ||
| 537 | """ | ||
| 538 | layer = find_bsp_layer(scripts_path, machine) | ||
| 539 | |||
| 540 | kernel = find_current_kernel(layer, machine) | ||
| 541 | if not kernel: | ||
| 542 | print "Couldn't determine the kernel for this BSP, exiting." | ||
| 543 | sys.exit(1) | ||
| 544 | |||
| 545 | kernel_bbappend = os.path.join(layer, "recipes-kernel/linux/" + kernel + ".bbappend") | ||
| 546 | kernel_bbappend_prev = kernel_bbappend + ".prev" | ||
| 547 | shutil.copyfile(kernel_bbappend, kernel_bbappend_prev) | ||
| 548 | |||
| 549 | ifile = open(kernel_bbappend_prev, "r") | ||
| 550 | ofile = open(kernel_bbappend, "w") | ||
| 551 | ifile_lines = ifile.readlines() | ||
| 552 | for ifile_line in ifile_lines: | ||
| 553 | if ifile_line.strip().startswith("PR"): | ||
| 554 | ifile_line = inc_pr(ifile_line) | ||
| 555 | ofile.write(ifile_line) | ||
| 556 | ofile.close() | ||
| 557 | ifile.close() | ||
| 558 | |||
| 559 | |||
| 560 | def write_kernel_src_uri(scripts_path, machine, src_uri): | ||
| 561 | """ | ||
| 562 | Write (replace) the SRC_URI append for a machine from a list | ||
| 563 | SRC_URI elements. | ||
| 564 | """ | ||
| 565 | layer = find_bsp_layer(scripts_path, machine) | ||
| 566 | |||
| 567 | kernel = find_current_kernel(layer, machine) | ||
| 568 | if not kernel: | ||
| 569 | print "Couldn't determine the kernel for this BSP, exiting." | ||
| 570 | sys.exit(1) | ||
| 571 | |||
| 572 | kernel_bbappend = os.path.join(layer, "recipes-kernel/linux/" + kernel + ".bbappend") | ||
| 573 | |||
| 574 | (uri_start_line, uri_end_line, unused) = find_bsp_kernel_src_uri(scripts_path, machine, True) | ||
| 575 | |||
| 576 | kernel_bbappend_prev = kernel_bbappend + ".prev" | ||
| 577 | shutil.copyfile(kernel_bbappend, kernel_bbappend_prev) | ||
| 578 | ifile = open(kernel_bbappend_prev, "r") | ||
| 579 | ofile = open(kernel_bbappend, "w") | ||
| 580 | |||
| 581 | ifile_lines = ifile.readlines() | ||
| 582 | if uri_start_line == -1: | ||
| 583 | uri_end_line = len(ifile_lines) # make sure we add at end | ||
| 584 | wrote_src_uri = False | ||
| 585 | for i, ifile_line in enumerate(ifile_lines): | ||
| 586 | if ifile_line.strip().startswith("PR"): | ||
| 587 | ifile_line = inc_pr(ifile_line) | ||
| 588 | if i < uri_start_line: | ||
| 589 | ofile.write(ifile_line) | ||
| 590 | elif i > uri_end_line: | ||
| 591 | ofile.write(ifile_line) | ||
| 592 | else: | ||
| 593 | if not wrote_src_uri: | ||
| 594 | write_uri_lines(ofile, src_uri) | ||
| 595 | wrote_src_uri = True | ||
| 596 | if uri_start_line == -1: | ||
| 597 | write_uri_lines(ofile, src_uri) | ||
| 598 | |||
| 599 | |||
| 600 | def kernels(context): | ||
| 601 | """ | ||
| 602 | Return the list of available kernels in the BSP i.e. corresponding | ||
| 603 | to the kernel .bbappends found in the layer. | ||
| 604 | """ | ||
| 605 | archdir = os.path.join(context["scripts_path"], "lib/bsp/substrate/target/arch/" + context["arch"]) | ||
| 606 | kerndir = os.path.join(archdir, "recipes-kernel/linux") | ||
| 607 | bbglob = os.path.join(kerndir, "*.bbappend") | ||
| 608 | |||
| 609 | bbappends = glob.glob(bbglob) | ||
| 610 | |||
| 611 | kernels = [] | ||
| 612 | |||
| 613 | for kernel in bbappends: | ||
| 614 | filename = os.path.splitext(os.path.basename(kernel))[0] | ||
| 615 | idx = filename.find(CLOSE_TAG) | ||
| 616 | if idx != -1: | ||
| 617 | filename = filename[idx + len(CLOSE_TAG):].strip() | ||
| 618 | kernels.append(filename) | ||
| 619 | |||
| 620 | return kernels | ||
| 621 | |||
| 622 | |||
| 623 | def extract_giturl(file): | ||
| 624 | """ | ||
| 625 | Extract the git url of the kernel repo from the kernel recipe's | ||
| 626 | SRC_URI. | ||
| 627 | """ | ||
| 628 | f = open(file, "r") | ||
| 629 | lines = f.readlines() | ||
| 630 | for line in lines: | ||
| 631 | line = line.strip() | ||
| 632 | if line.startswith("SRC_URI"): | ||
| 633 | line = line[len("SRC_URI"):].strip() | ||
| 634 | if line.startswith("="): | ||
| 635 | line = line[1:].strip() | ||
| 636 | if line.startswith("\""): | ||
| 637 | line = line[1:].strip() | ||
| 638 | fields = line.split(";") | ||
| 639 | if fields: | ||
| 640 | return fields[0] | ||
| 641 | return None | ||
| 642 | |||
| 643 | |||
| 644 | def find_giturl(context): | ||
| 645 | """ | ||
| 646 | Find the git url of the kernel repo from the kernel recipe's | ||
| 647 | SRC_URI. | ||
| 648 | """ | ||
| 649 | name = context["name"] | ||
| 650 | filebase = context["filename"] | ||
| 651 | scripts_path = context["scripts_path"] | ||
| 652 | |||
| 653 | meta_layer = find_meta_layer(scripts_path) | ||
| 654 | |||
| 655 | kerndir = os.path.join(meta_layer, "recipes-kernel/linux") | ||
| 656 | bbglob = os.path.join(kerndir, "*.bb") | ||
| 657 | bbs = glob.glob(bbglob) | ||
| 658 | for kernel in bbs: | ||
| 659 | filename = os.path.splitext(os.path.basename(kernel))[0] | ||
| 660 | if filename == filebase: | ||
| 661 | giturl = extract_giturl(kernel) | ||
| 662 | return giturl | ||
| 663 | |||
| 664 | return None | ||
| 665 | |||
| 666 | |||
| 667 | def base_branches(context): | ||
| 668 | """ | ||
| 669 | Return a list of the base branches found in the kernel git repo. | ||
| 670 | """ | ||
| 671 | giturl = find_giturl(context) | ||
| 672 | |||
| 673 | print "Getting branches from remote repo %s..." % giturl | ||
| 674 | |||
| 675 | gitcmd = "git ls-remote %s *heads* 2>&1" % (giturl) | ||
| 676 | tmp = os.popen(gitcmd).read() | ||
| 677 | |||
| 678 | branches = [] | ||
| 679 | |||
| 680 | if tmp: | ||
| 681 | tmpline = tmp.split("\n") | ||
| 682 | for line in tmpline: | ||
| 683 | if len(line)==0: | ||
| 684 | break; | ||
| 685 | if not line.endswith("base"): | ||
| 686 | continue; | ||
| 687 | idx = line.find("refs/heads/") | ||
| 688 | kbranch = line[idx + len("refs/heads/"):] | ||
| 689 | if kbranch.find("/") == -1 and kbranch.find("base") == -1: | ||
| 690 | continue | ||
| 691 | idx = kbranch.find("base") | ||
| 692 | branches.append(kbranch[:idx - 1]) | ||
| 693 | |||
| 694 | return branches | ||
| 695 | |||
| 696 | |||
| 697 | def all_branches(context): | ||
| 698 | """ | ||
| 699 | Return a list of all the branches found in the kernel git repo. | ||
| 700 | """ | ||
| 701 | giturl = find_giturl(context) | ||
| 702 | |||
| 703 | print "Getting branches from remote repo %s..." % giturl | ||
| 704 | |||
| 705 | gitcmd = "git ls-remote %s *heads* 2>&1" % (giturl) | ||
| 706 | tmp = os.popen(gitcmd).read() | ||
| 707 | |||
| 708 | branches = [] | ||
| 709 | |||
| 710 | if tmp: | ||
| 711 | tmpline = tmp.split("\n") | ||
| 712 | for line in tmpline: | ||
| 713 | if len(line)==0: | ||
| 714 | break; | ||
| 715 | idx = line.find("refs/heads/") | ||
| 716 | kbranch = line[idx + len("refs/heads/"):] | ||
| 717 | if (kbranch.find("/") != -1 and | ||
| 718 | (kbranch.find("standard") != -1 or kbranch.find("base") != -1) or | ||
| 719 | kbranch == "base"): | ||
| 720 | branches.append(kbranch) | ||
| 721 | continue | ||
| 722 | |||
| 723 | return branches | ||
