Linux内核在s3c2410平台的移植

 一.内核结构
/arch       所有硬件结构特定的kernel代码。多平台设计所用,如i386,alpha,arm(与体系结构相关的代码都存放在arch//和include/asm-/目录下。如arm体系则是arch/arm和include/asm-arm.);
/drivers   内核中所有的设备驱动程序,如usb和sound;
/fs   所有的文件系统的代码,如ntfs,ext3,jffs2等;
/include   建立内核代码时所需要的大部分库文件,这个模块利用其他模块重建内核。该目录也包括了不同平台需要的库文件,如asm-arm是arm平台需要的库文件;
/init  内核的初始化代码,内核从此处开始工作;
/ipc  进程间通信代码;
/kernel       主内核代码;
/mm 所有内存管理代码;
/net  和网络相关的代码,如atm,ipv6等;

一般在每个目录下都有一个.depend文件和一个Makefile文件。这两个文件都是编译时使用的辅助文件。

1./arch
  linux系统能支持如此多平台的部分原因是因为内核把sourcecode清晰地划分为与体系结构无关部分和体系结构相关部分。/arch包含与体系结构相关的代码.其中每一个目录代表一种硬件平台,such as arm,i386.对任何平台,都必须包括以下几个目录:
/boot:启动内核所使用的部分或全部平台特有代码;
/kernel:存放支持体系结构特有的(如信号处理和SMP)特征的实现;
/lib:存放告诉的体系结构特有的(如strlen和memcpy)通用的函数的实现;
/mm:存放体系结构特有的内存管理程序的实现;
/math-emu:模拟FPU的代码。对于arm处理器来说,此目录用mach-xxx代替。
So,移植工作的重点就是 /arch目录下的文件。

2./dirvers
  所有的设备驱动程序。它占整个内核发行版本代码的一半以上,非常庞大。有些驱动程序是与硬件平台无关的而有些是相关的。

3./fs
  所有的文件系统的代码。如ntfs,ext3,jffs2等。一般来说,文件系统也与硬件平台无关。

4./include
  建立编译内核代码时所需要的大部分头文件,例如与平台无关的头文件在/include/linux下。不同的平台需要的头文件会有所不同,因此该目录和/arch一样,按平台划分了多个sub-dir,such as asm-arm.

5./init
  内核的初始化代码(不是系统的引导代码),有main.c和version.c两个文件。这是研究核心如何工作的好起点。

6./ipc
  进程间通信代码.

7./kernel
  内核管理的核心代码。与处理器相关的代码都放在arch/*/kernel目录下。

8./lib
  与平台无关的如strlen和memcpy等通用函数.

9./mm
  所有的内存管理代码。与具体硬件体系结构相关的内存管理代码位于/arch/*/mm下。

10./net
  和网络相关的代码,如atm,ipv6等.其每一个子目录对应网络的一个方面。

11./其他
  还有两个dir.:/documentation including many docs和/scripts主要在配置内核时用到,存放了配置内核的一些脚本文件,如make menuconfig.
-----------------------------------------

二、    Linux操作系统的移植

假定内核代码存放在/usr/src/linux-2.4.18下,并设置环境变量$KERNELCODE=/usr/src/linux-2.4.18.

1.根目录
  只需要修改Makefile文件。这里Makefile的任务是:产生vmlinux文件和产生内核模块.
它将递归进入到内核的各个子目录中,分别调用位于这些子目录中的Makefile.起到组织内核的各模块,记录各模块的相互联系和以来关系。(建议一定读懂Makefile文件。)
  对最上层的Makefile的修改:
a:指定目标平台
before: ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
after:  ARCH := arm

b:指定交叉编译器
before: CROSS_COMPILE        =
after:  CROSS_COMPILE        = /opt/host/armv4l/bin/armv4l-unknown-linux-
//反正是指定交叉编译程序的目录.
Note that if you reset the CROSS_COMPILE,
      CC          = $(CROSS_COMPILE)gcc
if not reset,
       CC          = $(shell if [ -n "$(CROSS_COMPILE)" ]; then echo $(CROSS_COMPILE)gcc; else /
                $(CONFIG_SHELL) scripts/kwhich gcc296 2>/dev/null || echo cc; fi)

另外,你可能需要设置:
----------------
TMPDIR        = /dev/shm
而不需要
AWK              = awk
TMPPREFIX  =
-------------
在export中好象不要FINDHPATH,其他基本都加上。
-----------------
# INSTALL_PATH specifies where to place the updated kernel and system map
# images.  Uncomment if you want to place them anywhere other than root.
这个应该不要。
#export   INSTALL_PATH=/boot
----------------------
# INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory
# relocations required by build roots.  This is not defined in the
# makefile but the arguement can be passed to make if needed.
需要加入
export INSTALL_MOD_PATH=/tmp

------------------
2.arch目录
  这里存放着和体系结构相关部分的内核代码。
2.1 Makefile
  手动add:
ifeq ($(CONFIG_ARCH_S3C2410),y)
TEXTADDR   = 0xC0008000
MACHINE             = s3c2410
endif

TEXTADDR决定内核起始运行地址,即image.ram应下载的地址。
要点:根据自己的电路设置TEXTADDR变量。
这里我们的电路地址是0xC0008000:从地址0xC0000000开始,总共32MB的空间。

2.2 config.in
  配置文件,运行make menuconfig命令时出现的菜单就是config配置的。
a.添加CONFIG_ARCH_S3C2410子选项
if [ "$CONFIG_ARCH_S3C2410" = "y" ]; then
comment 'S3C2410 Implementation'
dep_bool ' SMDK (MERI TECH BOARD)' CONFIG_S3C2410_SMDK $CONFIG_ARCH_S3C2410
dep_bool '   change AIJI' CONFIG_SMDK_AIJI
dep_tristate 'S3C2410 USB function support' CONFIG_S3C2410_USB $CONFIG_ARCH_S3C2100
dep_tristate '  Support for S3C2410 USB character device emulation' CONFIG_S3C2410_USB_CHAR $CONFIG_S3C2410_USB
fi     # /* CONFIG_ARCH_S3C2410 */

b. other options
if [ "$CONFIG_FOOTBRIDGE_HOST" = "y" -o /
     "$CONFIG_ARCH_SHARK" = "y" -o /
     "$CONFIG_ARCH_CLPS7500" = "y" -o /
     "$CONFIG_ARCH_EBSA110" = "y" -o /
     "$CONFIG_ARCH_CDB89712" = "y" -o /
     "$CONFIG_ARCH_EDB7211" = "y" -o /
     "$CONFIG_ARCH_S3C2400" = "y" -o /
     "$CONFIG_ARCH_S3C2410" = "y" -o /
     "$CONFIG_ARCH_SA1100" = "y" ]; then
   define_bool CONFIG_ISA y
else
   define_bool CONFIG_ISA n
fi
---------
类似的添加项不只一处,读者可以根据需要在需要的地方加入。
移植要点:config文件决定了menuconfig菜单的内容。把使用的平台加在需要的地方,这样在配置linux内核时就能够选择是否支持你的平台了。

3 arch/arm/boot目录
  编译出来的内核是存放在这个目录中。这里将指定内核解压到目标板的地址,所以如果内核无法正常启动,很有可能是这里的地址指定错误。
3.1 Makefile

ifeq ($(CONFIG_ARCH_S3C2410),y)
ZTEXTADDR = 0x30008000
ZRELADDR   = 0x30008000
endif
------
ZRELADDR决定内核解压后数据输出的地址。
ZTEXTADDR为bootloader的压缩内核文件烧入flash的起始地址,即从哪个位置开始执行bootloader,若启动时直接运行,则将其设为0;若自带bios可以跳到想要的地址,则可改为所要的位置。
移植要点:要根据自己的电路设置ZTEXTADDR和ZRELADDR变量。

3.2 compressed/Makefile
  通过这个文件将从vmlinux创建一个压缩的vmlinuz镜像。此文件中用到的SYSTEM,ZTEXTADDR,ZBSSADDR和ZRELADDR是从arch/arm/boot/Makefile获得的。
ifeq ($(CONFIG_ARCH_S3C2410),y)
OBJS             += head-s3c2410.o
endif
移植要点:加入head-s3c2410.S

3.3 arch/arm/boot/compressed/head-s3c2410.S
  主要用来init处理器。好好研究下汇编代码//如何进行初始化需要仔细研究处理器的手册。
#include
#include
#include

       .section   ".start", #alloc, #execinstr

__S3C2410_start:

       @ Preserve r8/r7 i.e. kernel entry values
       @ What is it?
       @ Nandy

       @ Data cache, Intstruction cache, MMU might be active.
       @ Be sure to flush kernel binary out of the cache,
       @ whatever state it is, before it is turned off.
       @ This is done by fetching through currently executed
       @ memory to be sure we hit the same cache

       bic   r2, pc, #0x1f         @清楚pc中的相关位,存放在寄存器r2中
       add r3, r2, #0x4000              @ r3
1:     ldr r0, [r2], #32             @r0
       teq   r2, r3                    @compare contents of two regs
       bne  1b
       mcr p15, 0, r0, c7, c10, 4     @ drain WB
       mcr p15, 0, r0, c7, c7, 0      @ flush I & D caches

#if 0
       @ disabling MMU and caches禁用mmu和caches
       mrc p15, 0, r0, c1, c0, 0      @ read control register
       bic   r0, r0, #0x05                @ disable D cache and MMU
       bic r0, r0, #1000                  @ disable I cache
       mcr p15, 0, r0, c1, c0, 0            @使前面的设置生效
#endif

       /*
        * Pause for a short time so that we give enough time
        * for the host to start a terminal up.
        *暂停一段时间,等待主机启动终端
        */
       mov r0, #0x00200000
1:     subs r0, r0, #1
       bne  1b
-------------------
Note that:arm的D cache必须和MMU一起打开,而I cache可以单独打开。

3.4 arch/arm/def-configs目录
定义了一些平台的config文件,比如lart和assert等.把配置好的文件复制到这里就可以了。

3.5 arch/arm/kernel目录
与硬件平台相关的内核代码
3.5.1 Makefile
a.add the support for s3c2410x

no-irq-arch     := $(CONFIG_ARCH_INTEGRATOR) $(CONFIG_ARCH_CLPS711X) /
                 $(CONFIG_FOOTBRIDGE) $(CONFIG_ARCH_EBSA110) /
                 $(CONFIG_ARCH_SA1100) $(CONFIG_ARCH_CAMELOT) /
                 $(CONFIG_ARCH_S3C2400) $(CONFIG_ARCH_S3C2410) /
                 $(CONFIG_ARCH_MX1ADS) $(CONFIG_ARCH_PXA)
b.add other function
  obj-$(CONFIG_MIZI)       += event.o
  obj-$(CONFIG_APM)       += apm2.o

移植要点:有任何新加的功能都要告知Makefile文件。上述两条语句的目的是编译event.c和apm2.c.

3.5.2 debug-armv.S
在适当的地方加入如下代码,目的是关闭全部外围设备的时钟,从而保证系统正确运行.
#elif defined(CONFIG_ARCH_S3C2410)

               .macro  addruart,rx
               mrc     p15, 0, /rx, c1, c0
               tst     /rx, #1         @ MMU enabled 查看是否运行mmu?
               moveq   /rx, #0x50000000        @ physical base address
               movne   /rx, #0xf0000000        @ virtual address
               .endm

               .macro  senduart,rd,rx
               str     /rd, [/rx, #0x20]       @ UTXH
               .endm

               .macro  waituart,rd,rx
               .endm

               .macro  busyuart,rd,rx
1001:  ldr     /rd, [/rx, #0x10]       @ read UTRSTAT
               tst     /rd, #1             @ TX_EMPTY ?
               beq     1001b
               .endm

3.5.3 entry-armv.S
加入cpu的中断部分。
#elif defined(CONFIG_ARCH_S3C2410)
#include

              .macro  disable_fiq
              .endm

              .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
              mov r4, #INTBASE              @ virtual address of IRQ registers

              ldr   /irqnr, [r4, #0x8]    @ read INTMSK
              ldr   /irqstat, [r4, #0x10]   @ read INTPND

              bics    /irqstat, /irqstat, /irqnr
              bics    /irqstat, /irqstat, /irqnr
              beq  1002f
              
              mov /irqnr, #0
1001:             tst    /irqstat, #1
              bne  1002f                    @ jump if found IRQ
              add  /irqnr, /irqnr, #1
              mov /irqstat, /irqstat, lsr #1
              cmp /irqnr, #32
              bcc  1001b
1002:
              .endm

              .macro  irq_prio_table
              .endm            
---
移植要点:了解cpu初始化时是如何处理中断的。寄存器在s3c2410.h中定义。

3.5.4 setup.c
这个文件中有一个非常重要的函数setup_arch。这个函数用来完成和体系相关的初始化工作,比如对物理内存结构meminfo的初始化。这个结构将在后面的内存初始化中起到很重要的作用。其中,nr_banks指定了内存块的数量,bank指定了每块内存的范围。用来指定块开始及长度的PAGE_OFFSET和MEM——SIZE都在include/asm-arm/arch-s3c2410/memory.h中定义,PAGE_OFFSET是内存的开始地址,这块板子设置该值为0x00000000UL,就是前面介绍的init和data的开始地址,结束地址自然就是内存的结束地址。后文介绍的函数就将根据meminfo进行内存结构初始化。

3.6 arch/arm/mm目录
  此目录下的文件是和arm平台相关的内存管理内容,只有mm-armv.c文件需要移植。
把init_maps->bufferable = 0;
改为:
init_maps->bufferable = 1;
init_maps是一个map_desc性数据结构。map_desc定义在/include/asm-arm/mach/map.h中
struct map_desc {
       unsigned long virtual;
       unsigned long physical;
       unsigned long length;
       int domain:4,
           prot_read:1,
           prot_write:1,
           cacheable:1,
           bufferable:1,
           last:1;
};

3.7 arch/arm/mach-s3c2410目录
  这里只是对处理器的基本信息提供了支持,有关开发板的外设,如usb,powermanage等都需要用户自己添加。(可参考相应开发板配套cd).


三、    编译linux内核

之前要配置内核:
make config;
make oldconfig;
make menuconfig;
make xconfig.

无论哪个命令都产生一个.config文件,并在每个.c文件中加上,使define的宏CONFIG_XXX起全局性作用。
查看内核的配置:
make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig

执行make dep
make zImage
make modules
make modules_install

安装内核需要copy 4个文件:没压缩的内核镜像zImage,压缩的内核镜像vmlinux,内核符号映射文件System.map以及配置文件.config.
zImage文件是和平台无关的,它在Makefile文件中设置。这里使用arm平台,so生成的镜像文件在/arch/arm/boot/zImage下。其他三个文件在内核代码的根目录/usr/src/linux-2.4.18下.
对创建的内核进行backup的好处是能通过配置文件知道内核的功能。比如是否lcd的驱动,是否有bluetooth等。代码如下:

cp arch/arm/boot/zImage $(YOURBAKPATH)/image/zImage-2.4.18-rmk7
cp System.map $(YOURBAKPATH)/image/System.map-2.4.18-rmk7
cp vmlinux $(YOURBAKPATH)/image/vmlinux-2.4.18-rmk7
cp .config $(YOURBAKPATH)/image/2.4.18-rmk7.config

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值