xref: /OK3568_Linux_fs/yocto/poky/scripts/tiny/ksum.py (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#!/usr/bin/env python3
2*4882a593Smuzhiyun#
3*4882a593Smuzhiyun# Copyright (c) 2016, Intel Corporation.
4*4882a593Smuzhiyun#
5*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0-only
6*4882a593Smuzhiyun#
7*4882a593Smuzhiyun# DESCRIPTION 'ksum.py' generates a combined summary of vmlinux and
8*4882a593Smuzhiyun# module sizes for a built kernel, as a quick tool for comparing the
9*4882a593Smuzhiyun# overall effects of systemic tinification changes.  Execute from the
10*4882a593Smuzhiyun# base directory of the kernel build you want to summarize.  Setting
11*4882a593Smuzhiyun# the 'verbose' flag will display the sizes for each file included in
12*4882a593Smuzhiyun# the summary.
13*4882a593Smuzhiyun#
14*4882a593Smuzhiyun# AUTHORS
15*4882a593Smuzhiyun# Tom Zanussi <tom.zanussi (at] linux.intel.com>
16*4882a593Smuzhiyun#
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun__version__ = "0.1.0"
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun# Python Standard Library modules
21*4882a593Smuzhiyunimport os
22*4882a593Smuzhiyunimport sys
23*4882a593Smuzhiyunimport getopt
24*4882a593Smuzhiyunfrom subprocess import *
25*4882a593Smuzhiyun
26*4882a593Smuzhiyundef usage():
27*4882a593Smuzhiyun    prog = os.path.basename(sys.argv[0])
28*4882a593Smuzhiyun    print('Usage: %s [OPTION]...' % prog)
29*4882a593Smuzhiyun    print('  -v,                 display sizes for each file')
30*4882a593Smuzhiyun    print('  -h, --help          display this help and exit')
31*4882a593Smuzhiyun    print('')
32*4882a593Smuzhiyun    print('Run %s from the top-level Linux kernel build directory.' % prog)
33*4882a593Smuzhiyun
34*4882a593Smuzhiyunverbose = False
35*4882a593Smuzhiyun
36*4882a593Smuzhiyunn_ko_files = 0
37*4882a593Smuzhiyunko_file_list = []
38*4882a593Smuzhiyun
39*4882a593Smuzhiyunko_text = 0
40*4882a593Smuzhiyunko_data = 0
41*4882a593Smuzhiyunko_bss = 0
42*4882a593Smuzhiyunko_total = 0
43*4882a593Smuzhiyun
44*4882a593Smuzhiyunvmlinux_file = ""
45*4882a593Smuzhiyunvmlinux_level = 0
46*4882a593Smuzhiyun
47*4882a593Smuzhiyunvmlinux_text = 0
48*4882a593Smuzhiyunvmlinux_data = 0
49*4882a593Smuzhiyunvmlinux_bss = 0
50*4882a593Smuzhiyunvmlinux_total = 0
51*4882a593Smuzhiyun
52*4882a593Smuzhiyundef is_vmlinux_file(filename):
53*4882a593Smuzhiyun    global vmlinux_level
54*4882a593Smuzhiyun    if filename == ("vmlinux") and vmlinux_level == 0:
55*4882a593Smuzhiyun        vmlinux_level += 1
56*4882a593Smuzhiyun        return True
57*4882a593Smuzhiyun    return False
58*4882a593Smuzhiyun
59*4882a593Smuzhiyundef is_ko_file(filename):
60*4882a593Smuzhiyun    if filename.endswith(".ko"):
61*4882a593Smuzhiyun        return True
62*4882a593Smuzhiyun    return False
63*4882a593Smuzhiyun
64*4882a593Smuzhiyundef collect_object_files():
65*4882a593Smuzhiyun    print("Collecting object files recursively from %s..." % os.getcwd())
66*4882a593Smuzhiyun    for dirpath, dirs, files in os.walk(os.getcwd()):
67*4882a593Smuzhiyun        for filename in files:
68*4882a593Smuzhiyun            if is_ko_file(filename):
69*4882a593Smuzhiyun                ko_file_list.append(os.path.join(dirpath, filename))
70*4882a593Smuzhiyun            elif is_vmlinux_file(filename):
71*4882a593Smuzhiyun                global vmlinux_file
72*4882a593Smuzhiyun                vmlinux_file = os.path.join(dirpath, filename)
73*4882a593Smuzhiyun    print("Collecting object files [DONE]")
74*4882a593Smuzhiyun
75*4882a593Smuzhiyundef add_ko_file(filename):
76*4882a593Smuzhiyun        p = Popen("size -t " + filename, shell=True, stdout=PIPE, stderr=PIPE)
77*4882a593Smuzhiyun        output = p.communicate()[0].splitlines()
78*4882a593Smuzhiyun        if len(output) > 2:
79*4882a593Smuzhiyun            sizes = output[-1].split()[0:4]
80*4882a593Smuzhiyun            if verbose:
81*4882a593Smuzhiyun                print("     %10d %10d %10d %10d\t" % \
82*4882a593Smuzhiyun                    (int(sizes[0]), int(sizes[1]), int(sizes[2]), int(sizes[3])), end=' ')
83*4882a593Smuzhiyun                print("%s" % filename[len(os.getcwd()) + 1:])
84*4882a593Smuzhiyun            global n_ko_files, ko_text, ko_data, ko_bss, ko_total
85*4882a593Smuzhiyun            ko_text += int(sizes[0])
86*4882a593Smuzhiyun            ko_data += int(sizes[1])
87*4882a593Smuzhiyun            ko_bss += int(sizes[2])
88*4882a593Smuzhiyun            ko_total += int(sizes[3])
89*4882a593Smuzhiyun            n_ko_files += 1
90*4882a593Smuzhiyun
91*4882a593Smuzhiyundef get_vmlinux_totals():
92*4882a593Smuzhiyun        p = Popen("size -t " + vmlinux_file, shell=True, stdout=PIPE, stderr=PIPE)
93*4882a593Smuzhiyun        output = p.communicate()[0].splitlines()
94*4882a593Smuzhiyun        if len(output) > 2:
95*4882a593Smuzhiyun            sizes = output[-1].split()[0:4]
96*4882a593Smuzhiyun            if verbose:
97*4882a593Smuzhiyun                print("     %10d %10d %10d %10d\t" % \
98*4882a593Smuzhiyun                    (int(sizes[0]), int(sizes[1]), int(sizes[2]), int(sizes[3])), end=' ')
99*4882a593Smuzhiyun                print("%s" % vmlinux_file[len(os.getcwd()) + 1:])
100*4882a593Smuzhiyun            global vmlinux_text, vmlinux_data, vmlinux_bss, vmlinux_total
101*4882a593Smuzhiyun            vmlinux_text += int(sizes[0])
102*4882a593Smuzhiyun            vmlinux_data += int(sizes[1])
103*4882a593Smuzhiyun            vmlinux_bss += int(sizes[2])
104*4882a593Smuzhiyun            vmlinux_total += int(sizes[3])
105*4882a593Smuzhiyun
106*4882a593Smuzhiyundef sum_ko_files():
107*4882a593Smuzhiyun    for ko_file in ko_file_list:
108*4882a593Smuzhiyun        add_ko_file(ko_file)
109*4882a593Smuzhiyun
110*4882a593Smuzhiyundef main():
111*4882a593Smuzhiyun    try:
112*4882a593Smuzhiyun        opts, args = getopt.getopt(sys.argv[1:], "vh", ["help"])
113*4882a593Smuzhiyun    except getopt.GetoptError as err:
114*4882a593Smuzhiyun        print('%s' % str(err))
115*4882a593Smuzhiyun        usage()
116*4882a593Smuzhiyun        sys.exit(2)
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun    for o, a in opts:
119*4882a593Smuzhiyun        if o == '-v':
120*4882a593Smuzhiyun            global verbose
121*4882a593Smuzhiyun            verbose = True
122*4882a593Smuzhiyun        elif o in ('-h', '--help'):
123*4882a593Smuzhiyun            usage()
124*4882a593Smuzhiyun            sys.exit(0)
125*4882a593Smuzhiyun        else:
126*4882a593Smuzhiyun            assert False, "unhandled option"
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun    collect_object_files()
129*4882a593Smuzhiyun    sum_ko_files()
130*4882a593Smuzhiyun    get_vmlinux_totals()
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun    print("\nTotals:")
133*4882a593Smuzhiyun    print("\nvmlinux:")
134*4882a593Smuzhiyun    print("    text\tdata\t\tbss\t\ttotal")
135*4882a593Smuzhiyun    print("    %-10d\t%-10d\t%-10d\t%-10d" % \
136*4882a593Smuzhiyun        (vmlinux_text, vmlinux_data, vmlinux_bss, vmlinux_total))
137*4882a593Smuzhiyun    print("\nmodules (%d):" % n_ko_files)
138*4882a593Smuzhiyun    print("    text\tdata\t\tbss\t\ttotal")
139*4882a593Smuzhiyun    print("    %-10d\t%-10d\t%-10d\t%-10d" % \
140*4882a593Smuzhiyun        (ko_text, ko_data, ko_bss, ko_total))
141*4882a593Smuzhiyun    print("\nvmlinux + modules:")
142*4882a593Smuzhiyun    print("    text\tdata\t\tbss\t\ttotal")
143*4882a593Smuzhiyun    print("    %-10d\t%-10d\t%-10d\t%-10d" % \
144*4882a593Smuzhiyun        (vmlinux_text + ko_text, vmlinux_data + ko_data, \
145*4882a593Smuzhiyun         vmlinux_bss + ko_bss, vmlinux_total + ko_total))
146*4882a593Smuzhiyun
147*4882a593Smuzhiyunif __name__ == "__main__":
148*4882a593Smuzhiyun    try:
149*4882a593Smuzhiyun        ret = main()
150*4882a593Smuzhiyun    except Exception:
151*4882a593Smuzhiyun        ret = 1
152*4882a593Smuzhiyun        import traceback
153*4882a593Smuzhiyun        traceback.print_exc(5)
154*4882a593Smuzhiyun    sys.exit(ret)
155