01.今天刚刚拿到A31的源代码,拿到手之后首先研究下怎么编译,之前么有接触过全志的芯片, 02.所以要先看看这个编译系统,都是出自android源代码的编译系统,这个编译过程都是差不多的,但是每个厂商都有所改动。 03.首先看看这个全志源代码的目录 04.有两个文件一个是android的压缩文件,另一个是lichee压缩文件(从目录文件可以看出android应该是文件系统的东西,lichee应该是uboot和kernel) 05.先解压lichee文件tar -xvf lichee.tar.gz 06.解压出来之后出现一个文件夹进去 07.cd lichee 08.文件结构 09. 10. 11.先不关心这些里面的文件到底都有些什么,现在只要关心是怎么编译这些文件的 12.按照官方给出的文档里面有关于编译lichee的,就是执行这个build.sh脚本文件 13.来看看这个build.sh有些什么内容 14.#!/bin/bash 15.set -e 16.buildroot/scripts/common.sh $@ 17.这个脚本很简单只有两句话,一个是set -e(就是说在这个set -e后面的所有代码,只要出现了返回值非零,整个脚本就会立即退出) 18.
后面一句就是包含另一个文件夹的脚本common.sh,$@后面再说,再跑到common.sh里面
19.
今天刚刚拿到A31的源代码,拿到手之后首先研究下怎么编译,之前么有接触过全志的芯片,所以要先看看这个编译系统,都是出自android源代码的编译系统,这个编译过程都是差不多的,但是每个厂商都有所改动。首先看看这个全志源代码的目录有两个文件一个是android的压缩文件,另一个是lichee压缩文件(从目录文件可以看出android应该是文件系统的东西,lichee应该是uboot和kernel)先解压lichee文件tar -xvf lichee.tar.gz解压出来之后出现一个文件夹进去cd lichee文件结构先不关心这些里面的文件到底都有些什么,现在只要关心是怎么编译这些文件的按照官方给出的文档里面有关于编译lichee的,就是执行这个build.sh脚本文件来看看这个build.sh有些什么内容#!/bin/bashset -ebuildroot/scripts/common.sh $@这个脚本很简单只有两句话,一个是set -e(就是说在这个set -e后面的所有代码,只要出现了返回值非零,整个脚本就会立即退出)后面一句就是包含另一个文件夹的脚本common.sh,$@后面再说,再跑到common.sh里面[plain] view plaincopyprint?01. [plain] view plaincopyprint?01.#!/bin/bash 02.set -e 03. 04.PLATFORM="" 05.MODULE="" 06.CUR_DIR=$PWD 07.OUT_DIR=$CUR_DIR/out 08.KERN_VER=3.3 09.KERN_DIR=$CUR_DIR/linux-${KERN_VER} 10.KERN_OUT_DIR=$KERN_DIR/output 11.BR_DIR=$CUR_DIR/buildroot 12.BR_OUT_DIR=$BR_DIR/output 13.U_BOOT_DIR=$CUR_DIR/u-boot 14.KERN_VER_RELEASE=3.3.0 15.//这里定义了些变量 16. 17. 18.//帮助文件,就是在lichee文件下面执行./build.sh -h的时候会出现的提示内容 19.-h显示帮助信息 20.-p选择你所需要开发的平台 21.-k内核 22.-m所在的模块(比如kernel,uboot之类的)后面的脚本内容会用到这个参数 23.再下面就是几个例子 24.show_help() 25.{ 26.printf " 27.NAME 28. build - The top level build script for Lichee Linux BSP 29. 30.SYNOPSIS 31. build [-h] | [-p platform] [-k kern_version] [-m module] | pack 32. 33.OPTIONS 34. -h Display help message 35. -p [platform] platform, e.g. sun6i, sun6i_dragonboard, sun6i_fiber sun6i_fiber_a31s 36. sun6i: full linux bsp 37. sun6i_dragonboard: board test packages 38. sun6i_fiber: android kernel 39. sun6i_fiber_a31s: android kernel for a31s platform 40. sun6i_fiber_a31s512m: android kernel for a31s platform(512M DDR) 41. 42. -k [kern_ver] 3.3(default) [OPTIONAL] 43. 44. -m [module] Use this option when you dont want to build all. [OPTIONAL] 45. e.g. kernel, buildroot, uboot, all(default)... 46. pack To start pack program 47. 48.Examples: 49. ./build.sh -p sun6i 50. ./build.sh -p sun6i_dragonboard 51. ./build.sh -p sun6i_fiber 52. ./build.sh -p sun6i_fiber_a31s 53. ./build.sh -p sun6i_fiber_a31s512m 54. ./build.sh pack 55. 56." 57. 58.} 59. 60.下面的脚本内容都是些函数(这里就不说了,等用到的时候自己去看看) 61.现在来看看最后的部分 62. 63.//这个$1就是执行./build.sh 后面所带的参数,比如在lichee下面有一个READEME文件 64.Examples: 65.1.Build linux-3.3 image for EVB 66. $cd lichee 67. $./build.sh -p sun6i 68. $./build.sh pack 69. 70.2.Build linux kernel android 71. $./build.sh -p sun6i_fiber 72. 73.3.Build linux test package 74. $./build.sh -p sun6i_dragonboard 75. 76. 77.//这里的$1就是上面实例中./build.sh 所带的参数 78.//如果$1 == pack 79.if [ "$1" = "pack" ]; then 80. echo "generate rootfs now, it will takes several minutes and log in out/" 81. if [ ! -d "${OUT_DIR}" ]; then 82. mkdir -pv ${OUT_DIR} 83. fi 84. regen_rootfs > out/gen_rootfs_log.txt 2>&1 85. gen_output_sun6i >> out/gen_rootfs_log.txt 2>&1 86. echo "generate rootfs has finished!" 87. ${BR_DIR}/scripts/build_pack.sh 88. exit 0 89.//如果$1 == pack_dragonboard 90.elif [ "$1" = "pack_dragonboard" ]; then 91. regen_dragonboard_rootfs 92. gen_output_sun6i_dragonboard 93. ${BR_DIR}/scripts/build_pack.sh 94. exit 0 95.//如果$1 == pack_prvt 96.elif [ "$1" = "pack_prvt" ]; then 97. ${BR_DIR}/scripts/build_prvt.sh 98. exit 0 99.fi 100. 101.//怎么知道这个OPTION是什么意思呢,你可以在lichee下面执行./build.sh -h可以看到一个OPTION的参数 102.//也可以找到common.sh里面有一个show_help()的方法 103.//以./build.sh -p sun6i_fiber这个为例子 104.//所以可以知道 PLATFORM == sun6i_fiber 105. 106.while getopts hp:m:k: OPTION 107.do 108. case $OPTION in 109. h) show_help 110. exit 0 111. ;; 112. p) PLATFORM=$OPTARG 113. ;; 114. m) MODULE=$OPTARG 115. ;; 116. k) KERN_VER=$OPTARG 117. update_kdir $KERN_VER 118. ;; 119. *) show_help 120. exit 1 121. ;; 122.esac 123.done 124. 125.// 执行上面之后这个PLATFORM就不为空了 126.//在这里也说下这个shell的判断语言的参数是什么意思 127. 128.-e filename 如果 filename存在,则为真 129.-d filename 如果 filename为目录,则为真 130.-f filename 如果 filename为常规文件,则为真 131.-L filename 如果 filename为符号链接,则为真 132.-r filename 如果 filename可读,则为真 133.-w filename 如果 filename可写,则为真 134.-x filename 如果 filename可执行,则为真 135.-s filename 如果文件长度不为0,则为真 136.-h filename 如果文件是软链接,则为真 137.filename1 -nt filename2 如果 filename1比 filename2新,则为真。 138.filename1 -ot filename2 如果 filename1比 filename2旧,则为真。 139.-eq 等于 140.-ne 不等于 141.-gt 大于 142.-ge 大于等于 143.-lt 小于 144.-le 小于等于 145.至于!号那就是取非 146. 147.if [ -z "$PLATFORM" ]; then 148. show_help 149. exit 1 150.fi 151. 152. 153.if [ -z "$PLATFORM" ]; then 154. show_help 155. exit 1 156.fi 157. 158. 159.//如果MODULE等于buildroot,就是跑到相关目录执行脚本,后面的都是差不多的 160.if [ "$MODULE" = buildroot ]; then 161. cd ${BR_DIR} && ./build.sh -p ${PLATFORM} 162.elif [ "$MODULE" = kernel ]; then 163. export PATH=${BR_OUT_DIR}/external-toolchain/bin:$PATH 164. cd ${KERN_DIR} && ./build.sh -p ${PLATFORM} 165.elif [ "$MODULE" = "uboot" ]; then 166. case ${PLATFORM} in 167. a12_nuclear*) 168. echo "build uboot for sun5i_a12" 169. cd ${U_BOOT_DIR} && ./build.sh -p sun5i_a12 170. ;; 171. a12*) 172. echo "build uboot for sun5i_a12" 173. cd ${U_BOOT_DIR} && ./build.sh -p sun5i_a12 174. ;; 175. a13_nuclear*) 176. echo "build uboot for sun5i_a12" 177. cd ${U_BOOT_DIR} && ./build.sh -p sun5i_a13 178. ;; 179. a13*) 180. echo "build uboot for sun5i_a13" 181. cd ${U_BOOT_DIR} && ./build.sh -p sun5i_a13 182. ;; 183. *) 184. echo "build uboot for ${PLATFORM}" 185. cd ${U_BOOT_DIR} && ./build.sh -p ${PLATFORM} 186. ;; 187. esac 188.else 189.//如果MODULE不等于以上的就执行这里 190. //进入buildroot目录,这个BR_DIR在common.sh最开始的地方有定义,执行脚本. 191. cd ${BR_DIR} && ./build.sh -p ${PLATFORM} 192. 193. 194.//来看看这个buildroot目录下面的脚本build.sh 195.#!/bin/bash 196.set -e 197. 198.PLATFORM="" 199.MODULE="" 200.//显示帮助 201.show_help() 202.{ 203. printf "\nbuild.sh - Top level build scritps\n" 204. echo "Valid Options:" 205. echo " -h Show help message" 206. echo " -p platform:sun6i sun6i_fiber sun6i_fiber_a31s sun6i_fiber_a31s512m or sun6i_dragonboard" 207. printf " -m module\n\n" 208.} 209. 210. 211.//获得到platform,module的值 212.while getopts hp:m: OPTION 213.do 214. case $OPTION in 215. h) show_help 216. ;; 217. p) PLATFORM=$OPTARG 218. ;; 219. m) MODULE=$OPTARG 220. ;; 221. *) show_help 222. ;; 223.esac 224.done 225. 226.//如果platform等于空,则显示帮助并退出 227.if [ -z "$PLATFORM" ]; then 228. show_help 229. exit 1 230.fi 231. 232.//如果module等于空,则MODULE==all 233.if [ -z "$MODULE" ]; then 234. MODULE="all" 235.fi 236. 237.//判断目录下面的文件是否为可执行文件 238.if [ -x ./scripts/build_${PLATFORM}.sh ]; then 239. 执行相关脚本(这个脚本的功能就是解压工具链以及设置环境变量) 240. ./scripts/build_${PLATFORM}.sh $MODULE 241. 242.//如果没有可执行文件就显示错误信息,并显示帮助退出 243.else 244. printf "\nERROR: Invalid Platform\nonly sun6i sun6i_fiber sun6i_fiber_a31s sun6i_fiber_a31s512m or sun6i_dragonboard support\n" 245. show_help 246. exit 1 247.fi 248. 249. 250.再回到common.sh这个脚本继续往下看 251. //设置环境变量 252. export PATH=${BR_OUT_DIR}/external-toolchain/bin:$PATH 253. //执行该脚本编译内核(根据你选择相关平台来执行相关脚本如果build_sun6i_fiber.sh ) 254. cd ${KERN_DIR} && ./build.sh -p ${PLATFORM} 255. 256.进入lichee/linux-3.3/scripts/build_sun6i_fiber.sh 257.1。设置编译工具链环境变量 258.2. 259. LICHEE_ROOT=`(cd ${LICHEE_KDIR}/..; pwd)` 260. export PATH=${LICHEE_ROOT}/buildroot/output/external-toolchain/bin:${LICHEE_ROOT}/tools/pack/pctools/linux/android:$PATH 261. 262. //这个$1就是lichee/linux-3.3/build.sh所执行的./scripts/build_${PLATFORM}.sh $MODULE 263. //MODULE值== all,所以执行all分支下面的函数build_kernel,build_modules,build_ramfs 264. case "$1" in 265. kernel) 266. build_kernel 267. ;; 268. modules) 269. build_modules 270. ;; 271. clean) 272. clean_kernel 273. clean_modules 274. ;; 275. all) 276. build_kernel 277. build_modules 278. build_ramfs 279. ;; 280. *) 281. show_help 282. ;; 283. esac 284. 285.kernel编译完成之后就是编译uboot了 286. //编译uboot 287. case ${PLATFORM} in 288. a12_nuclear*) 289. echo "build uboot for sun5i_a12" 290. cd ${U_BOOT_DIR} && ./build.sh -p sun5i_a12 291. ;; 292. a12*) 293. echo "build uboot for sun5i_a12" 294. cd ${U_BOOT_DIR} && ./build.sh -p sun5i_a12 295. ;; 296. a13_nuclear*) 297. echo "build uboot for sun5i_a12" 298. cd ${U_BOOT_DIR} && ./build.sh -p sun5i_a13 299. ;; 300. a13*) 301. echo "build uboot for sun5i_a13" 302. cd ${U_BOOT_DIR} && ./build.sh -p sun5i_a13 303. ;; 304. sun6i) 305. echo "build uboot for sun6i" 306. cd ${U_BOOT_DIR} && ./build.sh -p sun6i 307. ;; 308. sun6i_fiber) 309. echo "build uboot for sun6i_fiber" 310. cd ${U_BOOT_DIR} && ./build.sh -p sun6i 311. gen_output_${PLATFORM} 312. ;; 313. sun6i_fiber_a31s) 314. echo "build uboot for sun6i_fiber_a31s" 315. cd ${U_BOOT_DIR} && ./build.sh -p sun6i 316. gen_output_${PLATFORM} 317. ;; 318. sun6i_fiber_a31s512m) 319. echo "build uboot for sun6i_fiber_a31s" 320. cd ${U_BOOT_DIR} && ./build.sh -p sun6i 321. gen_output_${PLATFORM} 322. ;; 323. sun6i_dragonboard) 324. echo "build uboot for sun6i_dragonboard" 325. cd ${U_BOOT_DIR} && ./build.sh -p sun6i 326. 327. ;; 328. *) 329. echo "build uboot for ${PLATFORM}" 330. cd ${U_BOOT_DIR} && ./build.sh -p ${PLATFORM} 331. ;; 332. esac 333. 334. #regen_rootfs 335. 336. #gen_output_${PLATFORM} 337. //最后编译完成会显示如下信息 338. echo -e "\033[0;31;1m###############################\033[0m" 339. echo -e "\033[0;31;1m# compile success #\033[0m" 340. echo -e "\033[0;31;1m###############################\033[0m" 341. fi