第一章移植内核
1.1 Linux内核基础知识 1.1.1 Linux版本 1.1.2 什么是标准内核 1.1.3 Linux操作系统的分类 1.1.4 linux内核的选择 1.2 Linux内核启动过程概述 1.2.1 Bootloader启动过程 1.2.2 Linux启动过程 1.3 Linux内核移植 1.3.1 移植内核和根文件系统准备工作 1.3.2 修改Linux源码中参数 1.3.3 配置Linux内核 1.3.4、编译内核 第二章制作根文件系统 2.1 根文件系统预备知识 2.2、构建根文件按系统 2.2.1、建立根文件系统目录 2.2.2、建立动态链接库 2.2.3 交叉编译Bosybox 2.2.4 建立etc目录下的配置文件 2.2.5 制作根文件系统映像文件 第三章启动系统 第四章总结 第一章移植内核 1.1 Linux内核基础知识 在动手进行Linux内核移植之前,非常有必要对Linux内核进行一定的了解,下面从Linux内核的版本和分类说起。 1.1.1 Linux版本 Linux内核的版本号可以从源代码的顶层目录下的Makefile中看到,比如2.6.29.1内核的Makefile中:VERSION = 2PATCHLEVEL = 6SUBLEVEL = 29EXTRAVERSION = .1 |
其中的“VERSION”和“PATCHLEVEL”组成主版本号,比如2.4、2.5、2.6等,稳定版本的德主版本号用偶数表示(比如2.6的内核),开发中的版本号用奇数表示(比如2.5),它是下一个稳定版本内核的前身。“SUBLEVEL”称为次版本号,它不分奇偶,顺序递增,每隔1~2个月发布一个稳定版本。“EXTRAVERSION”称为扩展版本号,它不分奇偶,顺序递增,每周发布几次扩展本版号。 1.1.2什么是标准内核 按照资料上的习惯说法,标准内核(或称基础内核)就是指主要在http://www.kernel.org/维护和获取的内核,实际上它也有平台属性的。这些linux内核并不总是适用于所有linux支持的体系结构。实际上,这些内核版本很多时候并不是为一些流行的嵌入式linux系统开发的,也很少运行于这些嵌入式linux系统上,这个站点上的内核首先确保的是在Intel X86体系结构上可以正常运行,它是基于X86处理器的内核,如对 linux-2.4.18.tar.bz2的配置make menuconfig时就可以看到,Processor type and features--->中只有386、486、586/K5/5x86/6x86/6x86MX、Pentium-Classic、Pentium-MMX、Pentium-Pro/Celeron/Pentium-II、Pentium-III/Celeron(Coppermine)、Pentium-4、K6/K6-II/K6-III 、Athlon/Duron/K7 、Elan 、Crusoe、Winchip-C6 、Winchip-2 、Winchip-2A/Winchip-3 、CyrixIII/C3 选项,而没有类似Samsun 2410等其他芯片的选择。如果需要用在其他特定的处理器平台上就需要对内核进行打补丁,形成不同的嵌入式内核。实际上,不同处理器系统的内核下载站点中提供的也往往是补丁patch而已,故原x86平台上的内核变成了基础内核,也被称为标准内核了。 1.1.3 Linux操作系统的分类 第一层次分类:以主要功能差异和发行组织区分(基础linux系统/内核)。 1、标准linux 2、μClinux 无MMU支持的linux系统,运行在无MMU的CPU上。 3、Linux-RT 是最早在linux上实现硬实时支持的linux发行版本。 4、Linux/RTAI 支持硬实时的linux,于RT-linux最大的不同之处在于RTAI定义了RTHAL,它将RTAI需要在linux中修改的部分定义成一组API接口,RTAI只使用API接口与linux交互。 5、Embedix 由Lineo公司开发,基于PowerPC和x86平台开发的。 6、Blue Cat Linux 7、Hard Hat Linux 8、其他 第二层分类:以应用的嵌入式平台区分(嵌入式linux系统/内核,使上面第一类中的各种linux系统扩展为对特定目标硬件的支持,成为一种具体的嵌入式linux系统) 由于嵌入式系统的发展与linux内核的发展是不同步的,所以为了要找一个能够运行于目标系统上的内核,需要对内核进行选择、配置和定制。因为每一种系统都是国际上不同的内核开发小组维护的,因此选择linux内核源码的站点也不尽相同。 第二层分类中的linux系统/内核相对于第一层分类的标准内核来说,也可以称为嵌入式linxu系统/内核。如应用在ARM平台上的嵌入式Linux系统通常有arm-linux(常运行在arm9平台上),μClinux(常用在arm7平台上),在标准linux基础上扩展对其他的平台的支持往往通过安装patch实现,如armlinux就是对linux安装rmk补丁(如patch-2.4.18-rmk7.bz2)形成的,只有安装了这些补丁,内核才能顺利地移植到ARM Linux上。也有些是已经安装好补丁的内核源码包,如linux-2.4.18-rmk7.tar.bz2。 不同处理器系统的内核/内核补丁下载站点:
处理器系统 适合的内核站点 下载方式x86 http://www.kernel.org/ ftp, http, rsyncARM http://www.arm.linux.org.uk/developer/ ftp, rsyncPowerPC http://penguinppc.org/ ftp, http, rsync, BitKeeperMIPS http://www.linux-mips.org/ ftp, cvsSuperH http://linuxsh.sourceforge.net/ cvs, BitKeeperM68K http://linux-m68k.org/ ftp, httpnon-MMU CPUs http://www.uclinux.org/ ftp, http |
execve("/sbin/init",argv_init,envp_init)execve("/etc/init",argv_init,envp_init)execve("/bin/init",argv_init,envp_init)execve("/bin/sh",argv_init,envp_init) |
… .default_display =0 .gpccon = 0xaa955699, .gpccon_mask = 0xffc003cc, .gpcup = 0x0000ffff, .gpcup_mask = 0xffffffff, .gpdcon = 0xaa95aaa1, .gpdcon_mask = 0xffc0fff0, .gpdup = 0x0000faff, .gpdup_mask = 0xffffffff, .lpcsel = 0xf82, }; 7、给内核打yaffs2文件系统的补丁 cd /mnt/hgfs/share tar –zxvf /mnt/hgfs/share/cvs-root.tar.gz –C /opt/studyarm cd /opt/stdudyarm/cvs/yaffs2/ ./patch-ker.sh c /opt/studyarm/linux-2.6.29.1/ 上面命令完成下面三件事情: (1) 修改内核fs/Kconfig 增加一行:source "fs/yaffs2/Kconfig" (2) 修改内核fs/Kconfig 增加一行:ojb-$(CONFIG_YAFFS_FS) +=yaffs2/ (3) 在内核fs/目录下创建yaffs2目录 将yaffs2源码目录下面的Makefile.kernel文件复制为内核fs/yaffs2/Makefie; 将yaffs2 源码目录的Kconfig文件复制到内核fs/yaffs2目录下; 将yaffs2源码目录下的*.c *.h文件复制到内核fs/yaffs2目录下. 8、修改S3C2440的机器号 由于Bootloader传递给Linux内核的机器号为782,为与Bootloader传递参数一致,修改 arch/arm/tools/math-types文件。 s3c2440 ARCH_S3C2440 S3C2440 362 修改为: s3c2440 ARCH_S3C2440 S3C2440 782 另外,还可以不修改内核中的S3C2440机器号,只需修改修改Bootloader传递给内核的参数中的机器号就可以了。在VIVI中菜单中,按s,再按s,输入mach_type,回车,输入362,w,保存。 1.3.3配置Linux内核 1、进入Linux-2.6.29.1内核主目录,通过以下命令将2410的默认配置文件写到当前目录下的.config。S3C2410的配置和S3C2440差不多,,在这基础上进行修改。 make s3c2410_defconfig 2、配置内核模块的功能,有几种方式可以进行界面选择: make menuconfig(文本选单的配置方式,在有字符终端下才能使用) make xconfig(图形窗口模式的配置方式,图形窗口的配置比较直观,必须支持Xwindow下才能使用) make oldconfig(文本配置方式,在原内核配置的基础修改时使用) 这里使用make menuconfig命令。 3、[*]Enable loadable module support---> [*]Forced module loading [*]Module unloading 4、System Type---> S3C2410 Machines---> [*]SMDK2410/A9M2410选上其余不选 S3C2440 Machines---> [*]SMDK2440 [*]SMDK2440 with S3C2440 CPU module,其余不选 其余的Machines下选项全部不选(如2400,2412,2442,2443) 5、Kernel Features---> [*]Use the ARM EABI to compile the kernel 注:由于所使用的的交叉编译arm-linux-gcc-4.3.2是符合EABI标准交叉编译器,对于浮点运行会预设硬浮点运算FPA(Float Point Architecture),而没有FPA的CPU,比如SAMSUNG S3C2410/S3C2440,会使用FPE(Float Point Emulation 即软浮点),这样在速度上就会遇到极大的限制,使用EABI(Embedded Application Binary InteRFace)则可以对此改善处理,ARM EABI有许多革新之处,其中最突出的改进就是Float Point Performance,它使用Vector Float Point(矢量浮点),因此可以极大提高涉及到浮点运算的程序。 参考:http://www.hotchn.cn/bbs/viewthread.php?tid=130&extra=page%3D1 6、Boot options-? noinitrd root="/dev/mtdblock2" init="/linuxrc" console=ttySAC0 7、Userspace binary formats---> [*]Kernel support for ELF binaries 其它的可以全部不选。 8、选择支持yaffs2文件系统 Filesystem---> Miscellaneous filesystems---> <*>YAFFS2 file system support [*] Lets Yaffs do its own ECC Native language support <*> Codepage 437 (United States,Canada) <*>Simplified Chinese charset(GB2312) <*>Traditional Chinese charset(Big5) <*>NLS ISO 8859-1(Latin1:Western European Languages) <*>NLS UTF-8 9、Device Drivers---> Graphics support---> <*>Support for frame buffer devices---> [*]Enable firmware EDID [*]Enable Video Mode Handling Helpers <*>S3C2410 LCD framebuffer support Console display driver support---> <*>Framebuffer Console support [*]Select compiled-in fonts [*] VGA8x8 font [*]VGA8x16 font [*]Bootup logo---> [*]Standard black and white Linux logo [*]Standard 16-color Linux logo [*]Standard 224-color Linux logo 在Bootup logo--->选择的那几项,将会在系统启动时在液晶上显示开机logo。 1.3.4、编译内核 编译内核需要遵守以下步骤: 1、make dep make dep的意思就是说:如果你使用程序A(比如支持特殊设备),而A需用到B(比如B是A的一个模块/子程序)。而你在做make config的时候将一个设备的驱动由内核支持改为module,或取消支持,这将可能影响到B的一个参数的设置,需重新编译B,重新编译或连接A....如果程序数量非常多,你是很难手工完全做好此工作的。make dep实际上读取配置过程生成的配置文件,来创建对应于配置的依赖关系树,从而决定哪些需要编译而那些不需要编译。所以,你要make dep。 2、make clean 清除一些以前留下的文件,比如以前编译生成的目标文件,这一步必须要进行。否则,即使内核配置改动过,编译内核时还是将原来生成的目标文件进行连接,而不生成改动后的文件。 3、make zImage Linux内核有两种映像:一种是非压缩内核,叫 Image,另一种是它的压缩版本,叫zImage。根据内核映像的不同,Linux内核的启动在开始阶段也有所不同。zImage是Image经过压缩形成的,所以它的大小比 Image小。但为了能使用zImage,必须在它的开头加上解压缩的代码,将 zImage解压缩之后才能执行,因此它的执行速度比Image要慢。但考虑到嵌入式系统的存储空容量一般比较小,采用zImage可以占用较少的存储空间,因此牺牲一点性能上的代价也是值得的,所以一般的嵌入式系统均采用压缩内核的方式。 编译完成后,会在内核目录arch/arm/boot/下生成zImage内核映像文件。
=======================================================================================================
第二章制作根文件系统 2.1 根文件系统预备知识 嵌入式Linux中都需要构建根文件系统,构建根文件系统的规则在FHS(Filesystem Hierarchy Standard)文档中,下面是根文件系统顶层目录。
目录 | 内容 |
bin | 存放所有用户都可以使用的、基本的命令。 |
sbin | 存放的是基本的系统命令,它们用于启动系统、修复系统等。 |
usr | 里面存放的是共享、只读的程序和数据。 |
proc | 这是个空目录,常作为proc文件系统的挂载点。 |
dev | 该目录存放设备文件和其它特殊文件。 |
etc | 存放系统配置文件,包括启动文件。 |
lib | 存放共享库和可加载块(即驱动程序),共享库用于启动系统、运行根文件系统中的可执行程序。 |
boot | 引导加载程序使用的静态文件 |
home | 用户主目录,包括供服务账号锁使用的主目录,如FTP |
mnt | 用于临时挂接某个文件系统的挂接点,通常是空目录。也可以在里面创建空的子目录。 |
opt | 给主机额外安装软件所摆放的目录。 |
root | root用户的主目录 |
tmp | 存放临时文件,通常是空目录。 |
var | 存放可变的数据。 |
#!/bin/shecho "------Create rootfs directons start...--------"mkdir rootfscd rootfsecho "--------Create root,dev....----------"mkdir root dev etc boot tmp var sys proc lib mnt homemkdir etc/init.d etc/rc.d etc/sysconfigmkdir usr/sbin usr/bin usr/lib usr/modules echo "make node in dev/console dev/null"mknod -m 600 dev/console c 5 1mknod -m 600 dev/null c 1 3 mkdir mnt/etc mnt/jffs2 mnt/yaffs mnt/data mnt/temp mkdir var/lib var/lock var/run var/tmp chmod 1777 tmpchmod 1777 var/tmp echo "-------make direction done---------" |
#etc/inittab::sysinit:/etc/init.d/rcS::askfirst:-/bin/sh::ctrlaltdel:/sbin/reboot::shutdown:/bin/umount -a –r |
#!/bin/shPATH=/sbin:/bin:/usr/sbin:/usr/binrunlevel=Sprevlevel=Numask 022export PATH runlevel prevlevel echo "----------munt all----------------"mount -a echo /sbin/mdev>/proc/sys/kernel/hotplugmdev -s echo "***********************************************"echo "****************Studying ARM*********************"echo "Kernel version:linux-2.6.29.1"echo "Student:Feng dong rui"echo "Date:2009.07.15"echo "***********************************************" /bin/hostname -F /etc/sysconfig/HOSTNAME |
#device mount-point type option dump fsck orderproc /proc proc defaults 0 0none /tmp ramfs defaults 0 0sysfs /sys sysfs defaults 0 0mdev /dev ramfs defaults 0 0 |
#Ash profile#vim:syntax=sh #No core file by defaults#ulimit -S -c 0>/dev/null 2>&1 USER="id -un"LOGNAME=$USERPS1='[/u@/h=W]#'PATH=$PATHHOSTNAME='/bin/hostname'export USER LOGNAME PS1 PATH |
======================================================================================================= 第三章启动系统 将前面两章生成的内核映像文件和根文件系统映像文件下载到mini2440开发板,查看启动信息。我成功移植启动信息如下:
VIVI version 0.1.4 (root@capcross) (gcc version 2.95.3 20010315 (release)) #0.1.4 Mon Oct 27 10:18:15 CST 2008MMU table base address = 0x33DFC000Succeed memory mapping.DIVN_UPLL0MPLLVal [M:7fh,P:2h,S:1h]CLKDIVN:5h +---------------------------------------------+| S3C2440A USB Downloader ver R0.03 2004 Jan |+---------------------------------------------+USB: IN_ENDPOINT:1 OUT_ENDPOINT:3FORMAT: <ADDR(DATA):4>+<SIZE(n+10):4>+<DATA:n>+<CS:2>NOTE: Power off/on or press the reset button for 1 sec in order to get a valid USB device address. NAND device: Manufacture ID: 0xec, Chip ID: 0x76 (Samsung K9D1208V0M)Found saved vivi parameters.Press Return to start the LINUX/Wince now, any other key for viviCopy linux kernel from 0x00050000 to 0x30008000, size = 0x00200000 ... donezImage magic = 0x016f2818Setup linux parameters at 0x30000100linux command line is: "noinitrd root="/dev/mtdblock2" init="/linuxrc" console="ttySAC0""MACH_TYPE = 362NOW, Booting Linux......Uncompressing Linux.......................................................................................................................... done, booting the kernel.Linux version 2.6.29.1 (root@localhost.localdomain) (gcc version 4.3.2 (Sourcery G++ Lite 2008q3-72) ) #8 Sat Jul 18 10:37:22 CST 2009CPU: ARM920T [41129200] revision 0 (ARMv4T), cr="c0007177"CPU: VIVT data cache, VIVT instruction cacheMachine: Study-S3C2440ATAG_INITRD is deprecated; please update your bootloader.Memory policy: ECC disabled, Data cache writebackCPU S3C2440A (id 0x32440001)S3C24XX Clocks, (c) 2004 Simtec ElectronicsS3C244X: core 405.000 MHz, memory 101.250 MHz, peripheral 50.625 MHzCLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL onBuilt 1 zonelists in Zone order, mobility grouping on. Total pages: 16256Kernel command line: noinitrd root="/dev/mtdblock2" init="/linuxrc" console="ttySAC0"irq: clearing pending status 02000000irq: clearing subpending status 00000002PID hash table entries: 256 (order: 8, 1024 bytes)Console: colour dummy device 80x30console [ttySAC0] enabledDentry cache hash table entries: 8192 (order: 3, 32768 bytes)Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)Memory: 64MB = 64MB totalMemory: 60876KB available (3536K code, 293K data, 136K init)Calibrating delay loop... 201.93 BogoMIPS (lpj=504832)Mount-cache hash table entries: 512CPU: Testing write buffer coherency: oknet_namespace: 296 bytesNET: Registered protocol family 16S3C2410 Power Management, (c) 2004 Simtec ElectronicsS3C2440: Initialising architectureS3C2440: IRQ SupportS3C24XX DMA Driver, (c) 2003-2004,2006 Simtec ElectronicsDMA channel 0 at c4808000, irq 33DMA channel 1 at c4808040, irq 34DMA channel 2 at c4808080, irq 35DMA channel 3 at c48080c0, irq 36S3C244X: Clock Support, DVS offbio: create slab <bio-0> at 0SCSI subsystem initializedusbcore: registered new interface driver usbfsusbcore: registered new interface driver hubusbcore: registered new device driver usbNET: Registered protocol family 2IP route cache hash table entries: 1024 (order: 0, 4096 bytes)TCP established hash table entries: 2048 (order: 2, 16384 bytes)TCP bind hash table entries: 2048 (order: 1, 8192 bytes)TCP: Hash tables configured (established 2048 bind 2048)TCP reno registeredNET: Registered protocol family 1NTFS driver 2.1.29 [Flags: R/O].yaffs Jul 18 2009 10:31:41 Installing.msgmni has been set to 119io scheduler noop registeredio scheduler anticipatory registered (default)io scheduler deadline registeredio scheduler cfq registeredConsole: switching to colour frame buffer device 30x40fb0: s3c2410fb frame buffer devicelp: driver loaded but no devices foundppdev: user-space parallel port driverSerial: 8250/16550 driver, 4 ports, IRQ sharing enableds3c2440-uart.0: s3c2410_serial0 at MMIO 0x50000000 (irq = 70) is a S3C2440s3c2440-uart.1: s3c2410_serial1 at MMIO 0x50004000 (irq = 73) is a S3C2440s3c2440-uart.2: s3c2410_serial2 at MMIO 0x50008000 (irq = 76) is a S3C2440brd: module loadedloop: module loadeddm9000 Ethernet Driver, V1.31Uniform Multi-Platform E-IDE driveride-gd driver 1.18ide-cd driver 5.00Driver 'sd' needs updating - please use bus_type methodsS3C24XX NAND Driver, (c) 2004 Simtec Electronicss3c2440-nand s3c2440-nand: Tacls="1", 9ns Twrph0=4 39ns, Twrph1=1 9nsNAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bit)Scanning device for bad blocksCreating 3 MTD partitions on "NAND 64MiB 3,3V 8-bit":0x000000000000-0x000000030000 : "boot"0x000000050000-0x000000250000 : "kernel"0x000000250000-0x000003ffc000 : "kernel"usbmon: debugfs is not availableohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Drivers3c2410-ohci s3c2410-ohci: S3C24XX OHCIs3c2410-ohci s3c2410-ohci: new USB bus registered, assigned bus number 1s3c2410-ohci s3c2410-ohci: irq 42, io mem 0x49000000usb usb1: New USB device found, idVendor="1d6b", idProduct="0001"usb usb1: New USB device strings: Mfr="3", Product="2", SerialNumber="1"usb usb1: Product: S3C24XX OHCIusb usb1: Manufacturer: Linux 2.6.29.1 ohci_hcdusb usb1: SerialNumber: s3c24xxusb usb1: configuration #1 chosen from 1 choicehub 1-0:1.0: USB hub foundhub 1-0:1.0: 2 ports detectedusbcore: registered new interface driver libusualusbcore: registered new interface driver usbserialUSB Serial support registered for genericusbcore: registered new interface driver usbserial_genericusbserial: USB Serial Driver coreUSB Serial support registered for FTDI USB Serial Deviceusbcore: registered new interface driver ftdi_sioftdi_sio: v1.4.3:USB FTDI Serial Converters DriverUSB Serial support registered for pl2303usbcore: registered new interface driver pl2303pl2303: Prolific PL2303 USB to serial adaptor drivers3c2410_udc: debugfs dir creation failed -19mice: PS/2 mouse device common for all micei2c /dev entries drivers3c2440-i2c s3c2440-i2c: slave address 0x10s3c2440-i2c s3c2440-i2c: bus frequency set to 98 KHzs3c2440-i2c s3c2440-i2c: i2c-0: S3C I2C adapterS3C2410 Watchdog Timer, (c) 2004 Simtec Electronicss3c2410-wdt s3c2410-wdt: watchdog inactive, reset disabled, irq enabledTCP cubic registeredRPC: Registered udp transport module.RPC: Registered tcp transport module.yaffs: dev is 32505858 name is "mtdblock2"yaffs: passed flags ""yaffs: Attempting MTD mount on 31.2, "mtdblock2"yaffs_read_super: isCheckpointed 0VFS: Mounted root (yaffs filesystem) on device 31:2.Freeing init memory: 136K----------munt all----------------***************************************************************Studying ARM*********************Kernel version:linux-2.6.29.1Student:Feng dong ruiDate:2009.07.15*********************************************** Please press Enter to activate this console.[@MrFeng=W]#lsbin etc linuxrc proc sys varboot home lost+found root tmp wwwdev lib mnt sbin usr[@MrFeng=W]# |
总结 参照友善的说明书熟悉了mini2440开发板的环境和使用,知道怎么使用,并不知道该如何自己构建这样的一个环境。在网上看到很多人从移植内核和根文件系统开始搭建开发环境,再写设备驱动和应用程序,基本上就是围绕着“内核--->驱动--->应用程序”这条线来的。移植内核和根文件系统,我参照了几十篇网上的文章和一些好心网友整理的资料,终于搭建好了一个能够正常启动的内核和根文件系统。在这里非常感谢网友的无私奉献,为感谢网友、分享学习心得,这是我写这篇笔记的主要原因,只会索取而不奉献怎么行,希望我的笔记对初学者有用,我也是初学者,正在学习。