SConstruct 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  1. #!/usr/bin/env python3
  2. # coding=utf-8
  3. '''
  4. * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. * Description: SCons build system entry.
  18. '''
  19. EnsureSConsVersion(3, 0, 1)
  20. EnsurePythonVersion(3, 7)
  21. import os
  22. import sys
  23. import datetime
  24. import atexit
  25. from distutils import dir_util
  26. sys.path.insert(0,os.path.join(os.getcwd(), 'build'))
  27. from scripts import common_env
  28. from scripts import scons_utils
  29. from scripts import scons_app
  30. from scripts import scons_env_cfg
  31. from scripts import pkt_builder
  32. from scripts.packet_create import packet_bin
  33. from tools.nvtool.build_nv import make_nv_bin
  34. import shutil
  35. #Init compile parameters
  36. env_cfg = scons_env_cfg.SconsEnvCfg()
  37. #Accept APP parameter
  38. app_name = ARGUMENTS.get('app', 'demo')
  39. factory_mode = ARGUMENTS.get('factory_mode', 'no')
  40. app_builder = scons_app.AppTarget(app_name, factory_mode)
  41. env_cfg.set_app_builder(app_builder)
  42. #Compile message output control
  43. if common_env.log_output_flag == False:
  44. current = datetime.datetime.now()
  45. if not os.path.exists(os.path.dirname(env_cfg.log_path)) or not os.path.exists(env_cfg.log_path):
  46. os.makedirs(env_cfg.log_path)
  47. log_file = os.path.join(env_cfg.log_path,'scons_trace.log')
  48. old_stdout = sys.stdout
  49. file = open(log_file, 'w+')
  50. file.write("Building at %s %s\n" % (current.strftime('%Y/%m/%d'), current.strftime('%H:%M:%S')))
  51. sys.stdout = file
  52. #Init environment
  53. env = Environment(ENV={'PATH':os.environ['PATH']},
  54. TARGET_PREFIX=env_cfg.target_name,)
  55. env_cfg.set_tools(env)
  56. env_cfg.set_environs(env)
  57. print('----------------------------top-----------------')
  58. #libraries to be built
  59. libs = [env.SConscript(os.path.join(env_cfg.get_module_dir(module), 'SConscript'), {'env':env, 'env_cfg':env_cfg, 'module':module},
  60. variant_dir=os.path.join(env_cfg.lib_path, env_cfg.get_module_dir(module)), duplicate=0) for module in env_cfg.get_build_modules()]
  61. #Get settings
  62. env['LIBPATH'] = env_cfg.get_lib_path()
  63. if scons_utils.scons_usr_bool_option('CONFIG_TARGET_CHIP_HI3861') == 'y':
  64. if scons_utils.scons_usr_bool_option('CONFIG_DIAG_SUPPORT') == 'y':
  65. if factory_mode == 'yes':
  66. env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861', 'debug', 'factory'))
  67. elif scons_utils.scons_usr_bool_option('CONFIG_QUICK_SEND_MODE') == 'y':
  68. env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861', 'debug', 'no_mesh_quick_start'))
  69. elif scons_utils.scons_usr_bool_option('CONFIG_MESH_SUPPORT') == 'y':
  70. env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861', 'debug', 'mesh'))
  71. else:
  72. env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861', 'debug', 'no_mesh'))
  73. else:
  74. if factory_mode == 'yes':
  75. env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861', 'release', 'factory'))
  76. elif scons_utils.scons_usr_bool_option('CONFIG_QUICK_SEND_MODE') == 'y':
  77. env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861', 'release', 'no_mesh_quick_start'))
  78. elif scons_utils.scons_usr_bool_option('CONFIG_MESH_SUPPORT') == 'y':
  79. env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861', 'release', 'mesh'))
  80. else:
  81. env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861', 'release', 'no_mesh'))
  82. else:
  83. if scons_utils.scons_usr_bool_option('CONFIG_DIAG_SUPPORT') == 'y':
  84. if factory_mode == 'yes':
  85. env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861l', 'debug', 'factory'))
  86. elif scons_utils.scons_get_cfg_val('CONFIG_CHIP_PKT_48K') == 'y':
  87. env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861l', 'debug', 'no_mesh_pkt_48k'))
  88. elif scons_utils.scons_usr_bool_option('CONFIG_MESH_SUPPORT') == 'y':
  89. env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861l', 'debug', 'mesh'))
  90. else:
  91. env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861l', 'debug', 'no_mesh'))
  92. else:
  93. if factory_mode == 'yes':
  94. env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861l', 'release', 'factory'))
  95. elif scons_utils.scons_get_cfg_val('CONFIG_CHIP_PKT_48K') == 'y':
  96. env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861l', 'release', 'no_mesh_pkt_48k'))
  97. elif scons_utils.scons_usr_bool_option('CONFIG_MESH_SUPPORT') == 'y':
  98. env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861l', 'release', 'mesh'))
  99. else:
  100. env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861l', 'release', 'no_mesh'))
  101. env.Append(LIBPATH=app_builder.get_app_lib_path())
  102. ## wifiiot_app is the only one app for ohos
  103. if app_name != "wifiiot_app":
  104. env['LIBS'] = list(map(lambda x:'-l%s'%x, env_cfg.get_libs()))
  105. else:
  106. env['LIBS'] = list(map(lambda x:'-l%s'%x, env_cfg.get_libs())) + ['--whole-archive'] + list(map(lambda x:'-l%s'%x, env_cfg.get_ohos_libs())) + ['--no-whole-archive']
  107. env.Append(LIBS = app_builder.get_app_libs())
  108. env.Append(LIBS = '-lwifi_flash')
  109. env.Append(LIBS = '-lwifi')
  110. env.Append(LIBS = '-llitekernel_flash')
  111. env.Append(LIBS = '-lsystem')
  112. if scons_utils.scons_usr_bool_option('CONFIG_MESH_SUPPORT') == 'y':
  113. if factory_mode != 'yes':
  114. env.Append(LIBS = '-lmeshautolink')
  115. env['LIBS'] = sorted(env["LIBS"])
  116. env['LIBPATH'] = sorted(env["LIBPATH"])
  117. env['LINKFILE'] = env_cfg.link_file
  118. env['MAPFILE'] = env_cfg.map_file
  119. print('~~~~~~~~~~~~~~~~~~~~~~~~~~~~libpath:',env['LIBPATH'])
  120. print('~~~~~~~~~~~~~~~~~~~~~~~~~~~~libs:',env['LIBS'])
  121. ####################################################### LINK by Command #######################################################
  122. # config by menuconfig
  123. signature = {
  124. 'RSA':{
  125. 0:0x0054d3c0, # factory startup addr:0x1E3000(HILINK_ADDR - 600K) = 0x14D000
  126. 'A':0x0040d3c0,
  127. 'B':0x004f13c0,
  128. },
  129. 'ECC':{
  130. 0:0x0054d3c0, # factory startup addr:0x1E3000(HILINK_ADDR - 600K) = 0x14D000
  131. 'A':0x0040d3c0,
  132. 'B':0x004f13c0,
  133. }
  134. }
  135. link_env = env.Clone()
  136. """Build link script
  137. """
  138. linker_builder = Builder(
  139. action='$CC $LINK_SCRIPTS_FLAG -E $SOURCE -o $TARGET -P',
  140. src_suffix='.ld.S'
  141. )
  142. """Build elf file
  143. """
  144. elf_builder = Builder(
  145. action='$LINK $LINKFLAGS $LIBPATH -T$LINKFILE -Map=$MAPFILE -o $TARGET --start-group $LIBS --end-group',#--verbose
  146. suffix='.out'
  147. )
  148. """Build binary from .out file
  149. """
  150. binary_builder = Builder(
  151. action='$OBJCOPY -O binary $SOURCE $TARGET',
  152. suffix='.bin',
  153. src_suffix='.out'
  154. )
  155. """Build asm file from binary
  156. """
  157. asm_builder = Builder(
  158. action='$OBJDUMP -d $SOURCE >$TARGET',
  159. suffix='.asm',
  160. src_suffix='.out'
  161. )
  162. """Base image builder
  163. """
  164. def baseimg_builder(target, source, env):
  165. base_bin_target = str(target[0])
  166. scons_utils.scons_bin_dd(str(source[0]), base_bin_target, seek=0, count=278)
  167. env_cfg.base_bin_check(base_bin_target)
  168. no_base_bin_target = str(target[1])
  169. scons_utils.scons_bin_dd(str(source[0]), no_base_bin_target, skip=278)
  170. """NV image builder
  171. """
  172. def nvimg_builder(target, source, env):
  173. if os.path.exists(env_cfg.nv_path) is False:
  174. os.makedirs(env_cfg.nv_path)
  175. make_nv_bin(env_cfg.nv_path, env_cfg.target_name, env_cfg.nv_cfg_name) #genrate nv first
  176. """Combine NV image and kernel
  177. """
  178. def nvkernel_builder(target, source, env):
  179. factory_nv = str(source[0])
  180. normal_nv = str(source[1])
  181. no_base_bin_target = str(source[2])
  182. nv_kernel_bin = str(target[0])
  183. scons_utils.scons_bin_dd(factory_nv, nv_kernel_bin, seek=0, bs=4096, count=1)
  184. scons_utils.scons_bin_dd(normal_nv, nv_kernel_bin, seek=2, bs=4096, count=1)
  185. scons_utils.scons_bin_dd(no_base_bin_target, nv_kernel_bin, seek=4, bs=4096)
  186. factory_nv = os.path.join(env_cfg.nv_path, env_cfg.nv_factory_name)
  187. normal_nv = os.path.join(env_cfg.nv_path, env_cfg.nv_normal_name)
  188. #Build flashboot
  189. flash_boot_bin = env.SConscript(os.path.join('boot', 'flashboot', 'SConscript'), {'env':env, 'env_cfg':env_cfg, 'module':'boot'}, duplicate=0)
  190. #Build loaderboot
  191. loader_boot_bin = env.SConscript(os.path.join('boot', 'loaderboot', 'SConscript'), {'env':env, 'env_cfg':env_cfg, 'module':'loaderboot'}, duplicate=0)
  192. #ota object
  193. ota_flag = 1 if scons_utils.scons_usr_bool_option('CONFIG_COMPRESSION_OTA_SUPPORT') != 'y' else 0
  194. ota_build_object = pkt_builder.ImageBuild(env_cfg.target_name, ota_mode=ota_flag)
  195. def init_ota_build_object(ota_build_object):
  196. ota_build_object.set_pkt_path(env_cfg.bin_path)
  197. ota_build_object.set_src_path(boot_bin_path=str(flash_boot_bin[0]), normal_nv_path=normal_nv, factory_nv_path=factory_nv)
  198. ota_build_object.set_chip_product_name(env.get("CHIP_TYPE"))
  199. def get_ota_object():
  200. return ota_build_object
  201. def get_secure_boot():
  202. if (scons_utils.scons_usr_bool_option('CONFIG_TARGET_SIG_SHA256') == 'y'):
  203. return False
  204. else:
  205. return True;
  206. def get_hilink_enable():
  207. if (scons_utils.scons_usr_bool_option('CONFIG_HILINK') == 'y'):
  208. return True
  209. else:
  210. return False;
  211. def get_sign_dict():
  212. sig = ''
  213. if scons_utils.scons_usr_bool_option('CONFIG_TARGET_SIG_RSA_V15') == 'y':
  214. sig = 'RSA'
  215. get_ota_object().set_sign_alg(0x0)
  216. elif scons_utils.scons_usr_bool_option('CONFIG_TARGET_SIG_RSA_PSS') == 'y':
  217. sig = 'RSA'
  218. get_ota_object().set_sign_alg(0x1)
  219. elif scons_utils.scons_usr_bool_option('CONFIG_TARGET_SIG_ECC') == 'y':
  220. sig = 'ECC'
  221. get_ota_object().set_sign_alg(0x10)
  222. elif scons_utils.scons_usr_bool_option('CONFIG_TARGET_SIG_SHA256') == 'y':
  223. sig = 'ECC'
  224. get_ota_object().set_sign_alg(0x3F)
  225. if sig not in signature:
  226. raise scons_utils.SconsBuildError("%s============== <%s> SIGNATURE SETTING NULL =============%s"%(scons_utils.colors['red'], sig, scons_utils.colors['end']))
  227. return signature[sig]
  228. init_ota_build_object(ota_build_object)
  229. sign_dict = get_sign_dict() #signature mode configuration
  230. def ota_builder(target, source, env):
  231. """Build upg binary
  232. """
  233. get_ota_object().set_encrypt_flag(0x42)
  234. if scons_utils.scons_usr_bool_option('CONFIG_FLASH_ENCRYPT_SUPPORT') == 'y':
  235. get_ota_object().set_file_attr_encrypt(0x2)
  236. else:
  237. get_ota_object().set_file_attr_encrypt(0x1)
  238. if scons_utils.scons_usr_bool_option('CONFIG_COMPRESSION_OTA_SUPPORT') == 'y':
  239. get_ota_object().set_kernel_file_attr_ota(0x4)
  240. get_ota_object().set_kernel_max_size(0) #(912+972)KB
  241. else:
  242. get_ota_object().set_kernel_file_attr_ota(env['SIGN'])
  243. get_ota_object().set_kernel_max_size(env['SIGN']) #912 or 972KB
  244. if scons_utils.scons_usr_bool_option('CONFIG_FLASH_ENCRYPT_SUPPORT') == 'y':
  245. get_ota_object().set_encrypt_flag(0xFF)
  246. get_ota_object().set_src_path(kernel_bin_path=str(source[1]))
  247. get_ota_object().BuildUpgBin(str(target[0]))
  248. return 0
  249. def factory_builder(target, source, env):
  250. """Build factory binary
  251. """
  252. get_ota_object().set_encrypt_flag(0x42)
  253. if scons_utils.scons_usr_bool_option('CONFIG_FLASH_ENCRYPT_SUPPORT') == 'y':
  254. get_ota_object().set_file_attr_encrypt(0x2)
  255. else:
  256. get_ota_object().set_file_attr_encrypt(0x1)
  257. get_ota_object().set_kernel_file_attr_ota('A') # same as kernel A.
  258. get_ota_object().set_kernel_max_size(0x4) #0x4 means __factory_bin_max_size:600K
  259. get_ota_object().set_src_path(kernel_bin_path=str(source[1]))
  260. get_ota_object().BuildUpgBurnBin(str(target[0]))
  261. factory_bin_path = os.path.join('build', 'libs', 'factory_bin')
  262. if not os.path.exists(factory_bin_path):
  263. os.makedirs(factory_bin_path)
  264. shutil.rmtree(factory_bin_path)
  265. shutil.copytree(env_cfg.bin_path, factory_bin_path, False) #copy factory bin output to build/libs temply.
  266. return 0
  267. def burn_bin_builder(target, source, env):
  268. """Build binary
  269. """
  270. get_ota_object().set_build_temp_path(build_temp_path = env_cfg.cache_path)
  271. burn_bin = get_ota_object().BuildHiburnBin(str(target[0]), str(source[0]))
  272. loader_bin = str(source[1])
  273. efuse_bin = str(source[2]) if len(source) == 3 else None
  274. boot_b = os.path.join('output', 'bin', '%s_boot_signed_B.bin'%(env.get('CHIP_TYPE')))
  275. boot_b_size = os.path.getsize(boot_b)
  276. factory_bin_path = os.path.join('build', 'libs', 'factory_bin')
  277. factory_bin = os.path.join(factory_bin_path, '%s_factory.bin'%env_cfg.target_name)
  278. burn_for_erase_bin = os.path.join('build', 'basebin', 'burn_for_erase_4k.bin')
  279. #证书安全存储示例
  280. tee_cert1_file = os.path.join('build', 'basebin', 'tee_cert1.bin');
  281. tee_cert2_file = os.path.join('build', 'basebin', 'tee_cert2.bin');
  282. tee_key_file = os.path.join('build', 'basebin', 'tee_key.bin');
  283. tee_cert_key_bin_max = 12*1024; #必须为4KB证书倍,需匹配分区表确定烧写地址和大小
  284. tee_total_file_cnt = 3; #3个文件:2个证书,1个key。
  285. burn_tee_cert = False
  286. if ((os.path.exists(tee_cert1_file)) and (os.path.exists(tee_cert2_file)) and (os.path.exists(tee_key_file))):
  287. burn_tee_cert = True
  288. version_bin = bytearray(8)
  289. boot_ver = get_ota_object().get_flashboot_file_ver()
  290. kernel_ver = get_ota_object().get_kernel_file_ver()
  291. boot_ver_bytes = boot_ver.to_bytes(4, byteorder = 'little', signed = True)
  292. kernel_ver_bytes = kernel_ver.to_bytes(4, byteorder = 'little', signed = True)
  293. version_bin[0:4] = boot_ver_bytes
  294. version_bin[4:8] = kernel_ver_bytes
  295. version_file = os.path.join("output", "bin", '%s_vercfg.bin'%env_cfg.target_name)
  296. with open(version_file, 'wb+') as fp:
  297. fp.write(version_bin)
  298. burn_bin_ease_size = 0x200000;
  299. #根据分区表适配烧写地址和大小
  300. if (get_hilink_enable() == True):
  301. burn_bin_ease_size = 0x200000 - 0x8000 - 0x1000 - 0x2000
  302. if (burn_tee_cert == True):
  303. burn_bin_ease_size = 0x200000 - 0x8000 - 0x1000 - 0x2000 - 0x5000
  304. if os.path.exists(factory_bin):
  305. cmd_list = ['%s|0|0|0'%loader_bin, '%s|0|0|3'%efuse_bin, '%s|0|%d|1'%(burn_bin, burn_bin_ease_size), '%s|%d|%d|6'%(factory_bin, 0x14D000, 0x96000)] if efuse_bin!=None else ['%s|0|0|0'%loader_bin, '%s|0|%d|1'%(burn_bin, burn_bin_ease_size), '%s|%d|%d|6'%(factory_bin, 0x14D000, 0x96000),]
  306. shutil.copytree(factory_bin_path, os.path.join(env_cfg.bin_path, 'factory_bin'))
  307. else:
  308. cmd_list = ['%s|0|0|0'%loader_bin, '%s|0|0|3'%efuse_bin, '%s|0|%d|1'%(burn_bin, burn_bin_ease_size)] if efuse_bin!=None else ['%s|0|0|0'%loader_bin, '%s|0|%d|1'%(burn_bin, burn_bin_ease_size)]
  309. if ((get_hilink_enable() == True) or (burn_tee_cert == True)):
  310. cmd_list.append('%s|%d|%d|1'%(burn_for_erase_bin, 0x200000 - 0x8000 - 0x1000, 0x1000))
  311. #cmd_list.append('%s|%d|%d|1'%(boot_b, 0x200000 - boot_b_size, boot_b_size));
  312. if (burn_tee_cert == True):
  313. cert_key_bin = bytearray(tee_cert_key_bin_max)
  314. tee_cert1_size = os.path.getsize(tee_cert1_file)
  315. tee_cert2_size = os.path.getsize(tee_cert2_file)
  316. tee_key_size = os.path.getsize(tee_key_file)
  317. total_cert_key_size = tee_cert1_size + tee_cert2_size + tee_key_size
  318. if (total_cert_key_size > tee_cert_key_bin_max - 4 - 4 - 4*tee_total_file_cnt):
  319. print ("%s============== cert total len bigger than %d=============%s"%(scons_utils.colors['red'], total_cert_key_size,scons_utils.colors['end']))
  320. return -1
  321. else:
  322. with open(tee_cert1_file, 'rb') as fp:
  323. tee_cert1_bin = fp.read()
  324. with open(tee_cert2_file, 'rb') as fp:
  325. tee_cert2_bin = fp.read()
  326. with open(tee_key_file, 'rb') as fp:
  327. tee_key_bin = fp.read()
  328. #填充头部结构
  329. start_flag = 0xDEADBEEF
  330. start_flag_bytes = start_flag.to_bytes(4, byteorder = 'little', signed = False)
  331. cert_key_bin[0:4] = start_flag_bytes #填充魔术字
  332. tee_total_file_cnt_bytes = tee_total_file_cnt.to_bytes(4, byteorder = 'little', signed = True)
  333. cert_key_bin[4:8] = tee_total_file_cnt_bytes #填充总的文件数
  334. #填充各文件的大小
  335. cert_key_bin[8:12] = tee_cert1_size.to_bytes(4, byteorder = 'little', signed = True)
  336. cert_key_bin[12:16] = tee_cert2_size.to_bytes(4, byteorder = 'little', signed = True)
  337. cert_key_bin[16:20] = tee_key_size.to_bytes(4, byteorder = 'little', signed = True)
  338. #填充各文件
  339. cert_key_bin[20:20 + tee_cert1_size] = tee_cert1_bin
  340. cert_key_bin[20 + tee_cert1_size:20 + tee_cert1_size + tee_cert2_size] = tee_cert2_bin
  341. cert_key_bin[20 + tee_cert1_size + tee_cert2_size:20 + tee_cert1_size + tee_cert2_size + tee_key_size] = tee_key_bin
  342. #写文件
  343. cert_bin_file = os.path.join("output", "bin", '%s_tee_cert_key.bin'%env_cfg.target_name)
  344. with open(cert_bin_file, 'wb+') as fp:
  345. fp.write(cert_key_bin)
  346. cmd_list.append('%s|%d|%d|1'%(cert_bin_file, 0x200000 - 0x8000 - 0x1000 - 0x2000 - 0x5000, tee_cert_key_bin_max))
  347. if (get_secure_boot() == True): #only need write ver file in secure boot mode.
  348. cmd_list.append('%s|0|0|7'%version_file)
  349. packet_bin(str(target[1]), cmd_list)
  350. if os.path.exists(factory_bin_path):
  351. shutil.rmtree(factory_bin_path)
  352. return 0
  353. def compress_ota_builder(target, source, env):
  354. """Build compressed upgrade file
  355. """
  356. get_ota_object().set_encrypt_flag(0x42)
  357. if scons_utils.scons_usr_bool_option('CONFIG_FLASH_ENCRYPT_SUPPORT') == 'y':
  358. get_ota_object().set_file_attr_encrypt(0x2)
  359. get_ota_object().set_encrypt_flag(0xFF)
  360. else:
  361. get_ota_object().set_file_attr_encrypt(0x1)
  362. get_ota_object().set_kernel_file_attr_ota(0x4)
  363. get_ota_object().set_build_temp_path(build_temp_path = env_cfg.cache_path)
  364. compress_ota = get_ota_object().BuildCompressUpgBin(str(target[0]), str(source[0]))
  365. return 0
  366. def boot_ota_builder(target, source, env):
  367. """Build boot ota
  368. """
  369. if scons_utils.scons_usr_bool_option('CONFIG_FLASH_ENCRYPT_SUPPORT') == 'y':
  370. get_ota_object().set_file_attr_encrypt(0x2)
  371. else:
  372. get_ota_object().set_file_attr_encrypt(0x1)
  373. if scons_utils.scons_usr_bool_option('CONFIG_COMPRESSION_OTA_SUPPORT') == 'y':
  374. get_ota_object().set_flashboot_file_attr_ota(0x4)
  375. else:
  376. get_ota_object().set_flashboot_file_attr_ota(0x3)
  377. get_ota_object().set_encrypt_flag(0x42)
  378. boot_ota = get_ota_object().BuildUpgBoot(str(target[0]))
  379. return 0
  380. #Builders
  381. link_env.Append(BUILDERS={'LinkFile':linker_builder,
  382. 'Elf':elf_builder,
  383. 'Binary':binary_builder,
  384. 'Asm':asm_builder,
  385. 'BaseImg':Builder(action=baseimg_builder),
  386. 'NVKernel':Builder(action=nvkernel_builder),
  387. 'BootOta':Builder(action=boot_ota_builder),
  388. 'OtaImg':Builder(action=ota_builder),
  389. 'FactoryImg':Builder(action=factory_builder),
  390. 'BurnImg':Builder(action=burn_bin_builder),
  391. 'CompressOtaImg':Builder(action = compress_ota_builder),
  392. })
  393. def build_all(build_env, link_sys, flash_boot_bin, loader_boot_bin):
  394. """Processing build
  395. """
  396. #kernel_ver
  397. kernel_ver = scons_utils.scons_usr_int_option('CONFIG_TARGET_KERNEL_VER')
  398. if (kernel_ver < 0 or kernel_ver > 48):
  399. raise scons_utils.SconsBuildError("%s============== kernel_ver invalied, should be 0-48 =============%s"%(scons_utils.colors['red'], scons_utils.colors['end']))
  400. else:
  401. get_ota_object().set_kernel_file_ver(kernel_ver)
  402. #boot_ver
  403. boot_ver = scons_utils.scons_usr_int_option('CONFIG_TARGET_BOOT_VER')
  404. if (boot_ver < 0 or boot_ver > 16):
  405. raise scons_utils.SconsBuildError("%s============== boot_ver invalied, should be 0-16 =============%s"%(scons_utils.colors['red'], scons_utils.colors['end']))
  406. else:
  407. get_ota_object().set_flashboot_file_ver(boot_ver)
  408. #images container, insert boot ota at first
  409. imgs = [build_env.BootOta(target=os.path.join(env_cfg.bin_path, '%s_flash_boot_ota.bin'%env_cfg.target_name), source=flash_boot_bin)]
  410. for sig_key in sign_dict:
  411. if sig_key == 0 and factory_mode != 'yes':
  412. continue
  413. sign_build = build_env.Clone()
  414. sign_build['SIGN'] = sig_key
  415. name_suffix = '_%s'%sig_key
  416. if sig_key == 0:
  417. name_suffix = '_factory'
  418. ota_file = os.path.join(env_cfg.bin_path, '%s%s.bin'%(env_cfg.target_name, name_suffix))
  419. elif scons_utils.scons_usr_bool_option('CONFIG_COMPRESSION_OTA_SUPPORT') == 'y':
  420. name_suffix = ''
  421. ota_file = os.path.join(env_cfg.cache_path, '%s_ota_%s.bin'%(env_cfg.target_name, 'temp')) #tmp file
  422. else:
  423. ota_file = os.path.join(env_cfg.bin_path, '%s_ota%s.bin'%(env_cfg.target_name, name_suffix))
  424. sign_build['LINKFILE'] = os.path.join(env_cfg.link_path, 'link%s.lds'%name_suffix)
  425. sign_build['MAPFILE'] = '%s%s.map'%(sign_build['MAPFILE'][:-len('.map')], name_suffix)
  426. sign_build.Append(LINK_SCRIPTS_FLAG = '-DFLASH_FIRM_START=%s'%sign_dict[sig_key])
  427. link_risc = sign_build.LinkFile(source=os.path.join('build', 'link', 'link'),
  428. target='$LINKFILE')
  429. sign_build.Depends(link_risc, link_sys)
  430. #start
  431. target_out = sign_build.Elf(source = libs, target = os.path.join(env_cfg.bin_path, '%s%s.out'%(env_cfg.target_name, name_suffix)))
  432. sign_build.Depends(target_out, [link_risc, libs])
  433. target_out_bin = sign_build.Binary(source = target_out, target = os.path.join(env_cfg.cache_path, '%s%s'%(env_cfg.target_name, name_suffix)))
  434. target_asm = sign_build.Asm(source = target_out, target=os.path.join(env_cfg.bin_path, '%s%s.asm'%(env_cfg.target_name, name_suffix)))
  435. base_bin_target = os.path.join(env_cfg.cache_path, '%s_base%s.bin'%(env_cfg.target_name, name_suffix))
  436. kernel_bin_target = os.path.join(env_cfg.cache_path, '%s_kernel%s.bin'%(env_cfg.target_name, name_suffix))
  437. #Build kernel and ota
  438. kernel = sign_build.BaseImg(source=target_out_bin, target=[base_bin_target, kernel_bin_target])
  439. if factory_mode == 'yes':
  440. ota_bin = sign_build.FactoryImg(source=kernel, target=ota_file)
  441. else:
  442. ota_bin = sign_build.OtaImg(source=kernel, target=ota_file)
  443. imgs.append(ota_bin)
  444. sign_build.AddPostAction(kernel, scons_utils.cleanup) #hook clean
  445. if sig_key == 'A': #need signature
  446. loader_bin = os.path.join('#', env_cfg.bin_path, '%s_loader_signed.bin'%(env.get('CHIP_TYPE')))
  447. efuse_bin = os.path.join('build', 'basebin', 'efuse_cfg.bin')
  448. burn_bin = os.path.join(env_cfg.bin_path, '%s_burn.bin'%env_cfg.target_name)
  449. allinone_bin = os.path.join(env_cfg.bin_path, '%s_allinone.bin'%env_cfg.target_name)
  450. burn_bins = sign_build.BurnImg(source=[ota_bin, loader_bin, efuse_bin] if os.path.exists(efuse_bin) else [ota_bin, loader_bin],
  451. target=[burn_bin, allinone_bin])
  452. imgs.append(burn_bins)
  453. #mark binaries to be built everytime
  454. if sig_key in ['A', 'B']:
  455. sign_build.AlwaysBuild([link_risc, target_out, target_out_bin, target_asm, kernel, ota_bin, burn_bins])
  456. if scons_utils.scons_usr_bool_option('CONFIG_COMPRESSION_OTA_SUPPORT') == 'y' and sig_key == 'A':
  457. compress_ota_bin = os.path.join(env_cfg.bin_path, '%s_ota.bin'%env_cfg.target_name)
  458. compress_ota_file = sign_build.CompressOtaImg(source = ota_bin, target = compress_ota_bin)
  459. break
  460. if sig_key == 0:
  461. break
  462. return imgs
  463. link_env.AddMethod(build_all, 'BUILD')
  464. #prepare link script
  465. link_sys = link_env.LinkFile(source=os.path.join('build', 'link', 'system_config'),
  466. target=os.path.join(env_cfg.link_path, 'system_config.ld'))
  467. link_env.Depends(link_sys, [flash_boot_bin, loader_boot_bin])
  468. link_env.AddPostAction(link_sys, nvimg_builder) #prepare nv image
  469. # START LINK
  470. target_img = link_env.BUILD(link_sys, flash_boot_bin, loader_boot_bin)
  471. link_env.AlwaysBuild([target_img, link_sys])
  472. Clean(target_img, env_cfg.clean_list)
  473. ####################################################### LINK #######################################################
  474. ####################################################### BUILD CHECK #######################################################
  475. def build_status():
  476. bf = GetBuildFailures()
  477. status = 0
  478. failures_message = ''
  479. if bf:
  480. status = -1
  481. failures_message = "\n".join(["Failed building %s" % scons_utils.bf_to_str(x) for x in bf if x is not None])
  482. return (status, failures_message)
  483. def display_build_status():
  484. if env.GetOption("clean"):
  485. return
  486. status, failures_message = build_status()
  487. if status == 0:
  488. scons_utils.show_burn_tips()
  489. else:
  490. scons_utils.show_alert("BUILD FAILED!!!!")
  491. scons_utils.show_alert(failures_message)
  492. atexit.register(display_build_status)
  493. if common_env.log_output_flag == False:
  494. file.close() #close log file handler
  495. sys.stdout = old_stdout