嵌入式Linux内核移植实战:从U-Boot到根文件系统的完整流程解析

嵌入式Linux内核移植实战:从U-Boot到根文件系统的完整流程解析

1. 项目概述与核心价值

折腾嵌入式Linux,尤其是给一块老旧的开发板做内核移植,这事儿听起来像是考古,但其中的门道和踩坑经验,对理解整个嵌入式系统的启动流程、硬件抽象层以及内核配置,有着不可替代的价值。今天要聊的,就是把Linux内核搬到Freescale(现NXP)的MPC8260ADS开发板上的全过程。MPC8260这颗芯片,属于经典的PowerQUICC II系列通信处理器,当年在通信网关、网络设备里应用广泛,虽然现在看主频和内存都显得寒酸,但其架构的典型性让它成为了学习PowerPC架构和嵌入式Linux移植的绝佳标本。

为什么非要干这事儿?直接买块树莓派或者i.MX系列开发板不香吗?对于产品开发,当然要选主流、有长期支持的平台。但对于学习和深入理解,从“零”开始让一个复杂的操作系统在裸板上跑起来,这个过程能让你彻底搞明白:计算机上电后第一行代码在哪、内存如何初始化、设备树(或早期的板级支持包)如何描述硬件、内核镜像如何被加载和解压、根文件系统又如何挂载。这些知识,是理解任何现代嵌入式Linux系统的基石。MPC8260ADS板子资源有限(比如文中提到的16MB DRAM,8MB Flash),迫使你必须精打细算,理解每一个配置选项的意义,这种“带着镣铐跳舞”的经历,比在资源丰富的平台上做开发,更能锻炼人。

本文将基于一份经典的Freescale应用笔记,但不止于复现。我会结合自己多次移植不同架构内核的经验,把其中省略的细节补全,把容易踩坑的地方重点标出,并解释每一个步骤背后的“为什么”。目标是让你读完之后,不仅能按照步骤让MPC8260ADS“活”过来,更能理解其背后的原理,具备举一反三的能力,去应对其他平台的移植挑战。整个过程涉及主机开发环境搭建、U-Boot编译与烧写、Linux内核配置与交叉编译、以及通过TFTP和NFS进行调试部署,是一条完整的嵌入式Linux开发流水线。

2. 环境准备与工具链选型

动手之前,得把“厨房”收拾好。嵌入式开发的核心特征就是“交叉编译”:在一台性能强大的主机(通常是x86架构的PC)上,编译出能在目标板(这里是PowerPC架构的MPC8260)上运行的代码。因此,搭建一个稳定、高效的交叉编译环境是第一步,也是后续所有工作的基础。

2.1 主机系统与网络配置

原文提到了Debian和Redhat,现在更普遍的选择是Ubuntu LTS版本(如20.04或22.04),其软件包管理方便,社区支持好。你完全可以在物理机或虚拟机(如VMware、VirtualBox)中安装一个纯净的Ubuntu系统。关键是要保证主机能稳定联网,因为我们需要安装大量开发包和下载源码。

网络配置是第一个关键点。文中示例采用点对点网络,这是实验室环境的典型做法:开发板通过网线直接连接到主机网卡,不经过路由器。你需要为主机和开发板分配同一个网段下的静态IP地址,例如:

  • 主机IP:192.168.1.1
  • 开发板IP:192.168.1.52
  • 子网掩码:255.255.255.0

在Ubuntu上,你可以通过图形界面或修改/etc/netplan/*.yaml文件来配置静态IP。务必确保配置后网络是通的,可以用ping 192.168.1.52(待开发板启动后)测试。

注意:很多新手会忽略防火墙。请确保主机的防火墙(如ufw)放行了后续TFTP、NFS服务所需的端口,或者直接在学习环境中暂时关闭防火墙:sudo ufw disable。否则会出现“能ping通但服务连不上”的诡异问题。

2.2 交叉编译工具链获取与配置

这是核心工具。你需要一个针对PowerPC架构的交叉编译器。原文提到了商业工具如MontaVista,但对于学习和个人项目,我们首选免费开源的工具链。现在最常用的构建工具是crosstool-NG,它可以灵活地定制和编译出所需的工具链。但对于MPC8260(PowerPC 603e核心)这种老平台,更简单的方法是直接寻找预编译好的工具链。

你可以尝试搜索“powerpc-eabi toolchain”或“powerpc-linux-gnu toolchain”。一些旧的嵌入式Linux发行版(如ELDK, Embedded Linux Development Kit)也包含所需工具。假设你找到了一个名为powerpc-linux-gnu-gcc的编译器套件。

  1. 安装工具链:下载后,通常解压到/opt目录下,例如/opt/toolchains/powerpc-linux-gnu。然后,将这个工具的bin目录添加到系统的PATH环境变量中。
  2. 设置环境变量:如原文所述,设置CROSS_COMPILE变量至关重要。这告诉内核和U-Boot的Makefile使用哪个前缀的编译工具。
    export CROSS_COMPILE=powerpc-linux-gnu- export PATH=/opt/toolchains/powerpc-linux-gnu/bin:$PATH
    你可以将这两行添加到~/.bashrc文件中,这样每次打开终端都会自动设置。
  3. 验证工具链:在终端输入powerpc-linux-gnu-gcc --version,如果能看到版本信息,说明安装成功。再输入echo $CROSS_COMPILE,确认输出是powerpc-linux-gnu-

实操心得:工具链的版本要与内核版本大致匹配。例如,编译2.4.x或2.6.x的古老内核,最好使用同时代的gcc 3.x或4.x版本的工具链。使用太新的编译器(如gcc 10+)可能会遇到语法或链接库不兼容的问题。如果遇到奇怪的编译错误,首先怀疑工具链的兼容性。

2.3 必备服务安装:TFTP与NFS

我们的开发流程是:在主机上编译好内核镜像,通过TFTP协议下载到开发板的内存中运行;同时,将根文件系统放在主机上,通过NFS协议让开发板挂载。这样避免了每次修改都要烧写Flash的繁琐过程,极大提升了调试效率。

  1. 安装TFTP服务器:
    sudo apt update sudo apt install tftpd-hpa
    安装后,默认的TFTP根目录通常是/srv/tftp/var/lib/tftpboot。我们按原文习惯,使用/tftpboot。需要创建目录并修改配置:
    sudo mkdir /tftpboot sudo chmod -R 777 /tftpboot # 为了方便,设置宽松权限,生产环境需收紧 sudo sed -i 's|TFTP_DIRECTORY=\".*\"|TFTP_DIRECTORY=\"/tftpboot\"|g' /etc/default/tftpd-hpa sudo systemctl restart tftpd-hpa
    测试TFTP服务:在/tftpboot目录下创建一个测试文件,然后在本机使用tftp客户端尝试获取它。
  2. 安装NFS服务器:
    sudo apt install nfs-kernel-server
    配置NFS导出目录。编辑/etc/exports文件,添加一行(假设我们将为开发板准备的根文件系统放在/tftpboot/nfs_root):
    /tftpboot/nfs_root 192.168.1.52(rw,sync,no_root_squash,no_subtree_check)
    这表示允许IP为192.168.1.52的客户端以读写方式挂载该目录,并且保留root权限。 然后创建目录并重启服务:
    sudo mkdir -p /tftpboot/nfs_root sudo exportfs -av # 使导出配置生效 sudo systemctl restart nfs-kernel-server

3. U-Boot引导加载程序详解与移植

U-Boot是嵌入式领域的“瑞士军刀”,它负责初始化最基础的硬件(如CPU、内存、串口),为加载操作系统内核做好准备。它是硬件上电后第一个跑起来的复杂软件。

3.1 U-Boot源码获取与初步配置

首先,从官方仓库获取U-Boot源码。虽然原文使用0.2.0版本,但我们可以尝试更新的版本(如2016年左右的版本),其对老平台的支持也较好,且修复了许多bug。使用git克隆:

git clone https://source.denx.de/u-boot/u-boot.git cd u-boot # 查看并切换到一个较老但稳定的分支,例如针对MPC8260的提交 git checkout v2016.03 -b mpc8260_work # 这是一个示例,具体版本需查询支持情况

如果找不到合适的新版本分支,那就必须使用老版本。可以下载源码包,如u-boot-0.2.0.tar.bz2,然后解压。

接下来是关键步骤:为MPC8260ADS板子配置U-Boot。U-Boot支持大量的开发板,每个板子都有一个对应的配置项。通常,配置名格式为<board_name>_config。我们需要在U-Boot源码目录中执行:

make MPC8260ADS_config

这个命令会根据boards.cfgMakefile中的定义,找到MPC8260ADS对应的板级配置目录(通常是board/freescale/mpc8260ads),并设置好编译所需的环境变量。

注意事项:执行配置命令前,务必确认当前终端环境中CROSS_COMPILE变量已正确设置。否则,配置过程可能会失败或错误地使用主机本地编译器。

3.2 U-Boot编译与关键文件解析

配置完成后,执行make all进行编译。编译过程会调用交叉编译器,生成多个重要文件:

  • u-boot.bin: 原始的二进制镜像,可以直接烧写到Flash的特定地址。
  • u-boot.srec: S-Record格式的镜像,是一种包含地址信息的ASCII文本格式,许多烧写工具(尤其是通过JTAG的编程器)更偏好这种格式。
  • u-boot: ELF格式的可执行文件,包含调试信息,用于仿真调试。
  • u-boot.map: 内存映射文件,记录了所有符号的地址,对分析问题非常有帮助。

编译成功与否,是验证交叉编译环境是否正常工作的第一道关卡。如果出现“找不到命令”错误,检查CROSS_COMPILE路径;如果出现语法错误,可能是工具链版本太新,需要尝试降级或为老代码打补丁。

3.3 U-Boot烧写与串口通信

得到u-boot.srecu-boot.bin后,需要将其烧写到开发板的Flash中。原文使用Macraigor OCD Flash Programmer通过JTAG烧写,这是最底层、最可靠的方式,但需要专门的硬件调试器(如J-Link、DAPLink配合OpenOCD软件,或商业工具)。

对于没有JTAG调试器的情况,如果板子上已有旧版本的U-Boot在运行,则可以通过该U-Boot自身的网络或串口命令来更新自己。例如,通过tftp命令将新的u-boot.bin下载到内存,然后用protect offerasecp.b等命令写Flash。但这操作有风险,一旦断电或出错,板子可能“变砖”,必须谨慎。

烧写完成后,连接串口线(USB转TTL或主机原生串口)到MPC8260ADS的调试串口(通常是RS232-1)。在主机上使用minicom或更现代的picocomscreen工具进行连接:

sudo picocom -b 115200 /dev/ttyUSB0 # 根据实际串口设备调整

上电后,你应该在终端看到U-Boot的启动日志,并出现=>提示符。此时可以输入printenv查看环境变量,help查看所有命令。

踩坑记录:串口连接最常见的两个问题:1) 波特率不对(MPC8260ADS通常为115200);2) 流控(Flow Control)需要关闭(RTS/CTS设为No)。在minicom的配置中(Ctrl+A, Z -> O -> Serial port setup)务必确认这些参数。

4. Linux内核配置、裁剪与编译

让U-Boot跑起来只是万里长征第一步,核心任务是让Linux内核在目标板上安家。

4.1 内核源码获取与版本选择

从 kernel.org 或镜像站下载内核源码。对于MPC8260这种老硬件,选择2.4.x或2.6.x的稳定版本是合适的,因为其驱动支持相对成熟。例如linux-2.6.32.tar.xz是一个长期支持版本。解压后进入源码目录。

4.2 内核配置详解:make menuconfig

这是移植过程中最体现功力的环节。运行make menuconfig(或make xconfig)会进入一个图形化(或文本菜单)配置界面。我们需要为PowerPC架构和MPC8260ADS具体型号进行配置。

  1. 选择架构和平台:

    • 首先执行make mrproper清理旧配置。
    • make menuconfig中,首要任务是设置正确的架构。这通常通过源码目录下的arch/powerpc/configs中的默认配置文件来指定。对于MPC8260ADS,可能需要寻找类似mpc8260ads_defconfig的文件。如果存在,可以直接运行make mpc8260ads_defconfig来加载一个基础配置。如果没有,可能需要从相近的配置(如pmac32_defconfig)开始修改。
    • menuconfig的顶层,确保Platform选项选择了Freescale系列,并在子选项中找到MPC8260ADSMPC8260的支持。
  2. 关键驱动配置:

    • 串口驱动:这是调试的生命线。确保Character devices -> Serial drivers下,MPC8260的SCC串口驱动(可能是CPM SCC Serial port support)被编译进内核(*),而不是模块(M)。
    • 网络驱动:MPC8260ADS通常使用FCC(Fast Communications Controller)作为以太网控制器。在Network device support -> Ethernet (10 or 100Mbit)下,找到并启用对应的FCC以太网驱动。
    • MTD与Flash驱动:如果要支持从板载Flash启动,需要配置MTD子系统。在Memory Technology Devices (MTD)下,启用对板载Flash芯片型号(如LH28F016SCT)的支持,以及对应的CFI驱动。
    • 根文件系统支持:我们初期使用NFS挂载根文件系统,所以必须在内核中启用Network File Systems -> NFS client support,以及Root file system on NFS。同时,为了后续支持从Flash中的文件系统(如JFFS2)启动,也可以预先配置好Journalling Flash File System v2 (JFFS2) support
    • 内核调试:Kernel hacking中,可以启用Kernel low-level debugging functionsEarly printk。这在内核启动初期、串口驱动尚未完全初始化时,能输出调试信息,是排查启动死机问题的利器。
  3. 内核裁剪原则:嵌入式系统资源紧张,必须裁剪掉不需要的功能。基本原则是:不确定的,先不选;用不到的,坚决不选。优先将驱动编译为模块(M)而非内置(*),可以减小初始内核镜像大小。但像串口、网络、MTD这些启动必须的,一定要内置。

4.3 内核编译与镜像生成

配置完成后,依次执行:

make clean # 清理旧编译产物 make dep # 建立依赖关系(2.4内核需要,2.6以后通常不需要此步骤) make zImage # 生成压缩的内核镜像

对于PowerPC架构,编译生成的最终内核镜像路径通常在arch/powerpc/boot/下。可能是zImage,也可能是uImageuImage是U-Boot专属的格式,它在zImage前面加了一个64字节的U-Boot头,包含了加载地址、入口点、压缩类型等信息。

如果编译产出的是zImage,我们需要使用U-Boot工具mkimage来将其转换为uImage。这个工具在U-Boot源码的tools/目录下。编译U-Boot后,它就会被生成。

# 假设在U-Boot源码目录下 ./tools/mkimage -A ppc -O linux -T kernel -C gzip -a 0 -e 0 -n "Linux-2.6.32 for MPC8260ADS" -d /path/to/your/linux/arch/powerpc/boot/zImage /tftpboot/uImage.mpc8260

参数解释:

  • -A ppc: 架构是PowerPC。
  • -O linux: 操作系统是Linux。
  • -T kernel: 镜像类型是内核。
  • -C gzip: 压缩方式是gzip。
  • -a 0: 加载地址为0。这里是个关键点!对于PowerPC架构,内核通常被加载到物理内存的起始地址(如0x0)。但具体地址必须与U-Boot的bootm命令期望的地址,以及内核自身链接的地址一致。这需要查阅MPC8260ADS的内存映射和U-Boot的默认配置。一个常见的地址是0x100000(1MB处)。如果设置错误,内核将无法启动。务必根据你的板级支持和U-Boot环境变量loadaddr来设置
  • -e 0: 入口点地址为0。对于压缩内核,入口点通常是加载地址。对于非压缩内核,是内核解压后的入口。
  • -n: 给镜像起个名字。
  • -d: 指定输入的内核镜像文件。
  • 最后是输出文件路径,我们放到TFTP目录下。

5. 系统集成:引导参数、根文件系统与启动

有了U-Boot和内核镜像,还需要告诉内核去哪里找它的“家”——根文件系统。

5.1 配置U-Boot环境变量

在U-Boot命令行中,我们需要设置几个关键的环境变量,它们构成了启动参数:

=> setenv serverip 192.168.1.1 # TFTP服务器的IP地址 => setenv ipaddr 192.168.1.52 # 开发板自身的IP地址 => setenv bootfile uImage.mpc8260 # 要下载的内核镜像文件名 => setenv loadaddr 0x100000 # 内核加载到内存的地址(必须与mkimage的-a参数及内核链接地址匹配!) => setenv bootargs root=/dev/nfs rw nfsroot=192.168.1.1:/tftpboot/nfs_root ip=192.168.1.52:192.168.1.1:192.168.1.254:255.255.255.0 console=ttyS0,115200 init=/bin/sh

bootargs的解释:

  • root=/dev/nfs: 指定根文件系统通过NFS挂载。
  • rw: 以读写方式挂载。
  • nfsroot=192.168.1.1:/tftpboot/nfs_root: 指定NFS服务器的IP和共享的目录路径。
  • ip=192.168.1.52:192.168.1.1:192.168.1.254:255.255.255.0: 这是内核命令行格式的IP配置(客户端IP:服务器IP:网关:子网掩码)。
  • console=ttyS0,115200: 指定控制台为第一个串口,波特率115200。这是内核打印信息的地方。
  • init=/bin/sh: 指定内核启动后执行的第一个程序是/bin/sh(shell),而不是默认的/sbin/init。这在调试初期非常有用,可以快速得到一个命令行。

设置好后,使用saveenv命令将这些变量保存到Flash中,下次上电会自动加载。

5.2 构建最小根文件系统

现在,我们需要在主机上的/tftpboot/nfs_root目录下,创建一个最小的、能让内核启动的根文件系统。至少需要以下内容:

  1. 基本目录结构:bin,sbin,etc,lib,proc,sys,tmp,var,dev。使用mkdir创建。
  2. 创建设备节点:dev目录下,需要创建必要的设备文件。最简单的方法是复制主机/dev下的consolettyS0,但要注意权限。更规范的做法是使用mknod命令静态创建,或者在内核启动后使用udevmdev动态创建。对于最小系统,可以静态创建:
    sudo mknod -m 622 /tftpboot/nfs_root/dev/console c 5 1 sudo mknod -m 666 /tftpboot/nfs_root/dev/null c 1 3
  3. BusyBox——嵌入式瑞士军刀:手动编译所有命令行工具(ls,cp,mount,sh等)是灾难。BusyBox将数百个常用工具集成进一个可执行文件,通过符号链接来调用,极大地节省了空间。这正是原文提到的。
    • 下载BusyBox源码,解压。
    • 进入目录,执行make menuconfig
    • Settings -> Build Options中,指定交叉编译器前缀CONFIG_CROSS_COMPILER_PREFIX="powerpc-linux-gnu-"
    • Settings -> Installation Options中,选择BusyBox installation prefix为你的/tftpboot/nfs_root路径。
    • 选择你需要的工具(Coreutils,Shells,Linux System Utilities等)。
    • 执行make -j4编译,然后make install。BusyBox就会把二进制文件和所有符号链接安装到/tftpboot/nfs_root目录下。
  4. 初始化脚本(可选但推荐):创建一个最简单的/tftpboot/nfs_root/etc/init.d/rcS文件,并赋予可执行权限。里面可以挂载procsys文件系统:
    #!/bin/sh mount -t proc proc /proc mount -t sysfs sysfs /sys
    然后在/tftpboot/nfs_root/etc/inittab(如果BusyBox配置了使用inittab)中添加一行:::sysinit:/etc/init.d/rcS

5.3 启动!从U-Boot到Linux Shell

万事俱备,开始启动:

  1. 确保主机TFTP目录下有uImage.mpc8260,NFS共享的nfs_root目录已准备好。
  2. 开发板串口连接好,启动U-Boot。
  3. 在U-Boot提示符下,输入bootm命令(如果设置了bootcmd环境变量为tftpboot; bootm,则直接输入boot即可)。
  4. U-Boot会通过TFTP协议,从serverip指定的主机下载bootfile指定的镜像到loadaddr指定的内存地址。
  5. 下载完成后,bootm命令会校验镜像头,然后根据头信息将内核解压(如果是压缩格式)并跳转到入口点执行。
  6. 内核开始启动,你会看到大量的内核日志从串口输出。它会解析bootargs,尝试挂载NFS根文件系统。
  7. 如果一切顺利,最后你会看到类似Please press Enter to activate this console或直接出现/ #的shell提示符。

恭喜!Linux内核已经在你的MPC8260ADS开发板上运行起来了。你可以执行ls,cat /proc/cpuinfo等基本命令来验证系统。

6. 问题排查与实战经验分享

移植过程极少一帆风顺,以下是几个最常见的问题及排查思路:

6.1 常见启动失败问题速查表

现象可能原因排查步骤
U-Boot无法启动,无串口输出1. 供电问题
2. 串口线连接错误或波特率不对
3. Flash中U-Boot镜像损坏或烧写地址错误
4. 硬件故障
1. 检查电源指示灯。
2. 确认串口号(/dev/ttyUSB0?)、波特率(115200)、流控(关闭)。
3. 尝试重新烧写U-Boot,确认烧写工具配置的Flash型号和起始地址正确。
4. 测量时钟、复位信号。
U-Boot能启动,但tftpboot失败1. 网络物理连接不通
2. IP地址设置错误
3. 主机防火墙阻止TFTP
4. TFTP服务器未运行或目录权限问题
1. 检查网线、指示灯。
2. 在U-Boot中用ping命令测试与主机的连通性。
3. 关闭主机防火墙或开放69端口。
4. 检查tftpd-hpa服务状态,确认/tftpboot目录存在且权限可读。
tftpboot成功,但bootm失败1.loadaddr设置错误
2. 内核镜像格式不对(非uImage)
3. 内核镜像损坏
4. 内核编译的架构与板子不匹配
1. 核对mkimage时的-a参数与U-Boot的loadaddr是否一致。
2. 使用mkimage -l uImage.mpc8260检查镜像头信息。
3. 重新编译并生成镜像。
4. 确认内核配置选择了正确的CPU类型和平台。
内核开始解压/运行后卡死或无输出1. 内核启动参数bootargs错误,特别是控制台console=
2. 内存初始化参数错误(如大小、bank设置)
3. 内核中缺少关键驱动(如串口)
4. 机器ID(Machine ID)不匹配
1. 检查console=参数指定的串口设备名是否正确(ttyS0,ttyS1?)。
2. 检查U-Boot传递给内核的mem=参数(如果有),或检查内核中配置的内存大小。
3. 确保串口驱动被编译进内核(*),而不是模块。
4. 对于老内核,可能需要确认U-Boot传递的bd_info结构或machine ID与内核期望的一致。这可能需要修改U-Boot源码或内核板级文件。
内核报错“VFS: Unable to mount root fs”1. NFS服务器未配置或未启动
2.bootargsnfsroot=路径错误
3. 内核未启用NFS客户端支持
4. 网络未初始化成功
1. 检查主机/etc/exports配置,重启nfs-kernel-server,用showmount -e查看。
2. 确认nfsroot=中的IP和路径完全正确,且主机该路径存在且包含有效的根文件系统。
3. 在内核配置中确认Network File Systems -> NFS client supportRoot file system on NFS已启用。
4. 查看内核启动日志中网络驱动的初始化是否成功,IP配置是否生效。

6.2 高级调试技巧

  1. 利用U-Boot进行内存和寄存器调试:在U-Boot中,可以使用md(显示内存)、mm(修改内存)、mw(写内存)等命令检查特定内存地址的内容。cp命令可以测试内存读写。这对于验证内存初始化是否正确非常有用。
  2. 启用内核早期打印(Early Printk):在内核配置中启用Early printk,它会在串口驱动完全初始化之前,通过一个最底层的输出函数打印信息,对于定位内核启动非常早期的崩溃(如解压后、内存管理初始化前)至关重要。
  3. 分析系统日志:内核启动时,关注以下几个关键节点的日志:CPU型号识别、内存检测大小、命令行参数解析、设备树(或ATAG)处理、各子系统初始化、网络设备注册、最后是挂载根文件系统。任何一步的警告(Warning)或错误(Error)都可能是线索。
  4. 简化问题:如果问题复杂,尝试退回到最简配置。例如,先不用NFS,尝试使用initramfs(一个编译进内核的微型根文件系统)来启动,排除网络和NFS的问题。或者,先注释掉bootargs中的init=,让内核尝试执行默认的/sbin/init,看错误信息是否变化。

6.3 从NFS到本地Flash启动的进阶

通过NFS挂载根文件系统是完美的开发调试方式。但产品最终需要从本地存储(如Flash)启动。这通常意味着:

  1. 制作可烧写的文件系统镜像:使用genext2fsmkfs.jffs2等工具,将nfs_root目录下的内容制作成一个文件系统镜像(如rootfs.jffs2)。
  2. 烧写镜像到Flash:在U-Boot中,通过TFTP将rootfs.jffs2下载到内存,然后使用Flash擦写命令将其烧写到Flash的特定分区(例如,从0x400000开始)。
  3. 修改启动参数:bootargs中的root=/dev/nfs改为root=/dev/mtdblock2(假设文件系统在第二个MTD分区),并移除NFS相关参数。
  4. 配置内核支持对应的MTD和文件系统:确保内核编译了对应的Flash驱动、MTD块设备驱动以及JFFS2文件系统支持。

这个过程需要对Flash的分区布局有清晰规划,并且要处理好在Flash上读写文件系统的磨损均衡等问题(对于JFFS2这类日志文件系统,内核会自动处理)。

移植Linux内核到一块具体的开发板,就像为一位客人精心准备一个家。你需要了解客人的习性(CPU架构),准备好坚固的地基(U-Boot),搭建好主体框架(Linux内核),并布置好生活设施(根文件系统)。每一步的错漏都可能导致“客人”无法入住。MPC8260ADS这个案例虽然硬件已老,但流程经典,覆盖了嵌入式Linux移植的几乎所有核心概念和技能点。通过这次实践,你收获的不仅仅是一块能跑Linux的板子,更是一套应对未来任何嵌入式Linux移植挑战的方法论和排错能力。当串口终端上第一次出现那个熟悉的#提示符时,那种成就感,就是嵌入式开发的乐趣所在。