




已阅读5页,还剩11页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Uclinux内核配置与裁减创建时间:08/01/17创建人:叶振风最后修改时间:修改人:叶振风Uclinux的配置和裁减也是利用的华恒科技提供的源码包(用于hhbf531学习板)。我们使用的开发板信息如下:CPU:BF533FLASH:S29AL004D-512KBSDRAM:HY57V281620-16MB这里我不敢说“uclinux的移植”,而只是以“配置与裁减”代之,是因为我觉得自己的工作真的谈不上什么移植。现成的源码包,所有的底层驱动都已经完成,我们所要做的只是选择自己需要的驱动、配置一下内核、做一些裁减工作而已。每每听到其他人提到“最近又完成了平台的linux移植”,我都会有点担心:国内有多少工程师能真正从最初始的工作开始,完成一个平台的系统移植应该很少吧。下面,我分以下步骤简单介绍一下我的配置过程。一,配置并在RAM中运行内核(不带根文件系统):由于我们的flash空间有限,在没有裁减之前,就算不带根文件系统,也无法烧写到flash内保存;所以先尝试下载到RAM中运行。另外,我们目前的开发板上没有网络功能,只能通过串口下载,所以在这里配置内核的过程中,做一些简单裁减,以便节约下载时间。解压源码包后,进入uclinux目录:#cd uClinux-dist设定交叉工具链:#PATH=”/usr/local/bin/gcc-bfin-3.4-uclinux/bin/:$PATH”进入配置:#make menuconfig运行后,进入“MainMenu”配置页,可以在此选择Vender/Product和Kernel/Library/Defaults等内容。根据我们使用的平台,我们选择:Vender-AnalogDevices,Product-HHBF533(或者HHBF531),Libc-uClibc;如果要配置内核和应用程序还要分别选中“Customize Kernel Settings”、“Customize Vender/User Settings”。退出保存后,将依次进入配置内核和配置应用程序页。如果想单独配置内核,可以进入目录linux-2.6.x/内运行“make menuconfig”。配置应用程序在这个源码包里好像没有单独的config选项。这些关于内核源码包结构的基本知识,需要大家提前了解。下面,我们来配置内核。配置一个可以在我们的SDRAM中运行的内核很简单,因为底层工作都已经完成。我们只需要配置一下处理器相关内容即可。处理器选项位于内核配置页的“Blackfin Processer Options”。进入该配置页,进行如下配置:CPU - BF533System type - BF533-HHBFBoard Customizations - 根据你的开发板时钟、SDRAM信息配置,其他不用修改。Clock Settings - 取消“Re-programClocks while Kernel boots”,默认为u-boot的时钟配置。其他选项不用修改,各项配置功能介绍见文档附.Linux 2.6.19.x内核编译配置选项简介。以上配置正确后,下载到你的开发板上,应该就可以运行了。但通过串口下载速度太慢,我们先去掉一些不需要的驱动。由于我们没有网络功能,所以把网络及其驱动全部取消,可以裁减150KB左右的空间;我们也不需要音视频功能,所以把音视频驱动也取消,又可以减小很大空间。如此配置后,我们可以尝试下载到SDRAM中运行了。现在,我们还不想裁减根文件系统,所以,我们想得到一个不带根文件系统的压缩内核镜像。由于华恒提供的源码包,编译后不能得到压缩的不带根文件系统的镜像,所以我们要通过修改Makefile得到我们需要的编译结果。需要修改的Makefile位于uClinux-dist目录下,打开该Makefile,在“.PHONY:linux”项的”ln f $(LINUXDIR)/vmlinux $(LINUXDIR)/linux;”语句后,添加以下内容。rm f $(LINUXDIR)/*.gz;bfin-uclinux-objcpy -O binary -S linuxlinux.bin; gzip -f9 linux.bin; bfin-uclinux-mkimage -A blackfin -O linux-T kernel -Cgzip -a 0x1000 -e 0x1000 -n uClinux Kernel Image -dlinux.bin.gz uImage.bin;这样在uClinux-dist目录下执行“make linux”就可以生成压缩的不带根文件系统的内核镜像了,该镜像文件为uImage.bin,位于linux-2.6.x目录内。现在,可以将得到的内核下载到SDRAM中运行了。因为是压缩内核,所以运行时要使用u-boot的bootm命令。至于u-boot命令的使用方法,自行学习。Makefile也是编译内核的基础知识,需要大家逐步掌握。这样,该步的工作就可以告一段落了。下载到SDRAM中,如果解压后无法运行,先检查一下上述配置操作是否有误。如果确定无误,就需要分析内核的执行过程,仔细分析问题了。接下来简单介绍一下内核执行流程。二,内核执行流程:承接上篇u-boot引导uclinux过程分析,介绍内核启动流程。/下载完内核镜像(zImage.bin)后,可以在内存中直接引导运行uclinux。因为内核是压缩后的镜像,所以需要u-boot进行解压引导,具体由u-boot的bootm指令实现。Bootm指令在u-boot内由do_bootm()函数实现,该函数位于/common/Cmd_bootm.c文件中。引导过程通过控制终端打印的信息如下:UBOOTbootm 00e00000# Booting image at 00e00000 .Image Name:Bfin uClinux KernelCreated:2007-12-202:05:37 UTCImage Type:Blackfin Linux Kernel Image (gzip compressed)Data Size:685719 Bytes = 669.6 kBLoad Address: 00001000Entry Point:00001000Verifying Checksum . OKUncompressing Kernel Image . OKStarting Kernel at 0x1000由打印信息可以看出,引导过程可以分为以下几步:l打印内核镜像头信息l内核镜像头校验l内核镜像解压l传递环境变量给内核并切换到内核运行下面分别介绍:1,打印内核镜像头信息:打印内核镜像头信息由以下函数实现:print_image_hdr (image_header_t *)addr);其中的addr可以通过以下语句查看:printf (# Booting image at %08lx .n, addr);addr就是内核镜像下载到RAM中的起始地址。打印信息的内容见前面的控制终端打印的信息。2,内核镜像头校验:由以下语句实现:if (verify) puts (Verifying Checksum . );if (crc32 (0, (char *)data, len) != ntohl(hdr-ih_dcrc)printf (Bad Data CRCn);SHOW_BOOT_PROGRESS (-3);return 1;puts (OKn);其中,(char *)data指向内核镜像起始地址,len为内核镜像头的长度,hdr-ih_dcrc为内核镜像头内保存的校验结果。校验正确,打印:Verifying Checksum . OK3,内核镜像解压:内核镜像解压根据内核的不同压缩格式调用不同的解压缩函数执行。压缩类型存储于内核镜像头中的hdr-ih_comp变量中,主要类型有:IH_COMP_NONE无压缩的XIPIH_COMP_GZIPGZIP压缩CONFIG_BZIP2BZIP2压缩我们使用的内核采用GZIP压缩格式,所以将调用GZIP解压缩函数执行解压,具体由以下函数实现:gunzip (void *)ntohl(hdr-ih_load), unc_len, (uchar *)data, &len)传递的四个参数依次是:解压目标地址(指针)、解压目标长度、解压源地址(指针)和解压源长度。其中解压目标长度只要大于实际解压后的目标长度即可。正确解压后打印如下信息:Uncompressing Kernel Image . OK4,传递环境变量给内核并切换到内核运行:内核镜像解压后,u-boot将根据内核镜像头指示的操作系统类型调用相应的boot操作函数。例如linux系统,u-boot会相应地调用do_bootm_linux()函数执行。操作系统类型存储在内核镜像头内的hdr-ih_os变量中。do_bootm_linux()函数位于lib_xxx/xxx_linux.c文件中,“xxx”表示与你的硬件平台对应的相关名称。例如,我们的平台为ADI的blackfin系列BF533,所以对应文件为lib_blackfin/bf533_linux.c。我们来分析一下do_bootm_linux()函数的内容:void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv,ulong addr, ulong * len_ptr, int verify)int (*appl)(char *cmdline);char *cmdline;#ifdef SHARED_RESOURCESswap_to(FLASH);#endifappl = (int (*)(char *)ntohl(header.ih_ep);(1)printf(Starting Kernel at %#xn, appl);(2)cmdline = make_command_line();(3)if (icache_status() flush_instruction_cache();icache_disable();if (dcache_status() flush_data_cache();dcache_disable();(*appl)(cmdline);(4)以上代码黑色部分是我们重要分析的部分,灰色内容暂时忽略;并对主要的四个语句分别标识了(1)到(4)的标号。通过语句(1)将函数指针appl指向内核解压后的起始地址,我们这里的起始地址默认为0x1000。所以接下来语句(2)的打印信息为:Starting Kernel at 0x1000语句(3)为了获得传递给linux内核的环境参数,保存在cmdline指针变量中。我们这里的内容是:root=/dev/mtdblock0 ro console=ttyS0,115200n8前半段指示根文件系统在mtd块设备中的block序号和读写属性,根据根文件系统在flash里实际存储的位置决定;后半段指示控制终端的属性。最后,语句(4)将保存在cmdline内的u-boot环境参数传递给linux内核,并切换到linux内核的起始入口点开始运行linux内核。我们看看语句(4)的汇编代码:R0 = FP 4;P1 = FP 8;CALL(P1);也就是说,编译器是将要传递的字符串参数指针放在R0中的。指向0x1000地址的函数指针则放在P1中,最后通过“CALL(P1);”跳转到内核入口点。/A,内核vmlinux入口u-boot执行“(*appl)(cmdline);”语句后,控制权就移交给linux内核,appl变量指向的地址就是linux内核的首地址。Linux内核执行的第一个文件是/linux-2.6.x/arch/blackfin/mach-bf533/head.S。经过一系列的初始化,跳转到start_kernel()函数,即进入linux系统初始化阶段。B, Linux系统初始化Start_kernel()函数位于文件/linux-2.6.x/init/main.c中,是linux内核通用的初始化函数。无论对于什么体系结构的linux,都要执行这个函数。asmlinkage void _initstart_kernel(void) char * command_line; extern struct kernel_param _start_param, _stop_param;/* Interrupts are still disabled. Do necessarysetups, then* enable them*/#if 0 /* comment by mhfan */*(volatile unsignedshort*)UART_LCR) &= 0x80; asmvolatile (ssync;);*(volatile unsignedshort*)UART_THR) = C; asm volatile (ssync;);#endif /* comment by mhfan */ lock_kernel(); page_address_init(); printk(KERN_NOTICE); printk(linux_banner); setup_arch(&command_line); setup_per_cpu_areas(); /* Do the rest non-_inited, were now alive*/ rest_init();Start_kernel()函数负责初始化内核各子系统,最后调用rest_init(),启动一个叫作init的内核线程,继续初始化。static void noinlinerest_init(void) _releases(kernel_lock) kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND); numa_default_policy(); unlock_kernel(); /* * The boot idle thread mustexecute schedule() * at least one to getthings moving: */ preempt_enable_no_resched(); schedule(); preempt_disable(); /* Call into cpu_idle with preempt disabled */ cpu_idle();起始内核线程init的任务依然是初始化,只不过是一种更高层次的初始化。static int init(void *unused) lock_kernel(); /* * init can run on any cpu. */ set_cpus_allowed(current, CPU_MASK_ALL); /* * Tell the world that weregoing to be the grim * reaper of innocentorphaned children. * * We dont want people tohave to make incorrect * assumptions about wherein the task array this * can be found. */ child_reaper = current; smp_prepare_cpus(max_cpus); do_pre_smp_initcalls(); fixup_cpu_present_map(); smp_init(); sched_init_smp(); cpuset_init_smp(); /* * Do this before initcalls,because some drivers want to access * firmware files. */ populate_rootfs();do_basic_setup(); /* * check if there is anearly userspace init. If yes, let it doall * the work */ if (!ramdisk_execute_command) ramdisk_execute_command = /init; if (sys_access(const char _user *) ramdisk_execute_command, 0)!= 0) ramdisk_execute_command = NULL;prepare_namespace(); /* * Ok, we have completed theinitial bootup, and * were essentially up andrunning. Get rid of the * initmem segments andstart the user-mode stuff. */ free_initmem(); unlock_kernel(); mark_rodata_ro(); system_state = SYSTEM_RUNNING; numa_default_policy(); if (sys_open(const char _user *) /dev/console,O_RDWR, 0) ram内核通过_initramfs_start和_initramfs_end找到根文件系统的img,这两个变量在文件/linux-2.6.x/init/Initramfs.c中被引用。介绍完根文件系统的挂载方式,我们来介绍如何配置和裁减应用程序。由于flash容量限制,而且我们也并不需要很多应用程序的支持,所以我们可以只保留最简单的init、sh、ls、cd等应用程序,其他应用全部裁减掉。注意必须保证要有init和sh,否则内核无法运行或没有shell界面。另外,为了进一步裁减体
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 纸张使用指南
- 化学废水排放监管制度执行执行
- 考研中的挑战与应对之策
- 代码管理规定
- 服装制作工艺方案
- 2025浙江嘉北街道招聘公益性岗位1人(第1号)笔试备考试题及答案解析
- 物业资产管理与财务审计要点
- 皮草设计原理分析报告
- 2025下半年浙江省海洋开发研究院招聘紧缺高层次人才2人笔试备考题库及答案解析
- 矿山开采权评估方案
- 机械加工质量控制计划
- DISC行为风格分析及沟通
- 工程款结清协议书书
- 《运动治疗技术》第二章 关节活动技术-基础理论课件
- 国家职业技术技能标准 4-01-06-01 电子商务师S 人社厅发202233号
- 2024至2030年中国迷迭香精油行业投资前景及策略咨询研究报告
- 电梯维保服务应急处理方案
- 人教版小学数学四年级上册教案全集(表格式教案)
- 事业单位公开招聘报名表
- 医学教材 变态反应性疾病的诊疗进展标准版资料
- 生活垃圾发电厂炉渣综合处理及建筑垃圾资源化项目可行性研究报告写作模板-备案审批
评论
0/150
提交评论