本章將依序介紹
1.Android BSP包 資料夾的意義
2.開機流程及說明
3.[嵌入式系統]Android 原廠-Bootloader build
4.[嵌入式系統]Android 原廠-Kernel build
5.[嵌入式系統]Android 原廠-Image build
===============================================
1.Android BSP包 資料夾的意義
android最上層目錄結構如下:
|-- Makefile (全域的Makefile)
|-- bionic (Bionic含意為仿生,這裡面主要放一些基礎的libraries的source code)
|-- bootloader (開機時bootload環境build的source code)
|-- build (build目錄中的內容不是目標所用的code,而是編譯和配置所需要的script及tools)
|-- dalvik (Android虛擬機器)
|-- development (程式開發所需要的樣板和tools)
|-- external (目標機器使用的一些libraries)
|-- frameworks (應用程式的架構層)
|-- hardware (與硬體相關的庫)
|-- kernel (Linux2.6的Source code)
|-- packages (Android的各種應用程式)
|-- prebuilt (Android在各種平台下編譯的預置script)
|-- recovery (與目標的恢復功能相關)
`-- system (Android的底層的一些libraries)
|-- bionic (Bionic含意為仿生,這裡面主要放一些基礎的libraries的source code)
|-- bootloader (開機時bootload環境build的source code)
|-- build (build目錄中的內容不是目標所用的code,而是編譯和配置所需要的script及tools)
|-- dalvik (Android虛擬機器)
|-- development (程式開發所需要的樣板和tools)
|-- external (目標機器使用的一些libraries)
|-- frameworks (應用程式的架構層)
|-- hardware (與硬體相關的庫)
|-- kernel (Linux2.6的Source code)
|-- packages (Android的各種應用程式)
|-- prebuilt (Android在各種平台下編譯的預置script)
|-- recovery (與目標的恢復功能相關)
`-- system (Android的底層的一些libraries)
2.開機流程及說明
開機順序
Env > bootloader > kernel
env檔主要為開機設定檔 定義bootloader 及 kernel的所在(記憶體位置)及版本
編輯主要需要16進制的編輯軟體
在此我是使用windows 去作編輯
因為是編輯16進制 可以找關鍵字hex editor
使用HxD : http://mh-nexus.de/en/hxd/
(Linux's GUI的hex editor 首推 bless 套件package名稱就叫做bless 可以透過apt-get安裝.)
找到最新版的之後安裝並開啟 並將欲編輯的文件直接拉近去作編輯
編輯完之後補完128k-5的位置
先存檔
再用CRC32檢查工具 將文件的CRC32碼逆向編入文件中00~03的位置
04則填入00或01使文件變成128k長度
行號會補0到1fff0 另存成bin檔 即可作燒寫入的動作
機器有此Env檔 就會按照設定去讀入對應的bootloader(U-boot)及kernel
以目前經驗來說Env檔會直接燒製在機器中,是由工廠用治具來燒製進去
第二步會去載入bootloader (U-boot):
Buildloader在Linux中主要用來決定系統的設定(包含硬體Memory的決定)(舉例來說你的機器是512MB但是bootloader是用1GB就會沒辦法開機,甚至在kernel載入就會有問題:但1G硬體載512MB可以正常開機),支援哪些指令(busy box 及 燒錄指令等)
第三步會依據env去載入kernel:
kernel主要build出取決於硬體有沒有打開通道的依據來讓上層軟體溝通,kernel在我觀念我認為他是framework或HAL層,在硬體跟軟體的中間。
3.[嵌入式系統]Android 原廠-Bootloader build
4.[嵌入式系統]Android 原廠-Kernel build
在android中要build kernel,若是硬體要打開的話,建議由android/kernel 進去,並下make menuconfig(由各層Kconfig檔组成)進去編輯(【】,【*】,【M】)(或用vim去編輯系統產生的.config文件。在裡面y代表打開,m代表模組化(模組化是為了省空間,但每次要使用需要用mknod來掛載),那我們傾向用y來打開硬體功能。
接下來也可選擇進到底下每一層 觀看Makefile或Kconfig檔(Kconfig的用途為Make選單的建立此外,Kconfig文件跟這些設定結果並沒有直接的關係,只是決定了make menuconfig的選單的選項)來設定:
(注意:由於是樹狀結構目錄,若最底層變動或新增Makefile,上一層也必須新增,否則在build kernel時會發生錯誤或無效)
Ref:
http://blog.csdn.net/flydream0/article/details/7079381:
1 Kconfig和Makefile
毫不夸张地说,Kconfig和Makefile是我们浏览内核代码时最为依仗的两个文件。基本上,Linux 内核中每一个目录下边都会有一个Kconfig文件和一个Makefile文件。Kconfig和Makefile就好似一个城市的地图,地图引导我们去 认识一个城市,而Kconfig和Makefile则可以让我们了解一个内核目录下面的结构。在希望研究内核的某个子系统、某个驱动或其他某个部分时,都 有必要首先仔细阅读一下相关目录下的Kconfig和Makefile文件。
分布到各目录的Kconfig构成了一个分布式的内核配置数据库,每个Kconfig分别描述了所属目录源文档相关的内核配置菜单。在内核配置make menuconfig时,从Kconfig中读出菜单,用户选择后保存到.config的内核配置文档中。 在内核编译时,主Makefile调用这个.config,就知道了用户的选择。
假如想使这个驱动被编译,则要修改Makefile文件,因此,需要添加新的驱动时,需要修改的文件有两个:Kconfig,Makefile.
2 菜单组织结构
一般一个Kconfig文件表示的就是一个菜单,一个菜单由多个菜单项组成,其格式如下:
- menu 菜单名
- 菜单项或菜单链接1
- 菜单项或菜单链接2
- ...
- 菜单项或菜单链接n
- endmenu
例如:
- # drivers/Kconfig
- menu "Device Drivers"
- source "drivers/base/Kconfig"
- source "drivers/connector/Kconfig"
- source "drivers/mtd/Kconfig"
- source "drivers/of/Kconfig"
- source "drivers/parport/Kconfig"
- source "drivers/pnp/Kconfig"
- source "drivers/block/Kconfig"
- source "drivers/hello/Kconfig"
- config test
- bool "提示字符串"
- default y
- ...
- endmenu
2.1 菜单项
语法:
- config <symbol>
- <config options>
例如:
- config UEVENT_HELPER_PATH
- string "path to uevent helper"
- depends on HOTPLUG
- default "/sbin/hotplug"
- help
- Path to uevent helper program forked by the kernel for
- every uevent.
注:每个config菜单项都会产生一个配置选项CONFIG_XXX, XXX即为. 如上,则会产生一个配置项:CONFIG_UEVENT_HELPER_PATH,此配置项的值记录在内核根目录下的隐藏文件.config内, 例:~/WORKING_DIRECTORY/kernel/goldfish/.config文件内.
2.2 菜单链接
菜单链接的格式如下:
- source "路径"
- source "drivers/pnp/Kconfig"
2.3 菜单属性
2.3.1 类型
类型可以是:bool、tristate、string、hex和int。
bool类型的只能选中或不选中,选中为y,不选中为n.
tristate类型的菜单项为值可为三种值,多了编译成内核模块的选项。其值可为y,n,m.
string类型表示需要用户输入一串字符串。
hex类型则需要用户输入一个16进制数。
int类型表示用户输入一个整型.
总结:
菜单类型属性就好比一个控件,bool相当于单选框,trstate相当于有三种状态的复选框,string相当于供用户输入字符串的文本编辑框,hex相当于供用户输入16进制数的文本编辑框,而int就相当于供用户输入整型数的文本编辑框。
类型关键字后边可跟随提示字符,也可以不跟随,取决于情况。如:
- string "path to uevent helper"
- bool "Prevent firmware from being built"
注:每一个菜单项必须有类型属性。
2.3.2 默认值
默认值属性default一般在类型属性后边,如:
- config UEVENT_HELPER_PATH
- string "path to uevent helper"
- default "/sbin/hotplug"
2.3.3 依赖
依赖可以是"depends on"或"requires".
语法:
- depends on/requires <expr>
如:
- depends on HOTPLUG
例如:
- config MODULES
- bool "Enable loadable module support"
- config MODVERSIONS
- bool "Set version information on all module symbols"
- depends on MODULES
- comment "module support disabled"
- depends on !MODULES
2.3.4 选择
语法:
- choice
- 选择项
- ..
- endchoice
2.3.5 提示
语法:
- comment "提示信息字符串"
- comment选项
comment只是用来给用户提示信息的,后跟字符串,此字符串也可以在终端中显示。
comment选项只可以是deponds on。
2.3.6 帮助
语法:
- help/---help--- <字符串>
- config EXTRA_FIRMWARE_DIR
- string "Firmware blobs root directory"
- depends on EXTRA_FIRMWARE != ""
- default "firmware"
- help
- This option controls the directory in which the kernel build system
- looks for the firmware files listed in the EXTRA_FIRMWARE option.
- The default is the firmware/ directory in the kernel source tree,
- but by changing this option you can point it elsewhere, such as
- the /lib/firmware/ directory or another separate directory
- containing firmware files.
3 举例
Kconfig:
- # drivers/Kconfig
- menu "Device Drivers"
- source "drivers/base/Kconfig"
- source "drivers/connector/Kconfig"
- source "drivers/mtd/Kconfig"
- ...
- endmenu
source "drivers/base/Kconfig"中的Kconfig内容如下:即对应着上图中的第一项"Generic Driver Option"的子菜单内容:
- menu "Generic Driver Options"
- config UEVENT_HELPER_PATH
- string "path to uevent helper"
- depends on HOTPLUG
- default "/sbin/hotplug"
- help
- Path to uevent helper program forked by the kernel for
- every uevent.
- config STANDALONE
- bool "Select only drivers that don't need compile-time external firmware" if EXPERIMENTAL
- default y
- help
- Select this option if you don't have magic firmware for drivers that
- need it.
- If unsure, say Y.
- config PREVENT_FIRMWARE_BUILD
- bool "Prevent firmware from being built"
- default y
- help
- Say yes to avoid building firmware. Firmware is usually shipped
- with the driver, and only when updating the firmware a rebuild
- should be made.
- If unsure say Y here.
- config FW_LOADER
- tristate "Userspace firmware loading support" if EMBEDDED
- depends on HOTPLUG
- default y
- ---help---
- This option is provided for the case where no in-kernel-tree modules
- require userspace firmware loading support, but a module built outside
- the kernel tree does.
- config FIRMWARE_IN_KERNEL
- bool "Include in-kernel firmware blobs in kernel binary"
- depends on FW_LOADER
- default y
- help
- The kernel source tree includes a number of firmware 'blobs'
- which are used by various drivers. The recommended way to
- use these is to run "make firmware_install" and to copy the
- resulting binary files created in usr/lib/firmware directory
- of the kernel tree to the /lib/firmware on your system so
- that they can be loaded by userspace helpers on request.
- Enabling this option will build each required firmware blob
- into the kernel directly, where request_firmware() will find
- them without having to call out to userspace. This may be
- useful if your root file system requires a device which uses
- such firmware, and do not wish to use an initrd.
- This single option controls the inclusion of firmware for
- every driver which uses request_firmware() and ships its
- firmware in the kernel source tree, to avoid a proliferation
- of 'Include firmware for xxx device' options.
- Say 'N' and let firmware be loaded from userspace.
- config EXTRA_FIRMWARE
- string "External firmware blobs to build into the kernel binary"
- depends on FW_LOADER
- help
- This option allows firmware to be built into the kernel, for the
- cases where the user either cannot or doesn't want to provide it from
- userspace at runtime (for example, when the firmware in question is
- required for accessing the boot device, and the user doesn't want to
- use an initrd).
- This option is a string, and takes the (space-separated) names of the
- firmware files -- the same names which appear in MODULE_FIRMWARE()
- and request_firmware() in the source. These files should exist under
- the directory specified by the EXTRA_FIRMWARE_DIR option, which is
- by default the firmware/ subdirectory of the kernel source tree.
- So, for example, you might set CONFIG_EXTRA_FIRMWARE="usb8388.bin",
- copy the usb8388.bin file into the firmware/ directory, and build the
- kernel. Then any request_firmware("usb8388.bin") will be
- satisfied internally without needing to call out to userspace.
- WARNING: If you include additional firmware files into your binary
- kernel image which are not available under the terms of the GPL,
- then it may be a violation of the GPL to distribute the resulting
- image -- since it combines both GPL and non-GPL work. You should
- consult a lawyer of your own before distributing such an image.
- config EXTRA_FIRMWARE_DIR
- string "Firmware blobs root directory"
- depends on EXTRA_FIRMWARE != ""
- default "firmware"
- help
- This option controls the directory in which the kernel build system
- looks for the firmware files listed in the EXTRA_FIRMWARE option.
- The default is the firmware/ directory in the kernel source tree,
- but by changing this option you can point it elsewhere, such as
- the /lib/firmware/ directory or another separate directory
- containing firmware files.
- config DEBUG_DRIVER
- bool "Driver Core verbose debug messages"
- depends on DEBUG_KERNEL
- help
- Say Y here if you want the Driver core to produce a bunch of
- debug messages to the system log. Select this if you are having a
- problem with the driver core and want to see more of what is
- going on.
- If you are unsure about this, say N here.
- config DEBUG_DEVRES
- bool "Managed device resources verbose debug messages"
- depends on DEBUG_KERNEL
- help
- This option enables kernel parameter devres.log. If set to
- non-zero, devres debug messages are printed. Select this if
- you are having a problem with devres or want to debug
- resource management for a managed device. devres.log can be
- switched on and off from sysfs node.
- If you are unsure about this, Say N here.
- config SYS_HYPERVISOR
- bool
- default n
- endmenu
各个目录下的Kconfig文件经过最终配置,最终会在内核根目录下生成一个.config文件,这是个隐藏文件,这个文件记录着各个选项的配置及值。供Makefile文件使用.
如:
.config:
- #
- # Automatically generated make config: don't edit
- # Linux kernel version: 2.6.29
- # Thu Dec 15 21:15:25 2011
- #
- CONFIG_ARM=y
- CONFIG_SYS_SUPPORTS_APM_EMULATION=y
- # CONFIG_GENERIC_GPIO is not set
- CONFIG_GENERIC_TIME=y
- CONFIG_GENERIC_CLOCKEVENTS=y
- CONFIG_MMU=y
- # CONFIG_NO_IOPORT is not set
- CONFIG_GENERIC_HARDIRQS=y
- CONFIG_STACKTRACE_SUPPORT=y
- CONFIG_HAVE_LATENCYTOP_SUPPORT=y
- CONFIG_LOCKDEP_SUPPORT=y
- CONFIG_TRACE_IRQFLAGS_SUPPORT=y
- CONFIG_HARDIRQS_SW_RESEND=y
- CONFIG_GENERIC_IRQ_PROBE=y
- CONFIG_RWSEM_GENERIC_SPINLOCK=y
- # CONFIG_ARCH_HAS_ILOG2_U32 is not set
- # CONFIG_ARCH_HAS_ILOG2_U64 is not set
- CONFIG_GENERIC_HWEIGHT=y
- CONFIG_GENERIC_CALIBRATE_DELAY=y
- CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
- CONFIG_VECTORS_BASE=0xffff0000
- CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
5.[嵌入式系統]Android 原廠-Image build
- 起始化相關變數
Android Makefile 的參照關係是這樣的
Makefile -> build/core/main.mk -> build/core/config.mk -> build/core/envsetup.mk -> build/core/product_config.mk
由 build/core/config.mk 所進行。 build/core/envsetup.mk 檢查 developer 的設定 (buildspec.mk) ,並檢查執行環境,以決定輸出目錄、項目。
build/core/config.mk 本身還依據參數,決定解譯時的相關參數。像是 compiler 的路徑、flags, lex 、yacc 的路徑參數等。
關於 product 的相關設定,則是由 build/core/product_config.mk 所處理,使用 build/core/product.mk 提供之 macro 載入。根據 AndroidProduct.mk 的內容, product_config.mk 決定了
PRODUCT_TAGSOTA_PUBLIC_KEYSPRODUCT_POLICY...... - 偵測編譯環境和目標環境
- 決定目標 product
- 讀取 product 的設定
- 讀取 product 所指定之目標平台架構設定
- 選擇 toolchain
- 指定編譯參數 (*-.mk)
- 清除輸出目錄
- 設定/檢查版本編號
- 讀取所有 BoardConfig.mk 檔案
- 讀取所有 module 的設定
- 根據設定,產生必需的 rule
- 產生 image
以上的主要流程都是由 build/core/main.mk 所安排。
沒有留言:
張貼留言