全球独家原创:linux-3.4.5内核移植到MPC880过程记录

本文记录了Linux3.4.5内核移植到MPC880平台的过程,包括解压内核文件、配置内核、选择dts配置文件、修改芯片相关配置等内容。解决了内核编译错误、根文件系统挂载失败等问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Linux3.4.5内核移植到MPC880过程记录


      最近难得清闲下来,总得给自己找点事情做。看了下手头上开发项目所用的Linux操作系统版本(基于Freescale公司的MPC880芯片)是Linux2.6.29,好像是几年前的内核版本,似乎有点落后了,连Linux3.0版本都推出好一段时间了,看来有必要试一下将最新的Linux内核版本移植到自己手头上的平台上来。晚上回家google了一下,最新的Linux内核版本升级到了linux-3.4.5版本(截止时间到2012.07.17晚上9点半),顺便down下来最新版本,拷贝带到公司留着第二天移植用。
    PS一下:我2009年9月份到的目前这家公司,当时看到这里所用的Linux内核版本还是Linux2.4.22版本时,囧!!!都什么年代了,还用这么古老的linux内核版本,太Out了,当时事业部的同事还用的不亦乐乎,让人愈发抓狂!后来事实证明,提前做好Linux内核版本的升级还是非常有必要的。因为后续产品开发对软件平台进行了重构(采用C++开发),把一个用户程序Download到Linux2.4.22平台上运行,使用top命令一看,CPU占用率飙升到98%了,更要命的是当时这个用户程序还只是集成了一部分功能,还有其他用户程序还没有启动,看来不能再继续在Linux2.4.22平台上做开发了,立马开足马力升级Linux操作系统平台!其实当时基于Linux2.6.29内核的移植工作已经完成的差不多了(未详细测试和个别驱动未移植完),将用户程序重新编译然后放到基于Linux2.6.29操作系统平台运行后,使用top命令查看CPU占用率只有4%,接近25倍的性能差异,看来Linux内核开发者平时所作的改进工作不是盖的,在此向Linux内核开发和维护者致敬。从此自己的开发工作开始跨入Linux2.6内核版本了。闲话少说,继续Linux3.4.5版本移植过程。
    移植工作第一步:解压内核文件并重新修改顶层的Makefile文件

将linux-3.4.5版本软件拷贝到Fedora12下的工作目录,并直接解压。等待解压完成后,先修改顶层的Makefile文件,指定SUBARCH := powerpc(硬件平台是PowerPC芯片-MPC880芯片)和CROSS_COMPILE :=powerpc-linux-,这一步操作估计问题不大。

然后需要打开一个终端,使用cd命令进入Linux3.4.5内核所在的位置,这时候不要忘记指定交叉编译工具的路径,例如我需要指定的交叉编译工具的路径和交叉编译工具如下:exportPATH=$PATH:/opt/eldk4.2_ppc8xx/usr/bin/

exportCROSS_COMPILE=ppc_8xx-

通过在Linux终端输入上面的命令,就完成了对交叉编译环境的设定。

移植工作第二步:选择内核编译配置

此时由于移植是在全新的Linux内核源码基础上进行的,为了避免频繁手动设定各种Linux内核配置选项,我采用的是ep88xc默认配置。此时可以在终端输入以下命令:

make ep88xc_defconfig

该默认配置信息具体内容大家可以参考/linux-3.4.5/arch/powerpc/configs/ep88xc_defconfig文件。可以看到Linux3.4.5内核编译工作开始了,此时我的电脑上编译内核时会报以下错:

BOOTCC  arch/powerpc/boot/treeboot-currituck.o

{standard input}:Assembler messages:

{standardinput}:126: Error: Unrecognized opcode: `mfdcrx' treeboot-currituck.c

出错的地方在arch/powerpc/boot/treeboot-currituck.c文件的第50行,参照以下红色标注处:

static unsignedlong long ibm_currituck_detect_memsize(void)

{

         u32 reg;

         unsigned i;

         unsigned long long memsize = 0;

 

         for(i = 0; i < MAX_RANKS; i++){

                  reg = mfdcrx(DDR3_MR0CF+ i);

 

                  if (!(reg & 1))

                          continue;

 

                  reg &= 0x0000f000;

                  reg >>= 12;

                  memsize += (0x800000ULL<< reg);

         }

 

         return memsize;

}

文件编译出错的原因是mfdcrx指令无法识别,手头的交叉编译工具可能落伍了,先关不了那么多,修改arch/powerpc/boot/Makefile文件,屏蔽treeboot-currituck相应内容,主要涉及到2个地方,

#$(obj)/treeboot-currituck.o:BOOTCFLAGS += -mcpu=405

$(obj)/virtex405-head.o:BOOTAFLAGS += -mcpu=405

以及:

src-plat:= of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c \

                  cuboot-ebony.ccuboot-hotfoot.c epapr.c treeboot-ebony.c \

                  prpmc2800.c \

                  ps3-head.S ps3-hvcall.S ps3.ctreeboot-bamboo.c cuboot-8xx.c \

                  cuboot-pq2.c cuboot-sequoia.ctreeboot-walnut.c \

                  cuboot-bamboo.c cuboot-mpc7448hpc2.ccuboot-taishan.c \

                  fixed-head.S ep88xc.c ep405.ccuboot-c2k.c \

                  cuboot-katmai.ccuboot-rainier.c redboot-8xx.c ep8248e.c \

                  cuboot-warp.ccuboot-85xx-cpm2.c cuboot-yosemite.c simpleboot.c \

                  virtex405-head.S virtex.credboot-83xx.c cuboot-sam440ep.c \

                  cuboot-acadia.ccuboot-amigaone.c cuboot-kilauea.c \

                  gamecube-head.S gamecube.cwii-head.S wii.c treeboot-iss4xx.c

#               treeboot-currituck.c

修改完成后继续编译,如果不出意外的话第一次编译顺利完成。此步骤的作用是确保所选用的内核代码可以顺利编译完成,便于后续继续开展移植修改工作。

移植工作第三步:选择芯片的dts配置文件

在Linux2.6内核以来,基于PowerPC芯片的开发引入了dts,相关内容可以自己到网上查找相关资料学习,很多与PowerPC芯片相关(Flash、SOC、中断配置、网口配置)内容都需要在对应的dts文件中进行配置。由于自己手头上有基于Linux2.6.29内核版本下对应芯片的dts文件,可以直接拷贝过来,我直接就修改了/linux-3.4.5/arch/powerpc/boot/dts/ep88xc.dts:

                  ranges = <

                          0x0 0x0 0xfc0000000x1000000    //指定Flash起始地址,容量信息 16M

                          0x4 0x0 0xfa0000000x1000000    //指定SDRAM起始地址,容量信息64M

                  >;

                  flash@0,1000000 {

                     #address-cells= <1>;

                          #size-cells =<1>;


                          compatible ="cfi-flash";

                          reg = <0x00x0000000 0x1000000>;  //指定Flash大小

                          bank-width =<2>;

                          device-width =<2>;

            partition@0 {

                                   label ="uboot";

                                   reg =<0x000000 0x0080000>;

                   read-only;

                          };

                          partition@80000 {

                                   label ="kernel";

                                   reg =<0x0080000 0x0180000>;

                read-only;

                          };

                          partition@280000 {

                                   label ="initrd";

                                   reg =<0x00200000 0x0480000>;

                   read-only;

                          };

                          partition@700000 {

                                   label ="user";

                  reg = <0x00680000 0x980000>;  

                          };

                  };

在该dts文件中指定了Flash的大小,Flash分区信息,其实大家可以阅读下该文件的内容,可以发现网口的信息也需要配置,开发过程中很多驱动需要用到的中断信息也需要在此文件中进行添加,如此就不一一详细列举。

移植工作第四步:修改关于MPC880芯片相关配置内容(具体修改内容要结合实际硬件)

我的移植过程中修改了/linux-3.4.5/arch/powerpc/boot/cuboot-8xx.c文件(时钟控制),/linux-3.4.5/arch/powerpc/platforms/8xx/ep88xc.c(增加内存控制相应内容)、/linux-3.4.5/arch/powerpc/sysdev/cpm1.c(CPM控制器相关配置),修改完成后直接编译完成后下到板上进行测试。

幸运的是此时Linux内核可以正常启动,顺利地看到以下信息:

U-Boot 2010.09(Jul 18 2012 - 12:38:19)

 

Uboot Version: V4.0.1.

Uboot For Kernel:Linux-3.4.5

 

CPU:   MPC885ZPnn at 132.779 MHz [40.0...133.0 MHz]

8 kB I-Cache 8 kB D-Cache FEC present

DRAM:  64 MB

FLASH: 16 MB

In:    serial

Out:   serial

Err:   serial

Net:   FEC, FEC2

autoboot in 2seconds (stop with 'c')...

## Booting kernelfrom Legacy Image at fc080000 ...

   Image Name:  Linux-3.4.5

   Image Type:  PowerPC Linux Kernel Image (gzip compressed)

   Data Size:   1363256 Bytes = 1.3 MB

   Load Address: 00400000

   Entry Point: 0040056c

   Verifying Checksum ... OK

## Loading initRamdisk from Legacy Image at fc280000 ...

   Image Name:  Ram disk

   Image Type:  PowerPC Linux RAMDisk Image (gzip compressed)

   Data Size:   4631202 Bytes = 4.4 MB

   Load Address: 00000000

   Entry Point: 00000000

   Verifying Checksum ... OK

   Uncompressing Kernel Image ... OK

   Loading Ramdisk to 0373f000, end 03ba9aa2 ... OK

Memory <-<0x0 0x4000000> (64MB)

ENET0:local-mac-address <- 00:30:bf:01:02:d2

ENET1:local-mac-address <- 0f:f0:cf:f0:69:6e

CPUclock-frequency <- 0x7ea0aa1 (133MHz)

CPUtimebase-frequency <- 0x3f5055(4MHz)

 

zImage starting:loaded at 0x00400000 (sp: 0x03baabb8)

Allocating0x2befec bytes for kernel ...

gunzipping(0x00000000 <- 0x0040d000:0x006f94e8)...done0x2a8f80 bytes

Using loadersupplied ramdisk at 0x3789000-0x3bc7aa2

initrd head: 0x1f8b0808

 

Linux/PowerPCload: root=/dev/ram0 rw init=/linuxrc

但是接下来的问题又大了:

List of allpartitions:

1f00            512 mtdblock0  (driver?)

1f01           2048 mtdblock1  (driver?)

1f02           4608 mtdblock2  (driver?)

1f03           9216 mtdblock3  (driver?)

No filesystemcould mount root, tried:  cramfs

Kernel panic -not syncing: VFS: Unable to mount root fs on unknown-block(31,2)

Call Trace:

[c3027ec0] [c0005a64] show_stack+0x58/0x154 (unreliable)

[c3027f00] [c00236d0] panic+0xc4/0x204

[c3027f50] [c0275d24]mount_block_root+0x274/0x298

[c3027fa0] [c0275f04] prepare_namespace+0x154/0x194

[c3027fc0] [c027536c] kernel_init+0x1a8/0x1c4

[c3027ff0][c000aa18] kernel_thread+0x4c/0x68

Rebooting in 180seconds..

Linux内核无法正常挂载根文件系统,导致Linux内核后续执行出现崩溃。

移植工作第五步:修正根文件系统无法挂载的问题

其实这个问题之前还遇到很多问题,比如说无法正确识别文件分区信息,则只需要在内核配置选项选中以下内容:

DeviceDrivers  --- >

         Memory Technology Device(MTD)support  --- >

                  Mapping drivers for chipaccess  --- >

                          <*>Flash devicein physical memory map based on OF description

而关于根文件系统无法挂载的问题修改起来很简单,我以前制作的根文件系统是ramdisk,现在只需要实现Linux3.4.5内核从ramdisk根文件系统启动成功就行。首先得看一下我制作根文件系统的脚本:

dd if=/dev/zeroof=mpc880rootfs bs=1k count=16384      

mke2fs -m0 -N2000 ./mpc880rootfs

mkdir ramdisk

mount -t ext2 -oloop ./mpc880rootfs ./ramdisk

cp -av rootfSource/*ramdisk

ppc_8xx-strip -sramdisk/lib/lib*

ppc_8xx-strip -sramdisk/lib/security/lib*

ppc_8xx-strip -sramdisk/usr/lib/lib*

umount ramdisk

gzip v9mpc880rootfs

mkimage -n"Ram disk" -A ppc -O linux -T ramdisk -C gzip -d mpc880rootfs.gz rootfs.bin

脚本的具体内容就不做解释了,里面要关注到2个问题,2个问题跟根文件系统挂载有关。问题1:ramdisk是一种内存虚拟磁盘技术,实质上并不是一种文件系统,它使用的文件系统是ext2文件系统,所以我们在配置Linux3.4.5内核配置选项时,一定要选择对ext2文件系统的支持。

File systems  --- >

         <*>Second extended fs support

问题2:在dd if=/dev/zero of=mpc880rootfs bs=1kcount=16384这个语句中,告诉我们创建的ramdisk文件空间大小是16384*1k,因此我们在配置对Default RAM disk size kbytes时选择的大小应该为16384。

DeviceDrivers  --- >

         [*]Block devices  --- >

                  <*>RAM block device support

                  (16384) Default RAM disk size(kbytes)

光解决上述2个问题还是不够的,需要注意到前面的打印信息,uboot需要将Linux内核启动参数传递给Linux内核--Linux/PowerPCload: root=/dev/ram0 rw init=/linuxrc内核启动打印会上述信息,由于我选择的是ramdisk作为根文件系统启动,因此需要修改uboot软件,重新制定uboot传递的信息内容,具体传递的启动信息内容格式如下:

initrd=xxxx(ramdisk启动地址),zzzz(ramdisk大小) root=/dev/ram rwinit=/linuxrc

ramdisk的启动地址和大小信息,在Linux内核启动时可以看到,修改好uboot软件后重新编译,并将修改编译好的内容下到板上,复位启动,哈哈。。。linux-3.4.5内核移植完成!!

U-Boot 2010.09(Jul 18 2012 - 12:38:19)

 

Uboot Version: V4.0.1.

Uboot For Kernel:Linux-3.4.5

 

CPU:   MPC885ZPnn at 132.779 MHz [40.0...133.0 MHz]

       8 kB I-Cache 8 kB D-Cache FEC present

DRAM:  64 MB

FLASH: 16 MB

In:    serial

Out:   serial

Err:   serial

Net:   FEC, FEC2

autoboot in 2seconds (stop with 'c')...

## Booting kernelfrom Legacy Image at fc080000 ...

   Image Name:  Linux-3.4.5

   Image Type:  PowerPC Linux Kernel Image (gzip compressed)

   Data Size:   1363256 Bytes = 1.3 MB

   Load Address: 00400000

   Entry Point: 0040056c

   Verifying Checksum ... OK

## Loading initRamdisk from Legacy Image at fc280000 ...

   Image Name:  Ram disk

   Image Type:  PowerPC Linux RAMDisk Image (gzip compressed)

   Data Size:   4631202 Bytes = 4.4 MB

   Load Address: 00000000

   Entry Point: 00000000

   Verifying Checksum ... OK

   Uncompressing Kernel Image ... OK

   Loading Ramdisk to 0373f000, end 03ba9aa2 ... OK

Memory <-<0x0 0x4000000> (64MB)

ENET0:local-mac-address <- 00:30:bf:01:02:d2

ENET1:local-mac-address <- 0f:f0:cf:f0:69:6e

CPUclock-frequency <- 0x7ea0aa1 (133MHz)

CPUtimebase-frequency <- 0x3f5055(4MHz)

 

zImage starting:loaded at 0x00400000 (sp: 0x03baabb8)

Allocating0x2befec bytes for kernel ...

gunzipping(0x00000000 <- 0x0040d000:0x006f94e8)...done0x2a8f80 bytes

Using loadersupplied ramdisk at 0x3789000-0x3c79aa2

initrd head: 0x1f8b0808

 

Linux/PowerPCload: initrd=0xC3789000, 0x004677BB root=/dev/ram rw init=/linuxrc

Finalizing devicetree... flat tree at 0x728220

Using EmbeddedPlanet EP88xC machine description

Linux version 3.4.5(root@Kevin Liu) (gcc version 4.2.2) #9 Wed Jul 18 15:41:08 CST 2012

Found initrd at0xc373f000:0xc3ba9aa2

Zone PFN ranges:

  DMA     0x00000000 -> 0x00004000

  Normal  empty

Movable zonestart PFN for each node

Early memory PFNranges

    0: 0x00000000 -> 0x00004000

MMU: Allocated 72bytes of context maps for 16 contexts

Built 1 zonelistsin Zone order, mobility grouping on. Total pages: 16256

Kernel commandline: initrd=0xC3789000,0x004677BB root=/dev/ram rw init=/linuxrc

PID hash tableentries: 256 (order: -2, 1024 bytes)

Dentry cache hashtable entries: 8192 (order: 3, 32768 bytes)

Inode-cache hashtable entries: 4096 (order: 2, 16384 bytes)

Memory:57352k/65536k available (2744k kernel code, 8184k reserved, 116k data, 90k bss,108k init)

Kernel virtualmemory layout:

  * 0xfffdf000..0xfffff000  : fixmap

  * 0xfde00000..0xfe000000  : consistent mem

  * 0xfddf6000..0xfde00000  : early ioremap

  * 0xc5000000..0xfddf6000  : vmalloc & ioremap

SLUB:Genslabs=14, HWalign=16, Order=0-3, MinObjects=0, CPUs=1, Nodes=1

NR_IRQS:512nr_irqs:512 16

DecrementerFrequency = 0x7ea0aa

clocksource:timebase mult[788054df] shift[24] registered

console [ttyCPM0]enabled

pid_max: default:4096 minimum: 301

Mount-cache hashtable entries: 512

NET: Registeredprotocol family 16

bio: create slab<bio-0> at 0

Switching toclocksource timebase

FS-Cache: Loaded

NET: Registeredprotocol family 2

IP route cachehash table entries: 1024 (order: 0, 4096 bytes)

TCP establishedhash table entries: 2048 (order: 2, 16384 bytes)

TCP bind hashtable entries: 2048 (order: 1, 8192 bytes)

TCP: Hash tablesconfigured (established 2048 bind 2048)

TCP: reno registered

NET: Registeredprotocol family 1

RPC: Registerednamed UNIX socket transport module.

RPC: Registeredudp transport module.

RPC: Registeredtcp transport module.

RPC: Registeredtcp NFSv4.1 backchannel transport module.

Trying to unpackrootfs image as initramfs...

rootfs image is notinitramfs (no cpio magic); looks like an initrd

Freeing initrdmemory: 4524k freed

jffs2: version2.2. (NAND) 漏 2001-2006 RedHat, Inc.

msgmni has beenset to 120

io scheduler noopregistered

io schedulerdeadline registered (default)

fa200a80.serial: ttyCPM0 at MMIO 0xc5064a80 (irq = 19) is a CPM UART

brd: moduleloaded

fc000000.flash:Found 1 x16 devices at 0x0 in16-bit bank. Manufacturer ID 0x000089 Chip ID 0x000018

Intel/SharpExtended Query Table at 0x0031

Intel/SharpExtended Query Table at 0x0031

Using bufferwrite method

cfi_cmdset_0001:Erase suspend on write enabled

4 ofpartpartitions found on MTD device fc000000.flash

Creating 4 MTDpartitions on "fc000000.flash":

0x000000000000-0x000000080000: "uboot"

0x000000080000-0x000000280000: "kernel"

0x000000280000-0x000000700000: "initrd"

0x000000700000-0x000001000000: "user"

eth0: fs_enet:00:30:bf:01:02:d2

eth1: fs_enet:00:3b:f5:21:69:6e

FEC MII Bus:probed

mdio_busfa200e00: error probing PHY at address 2

rtc-genericrtc-generic: rtc core: registered rtc-generic as rtc0

i2c /dev entries driver

TCP: cubicregistered

NET: Registeredprotocol family 17

rtc-genericrtc-generic: setting system clock to 1970-01-28 10:51:28 UTC (2371888)

RAMDISK: gzipimage found at block 0

VFS: Mounted root(ext2 filesystem) on device 1:0.

Freeing unusedkernel memory: 108k freed

Failed to execute/linuxrc.  Attempting defaults...

    内核移植当天就完成了,似乎很顺利呀,用于驱动也顺便重新编译,下到板上还跑了些用户程序,一切都很OK!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值