ksum.py 4.6 KB

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