首先是内核源码的来源,首推的当然是来自www.kernel.org的源码,其次很多其他组织或者机构也会用这个正宗内核原版源码,根据自己开发板的应用需求进行裁剪得到最适合自己的linux系统源码,这也就是嵌入式的核心概念,软硬件可裁剪。TI当然也会为自己的BBB板子定制一个内核源码,该源码就在TI的安装包中,下载地址:http://software-dl.ti.com/sitara_linux/esd/AM335xSDK/latest/index_FDS.html。
相关参考资料:
详细讲解关于编译内核的步骤
http://processors.wiki.ti.com/index.php?oldid=149205
本例以目前官方的最新稳定版本3.16.0来进行操作,如下
zhouyu@zhouyu-virtual-machine:~/linux_kernel.org/linux-3.16$ ls
arch Documentation init lib README sound
block drivers ipc MAINTAINERS REPORTING-BUGS tools
COPYING firmware Kbuild Makefile samples usr
CREDITS fs Kconfig mm scripts virt
crypto include kernel net security
同样,查看一个内核源码的版本也是查看源码树根目录下的Makefile文件,如下图
step1:在进行任何操作之前,先清除内核源码树之前留下的中间文件,如下
zhouyu@zhouyu-virtual-machine:~/linux_kernel.org/linux-3.16$ make distclean
step2:对将要编译的内核进行配置,可以有两种方式进行选择。
方式一:在源码树根目录下arch/arm/configs/目录下有你需要的配置文件,此处选用TI-SDK里面的专门配置文件tisdk_am335x-evm_defconfig,将其复制到这个目录下,那么如下进行配置即可,
zhouyu@zhouyu-virtual-machine:~/linux_kernel.org/linux-3.16$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- tisdk_am335x-evm_defconfig
#
# configuration written to .config
#
最后一个参数表示你在arch/ar m/configs/目录下选中的配置文件,命令执行后,会依据文件tisdk_am335x-evm_defconfig在源码根目录下的生成编译源码所需的.config文件。
方式二:从其他地方(也包括方式一的目录中)你找到你需要的配置文件,将该文件复制到源码数根目录下命名.config,比如将上述的配置文件tisdk_am335x-evm_defconfig复制到根目录下为.config,那么如下进行配置即可,
zhouyu@zhouyu-virtual-machine:~/linux_kernel.org/linux-3.16$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
HOSTCC scripts/basic/fixdep
HOSTCC scripts/kconfig/conf.o
HOSTCC scripts/kconfig/lxdialog/checklist.o
HOSTCC scripts/kconfig/lxdialog/inputbox.o
HOSTCC scripts/kconfig/lxdialog/menubox.o
HOSTCC scripts/kconfig/lxdialog/textbox.o
HOSTCC scripts/kconfig/lxdialog/util.o
HOSTCC scripts/kconfig/lxdialog/yesno.o
HOSTCC scripts/kconfig/mconf.o
SHIPPED scripts/kconfig/zconf.tab.c
SHIPPED scripts/kconfig/zconf.lex.c
SHIPPED scripts/kconfig/zconf.hash.c
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/mconf
scripts/kconfig/mconf Kconfig
configuration written to .config
*** End of the configuration.
*** Execute 'make' to start the build or try 'make help'.
step3:正式开始编译
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage
......
LINK vmlinux
LD vmlinux.o
MODPOST vmlinux.o
GEN .version
CHK include/generated/compile.h
UPD include/generated/compile.h
CC init/version.o
LD init/built-in.o
KSYM .tmp_kallsyms1.o
KSYM .tmp_kallsyms2.o
LD vmlinux
SORTEX vmlinux
SYSMAP System.map
OBJCOPY arch/arm/boot/Image
Kernel: arch/arm/boot/Image is ready
AS arch/arm/boot/compressed/head.o
GZIP arch/arm/boot/compressed/piggy.gzip
AS arch/arm/boot/compressed/piggy.gzip.o
CC arch/arm/boot/compressed/misc.o
CC arch/arm/boot/compressed/decompress.o
CC arch/arm/boot/compressed/string.o
SHIPPED arch/arm/boot/compressed/hyp-stub.S
AS arch/arm/boot/compressed/hyp-stub.o
SHIPPED arch/arm/boot/compressed/fdt_rw.c
SHIPPED arch/arm/boot/compressed/fdt.h
SHIPPED arch/arm/boot/compressed/libfdt.h
SHIPPED arch/arm/boot/compressed/libfdt_internal.h
CC arch/arm/boot/compressed/fdt_rw.o
SHIPPED arch/arm/boot/compressed/fdt_ro.c
CC arch/arm/boot/compressed/fdt_ro.o
SHIPPED arch/arm/boot/compressed/fdt_wip.c
CC arch/arm/boot/compressed/fdt_wip.o
SHIPPED arch/arm/boot/compressed/fdt.c
CC arch/arm/boot/compressed/fdt.o
CC arch/arm/boot/compressed/atags_to_fdt.o
SHIPPED arch/arm/boot/compressed/lib1funcs.S
AS arch/arm/boot/compressed/lib1funcs.o
SHIPPED arch/arm/boot/compressed/ashldi3.S
AS arch/arm/boot/compressed/ashldi3.o
SHIPPED arch/arm/boot/compressed/bswapsdi2.S
AS arch/arm/boot/compressed/bswapsdi2.o
LD arch/arm/boot/compressed/vmlinux
OBJCOPY arch/arm/boot/zImage
Kernel: arch/arm/boot/zImage is ready
内核编译生成步骤:
(1)vmlinux:编译完成后得到的最初的可引导的ELF格式的内核文件,99.6MB
(2)System.map:从上述的vmlinux导出的映像文件的符号表,2.1MB
(3)arch/arm/boot/Image:经由上面的vmlinux进行OBJCOPY处理除去调试信息、注释、符号表后成为一个只包含内核代码,数据的文件, 已经不是elf格式的了,8.7MB
(4)arch/arm/boot/compressed/vmlinux:将Image镜像用gzip压缩工具进行压缩,得到piggy.gz的文件,piggy.S文件中直接将piggy.gz文件包含在其中,将piggy.S编译得到piggy.o文件,再接着将piggy.o、head.o、misc.o三个文件链接成文内核镜像vmlinux,4.3MB
(5)arch/arm/boot/zImage:将上述的vmlinux,进行OBJCOPY处理除去调试信息、注释、符号表后,得到zImage,该文件只能从0X0地址运行,4.2MB
(6)uImage:u-boot专用的内核映像文件,通过bootm命令引导的Linux压缩内核映像文件格式,mkimage工具在zImage之前加上一个长度为64字节的“头”,说明这个内核的版本、加载位置、生成时间、大小等信息;其0x40之后与zImage没区别。 uImage相比zImage的好处就是可以和bootloader共存,可由bootm命令从任意地址解压启动内核。
关于vmlinux,vmlinuz,uImage,zImage,bzImage之间的异同的参考资料:
http://www.360doc.com/content/10/1228/08/496343_81916311.shtml
或者http://blog.csdn.net/mirkerson/article/details/6442522
内核镜像zImage是如何生成的
http://blog.chinaunix.net/uid-28236237-id-3845019.html
step4:内核编译完成,得到zImage,如果还需要uImage文件,可以通过两种方式获得,第一种直接使用命令如下,
zhouyu@zhouyu-virtual-machine:~/linux_kernel.org/linux-3.16$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- LOADADDR=0x80008000 uImage
CHK include/config/kernel.release
CHK include/generated/uapi/linux/version.h
CHK include/generated/utsrelease.h
make[1]: “include/generated/mach-types.h”是最新的。
CALL scripts/checksyscalls.sh
CHK include/generated/compile.h
CHK kernel/config_data.h
Kernel: arch/arm/boot/Image is ready
Kernel: arch/arm/boot/zImage is ready
UIMAGE arch/arm/boot/uImage
Image Name: Linux-3.16.0
Created: Sun Sep 14 00:42:29 2014
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 4177544 Bytes = 4079.63 kB = 3.98 MB
Load Address: 80008000
Entry Point: 80008000
Image arch/arm/boot/uImage is ready
第二种,手动使用mkimage工具手动生成uImage文件,这种情况下,需要先将u-boot目录下的tool中将mkimage复制到/usr/local/bin目录下,即可随处使用这个工具,查看mkimage命令参数如下,
Usage: mkimage -l image
-l ==> list image header information
mkimage [-x] -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image
-A ==> set architecture to 'arch'<span style="white-space:pre"><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px; line-height: 19px; background-color: rgb(245, 245, 245); ">//用于指定CPU类型,比如arm</span></span>
-O ==> set operating system to 'os'<span style="white-space:pre"><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px; line-height: 19px; background-color: rgb(245, 245, 245); ">//用于指定操作系统,比如linux</span></span>
-T ==> set image type to 'type'<span style="white-space:pre"></span>//用于指定<span>映象类型,比如kernel</span>
-C ==> set compression type 'comp'<span style="white-space:pre"></span>//用于选择压缩方式可以none、gzip、bzip2
-a ==> set load address to 'addr' (hex)<span style="white-space:pre"></span>//用于指定载入内存的地址
-e ==> set entry point to 'ep' (hex)<span style="white-space:pre"></span>//用于指定入口地址
-n ==> set image name to 'name'<span style="white-space:pre"></span>//用于设定映像名称,这个名称保存在头部
-d ==> use image data from 'datafile'<span style="white-space:pre"></span>//用于指定制作uImage的源文件zImage的路径
-x ==> set XIP (execute in place)<span style="white-space:pre"></span>//指定执行地址
mkimage [-D dtc_options] [-f fit-image.its|-F] fit-image -D => set options for device tree compiler -f => input filename for FIT sourceSigning / verified boot not supported (CONFIG_FIT_SIGNATURE undefined) mkimage -V ==> print version information and exit
执行如下命令,
<pre name="code" class="plain">zhouyu@zhouyu-virtual-machine:~/linux_kernel.org/linux-3.16/arch/arm/boot$ mkimage -A arm -O linux -T kernel -C none -a 80008000 -e 80008040 -n uImage -d zImage uImage_mkimage_backup
Image Name: uImage
Created: Sun Sep 14 11:51:56 2014
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 4177544 Bytes = 4079.63 kB = 3.98 MB
Load Address: 80008000
Entry Point: 80008040
得到最终需要的uImage,不过我将它命名为uImage_mkimage_backup。
step5:得到了内核之后,还需要编译设备树,也就是将.dts源文件编译成.dtb文件,dts文件存放在arch/arm/boot/dts/目录之下,如图,
对于BBB板子选择红线框中的第二个文件,执行命令如下进行编译,
zhouyu@zhouyu-virtual-machine:~/linux_kernel.org/linux-3.16$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- am335x-boneblack.dtb
DTC arch/arm/boot/dts/am335x-boneblack.dtb
NOTE:如果原文件是*.dts,那么后面的参数一定是*.dtb,
得到的设备树文件如下,
step6:编译内核模块,执行命令如下,
zhouyu@zhouyu-virtual-machine:~/linux_kernel.org/linux-3.16$ make ARCH=arm CROSS_COMPILE=arm-
linux-gnueabihf- modules
......
LD [M] sound/soc/omap/snd-soc-omap.ko
CC sound/soc/omap/snd-soc-omap3pandora.mod.o
LD [M] sound/soc/omap/snd-soc-omap3pandora.ko
CC sound/soc/snd-soc-core.mod.o
LD [M] sound/soc/snd-soc-core.ko
CC sound/soundcore.mod.o
LD [M] sound/soundcore.ko
CC sound/usb/snd-usb-audio.mod.o
LD [M] sound/usb/snd-usb-audio.ko
CC sound/usb/snd-usbmidi-lib.mod.o
LD [M] sound/usb/snd-usbmidi-lib.ko
现在内核zImage/uImage、设备树dtb、内核模块都已经做好,接下来就是进行安装。
step7:安装内核和设备树文件
新版的u-boot从2013.10开始,u-boot启动后,不再在boot分区中寻找zImage/uImage、设备树dtb二进制文件,而是在rootfs分区中的/boot目录下寻找,所以将这两个文件拷贝到rootfs分区中的/boot目录下即完成安装。
step8:安装内核模块,执行命令如下,
zhouyu@zhouyu-virtual-machine:~/linux_kernel.org/linux-3.16$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=/home/zhouyu/zynfs/ modules_install
INSTALL crypto/ccm.ko
INSTALL crypto/ctr.ko
INSTALL crypto/seqiv.ko
INSTALL crypto/tcrypt.ko
INSTALL drivers/base/regmap/regmap-spi.ko
INSTALL drivers/bluetooth/bcm203x.ko
INSTALL drivers/bluetooth/bpa10x.ko
INSTALL drivers/bluetooth/btwilink.ko
INSTALL drivers/bluetooth/hci_uart.ko
INSTALL drivers/hwmon/lm75.ko
INSTALL drivers/iio/adc/ti_am335x_adc.ko
INSTALL drivers/iio/industrialio.ko
INSTALL drivers/iio/kfifo_buf.ko
INSTALL drivers/input/input-polldev.ko
INSTALL drivers/input/touchscreen/pixcir_i2c_ts.ko
INSTALL drivers/media/usb/gspca/gspca_main.ko
INSTALL drivers/media/usb/uvc/uvcvideo.ko
INSTALL drivers/media/v4l2-core/videobuf2-core.ko
INSTALL drivers/media/v4l2-core/videobuf2-memops.ko
INSTALL drivers/media/v4l2-core/videobuf2-vmalloc.ko
INSTALL drivers/misc/bmp085-i2c.ko
INSTALL drivers/misc/lis3lv02d/lis3lv02d.ko
INSTALL drivers/misc/lis3lv02d/lis3lv02d_i2c.ko
INSTALL drivers/misc/tsl2550.ko
INSTALL drivers/net/can/c_can/c_can.ko
INSTALL drivers/net/can/c_can/c_can_platform.ko
INSTALL drivers/net/can/can-dev.ko
INSTALL drivers/net/wireless/libertas/libertas.ko
INSTALL drivers/net/wireless/libertas/libertas_sdio.ko
INSTALL drivers/net/wireless/libertas/usb8xxx.ko
INSTALL drivers/net/wireless/ti/wl12xx/wl12xx.ko
INSTALL drivers/net/wireless/ti/wl18xx/wl18xx.ko
INSTALL drivers/net/wireless/ti/wlcore/wlcore.ko
INSTALL drivers/net/wireless/ti/wlcore/wlcore_sdio.ko
INSTALL drivers/phy/phy-twl4030-usb.ko
INSTALL drivers/usb/dwc3/dwc3-omap.ko
INSTALL drivers/usb/dwc3/dwc3.ko
INSTALL drivers/usb/gadget/g_acm_ms.ko
INSTALL drivers/usb/gadget/g_audio.ko
INSTALL drivers/usb/gadget/g_cdc.ko
INSTALL drivers/usb/gadget/g_dbgp.ko
INSTALL drivers/usb/gadget/g_ether.ko
INSTALL drivers/usb/gadget/g_ffs.ko
INSTALL drivers/usb/gadget/g_hid.ko
INSTALL drivers/usb/gadget/g_mass_storage.ko
INSTALL drivers/usb/gadget/g_midi.ko
INSTALL drivers/usb/gadget/g_multi.ko
INSTALL drivers/usb/gadget/g_ncm.ko
INSTALL drivers/usb/gadget/g_printer.ko
INSTALL drivers/usb/gadget/g_serial.ko
INSTALL drivers/usb/gadget/g_webcam.ko
INSTALL drivers/usb/gadget/g_zero.ko
INSTALL drivers/usb/gadget/gadgetfs.ko
INSTALL drivers/usb/gadget/libcomposite.ko
INSTALL drivers/usb/gadget/u_ether.ko
INSTALL drivers/usb/gadget/u_serial.ko
INSTALL drivers/usb/gadget/usb_f_acm.ko
INSTALL drivers/usb/gadget/usb_f_ecm.ko
INSTALL drivers/usb/gadget/usb_f_ecm_subset.ko
INSTALL drivers/usb/gadget/usb_f_fs.ko
INSTALL drivers/usb/gadget/usb_f_mass_storage.ko
INSTALL drivers/usb/gadget/usb_f_ncm.ko
INSTALL drivers/usb/gadget/usb_f_obex.ko
INSTALL drivers/usb/gadget/usb_f_rndis.ko
INSTALL drivers/usb/gadget/usb_f_serial.ko
INSTALL drivers/usb/gadget/usb_f_ss_lb.ko
INSTALL drivers/usb/misc/usbtest.ko
INSTALL drivers/usb/musb/musb_am335x.ko
INSTALL drivers/usb/musb/musb_dsps.ko
INSTALL drivers/usb/musb/musb_hdrc.ko
INSTALL drivers/usb/musb/omap2430.ko
INSTALL drivers/usb/phy/phy-twl6030-usb.ko
INSTALL fs/configfs/configfs.ko
INSTALL net/802/p8022.ko
INSTALL net/802/psnap.ko
INSTALL net/802/stp.ko
INSTALL net/bluetooth/bluetooth.ko
INSTALL net/bridge/bridge.ko
INSTALL net/can/can-bcm.ko
INSTALL net/can/can-gw.ko
INSTALL net/can/can-raw.ko
INSTALL net/can/can.ko
INSTALL net/ipv4/inet_diag.ko
INSTALL net/ipv4/netfilter/ip_tables.ko
INSTALL net/ipv4/netfilter/ipt_MASQUERADE.ko
INSTALL net/ipv4/netfilter/iptable_filter.ko
INSTALL net/ipv4/netfilter/iptable_nat.ko
INSTALL net/ipv4/netfilter/nf_conntrack_ipv4.ko
INSTALL net/ipv4/netfilter/nf_defrag_ipv4.ko
INSTALL net/ipv4/netfilter/nf_nat_ipv4.ko
INSTALL net/ipv4/tcp_diag.ko
INSTALL net/ipv4/xfrm4_mode_beet.ko
INSTALL net/ipv4/xfrm4_mode_transport.ko
INSTALL net/ipv4/xfrm4_mode_tunnel.ko
INSTALL net/llc/llc.ko
INSTALL net/mac80211/mac80211.ko
INSTALL net/netfilter/nf_conntrack.ko
INSTALL net/netfilter/nf_nat.ko
INSTALL net/netfilter/x_tables.ko
INSTALL net/netfilter/xt_nat.ko
INSTALL net/netfilter/xt_tcpudp.ko
INSTALL net/wireless/cfg80211.ko
INSTALL net/wireless/lib80211.ko
INSTALL sound/core/oss/snd-mixer-oss.ko
INSTALL sound/core/oss/snd-pcm-oss.ko
INSTALL sound/core/snd-compress.ko
INSTALL sound/core/snd-hwdep.ko
INSTALL sound/core/snd-pcm-dmaengine.ko
INSTALL sound/core/snd-pcm.ko
INSTALL sound/core/snd-rawmidi.ko
INSTALL sound/core/snd-timer.ko
INSTALL sound/core/snd.ko
INSTALL sound/soc/codecs/snd-soc-dmic.ko
INSTALL sound/soc/codecs/snd-soc-tlv320aic3x.ko
INSTALL sound/soc/codecs/snd-soc-twl4030.ko
INSTALL sound/soc/codecs/snd-soc-twl6040.ko
INSTALL sound/soc/davinci/snd-soc-davinci-mcasp.ko
INSTALL sound/soc/davinci/snd-soc-davinci.ko
INSTALL sound/soc/davinci/snd-soc-evm.ko
INSTALL sound/soc/omap/snd-soc-omap-abe-twl6040.ko
INSTALL sound/soc/omap/snd-soc-omap-dmic.ko
INSTALL sound/soc/omap/snd-soc-omap-mcbsp.ko
INSTALL sound/soc/omap/snd-soc-omap-mcpdm.ko
INSTALL sound/soc/omap/snd-soc-omap-twl4030.ko
INSTALL sound/soc/omap/snd-soc-omap.ko
INSTALL sound/soc/omap/snd-soc-omap3pandora.ko
INSTALL sound/soc/snd-soc-core.ko
INSTALL sound/soundcore.ko
INSTALL sound/usb/snd-usb-audio.ko
INSTALL sound/usb/snd-usbmidi-lib.ko
DEPMOD 3.16.0
其中的参数INSTALL_MOD_PATH=/home/zhouyu/zynfs/指定了所有的内核模块都拷贝到这个路径下,而执行之后,这个目录下会有lib/modules/内核版本号/......只要把这些文件(lib文件夹)覆盖到rootfs的lib目录下,即完成了内核模块的安装。其实就是把内核模块放到你制作的根文件系统中去。在一个系统上(包括PC机)安装新内核,都会有这个文件夹目录。
制作完成!