首先是内核源码的来源,首推的当然是来自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机)安装新内核,都会有这个文件夹目录。
制作完成!