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 | |
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>
-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 | ||