ksum.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #!/usr/bin/env python
  2. # ex:ts=4:sw=4:sts=4:et
  3. # -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
  4. #
  5. # Copyright (c) 2016, Intel Corporation.
  6. # All rights reserved.
  7. #
  8. # This program is free software; you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License version 2 as
  10. # published by the Free Software Foundation.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License along
  18. # with this program; if not, write to the Free Software Foundation, Inc.,
  19. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20. #
  21. # DESCRIPTION 'ksum.py' generates a combined summary of vmlinux and
  22. # module sizes for a built kernel, as a quick tool for comparing the
  23. # overall effects of systemic tinification changes. Execute from the
  24. # base directory of the kernel build you want to summarize. Setting
  25. # the 'verbose' flag will display the sizes for each file included in
  26. # the summary.
  27. #
  28. # AUTHORS
  29. # Tom Zanussi <tom.zanussi (at] linux.intel.com>
  30. #
  31. __version__ = "0.1.0"
  32. # Python Standard Library modules
  33. import os
  34. import sys
  35. import getopt
  36. from subprocess import *
  37. def usage():
  38. prog = os.path.basename(sys.argv[0])
  39. print('Usage: %s [OPTION]...' % prog)
  40. print(' -v, display sizes for each file')
  41. print(' -h, --help display this help and exit')
  42. print('')
  43. print('Run %s from the top-level Linux kernel build directory.' % prog)
  44. verbose = False
  45. n_ko_files = 0
  46. ko_file_list = []
  47. ko_text = 0
  48. ko_data = 0
  49. ko_bss = 0
  50. ko_total = 0
  51. vmlinux_file = ""
  52. vmlinux_level = 0
  53. vmlinux_text = 0
  54. vmlinux_data = 0
  55. vmlinux_bss = 0
  56. vmlinux_total = 0
  57. def is_vmlinux_file(filename):
  58. global vmlinux_level
  59. if filename == ("vmlinux") and vmlinux_level == 0:
  60. vmlinux_level += 1
  61. return True
  62. return False
  63. def is_ko_file(filename):
  64. if filename.endswith(".ko"):
  65. return True
  66. return False
  67. def collect_object_files():
  68. print "Collecting object files recursively from %s..." % os.getcwd()
  69. for dirpath, dirs, files in os.walk(os.getcwd()):
  70. for filename in files:
  71. if is_ko_file(filename):
  72. ko_file_list.append(os.path.join(dirpath, filename))
  73. elif is_vmlinux_file(filename):
  74. global vmlinux_file
  75. vmlinux_file = os.path.join(dirpath, filename)
  76. print "Collecting object files [DONE]"
  77. def add_ko_file(filename):
  78. p = Popen("size -t " + filename, shell=True, stdout=PIPE, stderr=PIPE)
  79. output = p.communicate()[0].splitlines()
  80. if len(output) > 2:
  81. sizes = output[-1].split()[0:4]
  82. if verbose:
  83. print " %10d %10d %10d %10d\t" % \
  84. (int(sizes[0]), int(sizes[1]), int(sizes[2]), int(sizes[3])),
  85. print "%s" % filename[len(os.getcwd()) + 1:]
  86. global n_ko_files, ko_text, ko_data, ko_bss, ko_total
  87. ko_text += int(sizes[0])
  88. ko_data += int(sizes[1])
  89. ko_bss += int(sizes[2])
  90. ko_total += int(sizes[3])
  91. n_ko_files += 1
  92. def get_vmlinux_totals():
  93. p = Popen("size -t " + vmlinux_file, shell=True, stdout=PIPE, stderr=PIPE)
  94. output = p.communicate()[0].splitlines()
  95. if len(output) > 2:
  96. sizes = output[-1].split()[0:4]
  97. if verbose:
  98. print " %10d %10d %10d %10d\t" % \
  99. (int(sizes[0]), int(sizes[1]), int(sizes[2]), int(sizes[3])),
  100. print "%s" % vmlinux_file[len(os.getcwd()) + 1:]
  101. global vmlinux_text, vmlinux_data, vmlinux_bss, vmlinux_total
  102. vmlinux_text += int(sizes[0])
  103. vmlinux_data += int(sizes[1])
  104. vmlinux_bss += int(sizes[2])
  105. vmlinux_total += int(sizes[3])
  106. def sum_ko_files():
  107. for ko_file in ko_file_list:
  108. add_ko_file(ko_file)
  109. def main():
  110. try:
  111. opts, args = getopt.getopt(sys.argv[1:], "vh", ["help"])
  112. except getopt.GetoptError as err:
  113. print('%s' % str(err))
  114. usage()
  115. sys.exit(2)
  116. for o, a in opts:
  117. if o == '-v':
  118. global verbose
  119. verbose = True
  120. elif o in ('-h', '--help'):
  121. usage()
  122. sys.exit(0)
  123. else:
  124. assert False, "unhandled option"
  125. collect_object_files()
  126. sum_ko_files()
  127. get_vmlinux_totals()
  128. print "\nTotals:"
  129. print "\nvmlinux:"
  130. print " text\tdata\t\tbss\t\ttotal"
  131. print " %-10d\t%-10d\t%-10d\t%-10d" % \
  132. (vmlinux_text, vmlinux_data, vmlinux_bss, vmlinux_total)
  133. print "\nmodules (%d):" % n_ko_files
  134. print " text\tdata\t\tbss\t\ttotal"
  135. print " %-10d\t%-10d\t%-10d\t%-10d" % \
  136. (ko_text, ko_data, ko_bss, ko_total)
  137. print "\nvmlinux + modules:"
  138. print " text\tdata\t\tbss\t\ttotal"
  139. print " %-10d\t%-10d\t%-10d\t%-10d" % \
  140. (vmlinux_text + ko_text, vmlinux_data + ko_data, \
  141. vmlinux_bss + ko_bss, vmlinux_total + ko_total)
  142. if __name__ == "__main__":
  143. try:
  144. ret = main()
  145. except Exception:
  146. ret = 1
  147. import traceback
  148. traceback.print_exc(5)
  149. sys.exit(ret)