根文件系统移植之NFS启动bootloader的设置

时间:2022-12-18 13:54:24

前言:再次吐槽下飞凌的支持,就两字–“坑爹”。

修改路程:

看飞凌的资料没有这方面的介绍,一般网上搜到的资料做NFS文件系统时利用的bootloader都是u-boot,因为它可以使用setenv bootargs root命令设置启动参数。飞凌自带的bootloader是否可以呢???好吧,太伤人了,什么说明都没有,问他们也不说还要我去CALL,E-MAIL,这要是能说清楚就见鬼了(后来发现QQ上就几句话的事就能OK了)。我试着更改linux内核的启动参数如下:

anzyelay@ubuntu:linux-2.6.35.4-2440$ vi .config +/CONFIG_CMDLINE 

更改CONFIG_CMDLINE

398 CONFIG_ZBOOT_ROM_TEXT=0x0
399 CONFIG_ZBOOT_ROM_BSS=0x0
400 CONFIG_CMDLINE=”console=ttySAC0,115200 root=/dev/nfs nfsroot=192.168.1.225: /home/anzyelay/Desktop/rootfs ip=192.168.1.15:::::eth0”
401 # CONFIG_CMDLINE_FORCE is not set
402 # CONFIG_XIP_KERNEL is not set
403 # CONFIG_KEXEC is not set

重启linux还是

+————————————————————+
| [0] Download & Run |
| [1] Download to flash |
| [2] Download From UART |
| [3] Boot My Application |
| [4] Boot Linux |
| [5] Boot Wince |
| [6] Erase Flash Partition |
| [7] Config parameters |
+————————————————————+
NAND ID is 0xecda
Set boot params = root=/dev/mtdblock3 init=/linuxrc load_ramdisk=0 console=ttyS0
Load Kernel…

又被bootloader自动设置了.
于是做好的文件系统只能下载去验证了,搞了两次就不能忍了,于是悲催的移植U-boot开始了,可是移植完到要下载验证时完了,没有下载u-boot的工具呀,直接用飞凌的bootloader利用USB下载?要是移植的有问题这开发板不就成砖了吗?只有一次机会,我冒不起这风险,只好看起了FL的bootloader源码来grep ‘Set boot params’ ,发现了下面的东东:
在文件nand.c中

static void LoadRun(void)
{
    U32 i, ram_addr, buf = 0x30200000;//boot_params.run_addr.val;
    struct param_struct *params = (struct param_struct *)0x30000100;
    struct Partition *nf_part;
    int size;
    memset(params, 0, sizeof(struct param_struct));
    if(1/*boot_params.start.val*/) {
        char parameters[512];
        char *rootfs;
        char initrd[32];
        char *tty_sel;
        char *devfs_sel;
        char *display_sel;

        switch (boot_params.root_sel.val) {
        case 0:
            rootfs = "/dev/ram";
            break;
        case 1:
            rootfs = "nfs";
            break;
        case 2:
            rootfs = "/dev/mtdblock2"; // by pht.
            break;
        case 3:
            rootfs = "/dev/mtdblock3";
            break;
        case 4:
            rootfs = "/dev/mtdblock4";
            break;
        default:
            rootfs="";  //user define
            break;
        }

        switch (boot_params.display_sel.val) {
        case 0:
            display_sel = "display=sam320";
            break;
        case 1:
            display_sel = "display=vga640";
            break;
        case 2:
            display_sel = "display=vga800";
            break;          
        case 3:
            display_sel = "display=qch800";
            break;  
        case 4:
            display_sel = "display=lcd480";
            break;  

        default:
            display_sel = "display=sam640"; 
            break;
        }
        if(boot_params.root_sel.val)
            sprintf(initrd, "load_ramdisk=0");
        else
            sprintf(initrd, "initrd=0x%08x,0x%08x",
                        boot_params.initrd_addr.val,
                        boot_params.initrd_len.val);

        switch (boot_params.tty_sel.val) {
        case 0:
            tty_sel="ttySAC0";
            break;
        case 1:
            tty_sel="ttySAC1";
            break;
        case 2:
            tty_sel="ttyS0";
            break;
        case 3:
            tty_sel="ttyS1";
            break;
        case 4:
            tty_sel="tty0";
            break;
        default:
            tty_sel="ttySAC0";  //user define
            break;
        }
        devfs_sel = "devfs=mount";  
        memset(parameters, 0, sizeof(parameters));
        sprintf(parameters,
                    "root=%s init=/linuxrc %s console=%s,%d mem=%dK %s %s %s",
                    rootfs,
                    initrd,
                    tty_sel,
                    boot_params.serial_baud.val,
                    boot_params.mem_cfg.val>>10,
                    devfs_sel,
                    display_sel,
                    boot_params.string);

        params->u1.s.page_size = LINUX_PAGE_SIZE;
        params->u1.s.nr_pages = (boot_params.mem_cfg.val >> LINUX_PAGE_SHIFT);
        memcpy(params->commandline, parameters, strlen(parameters));

        printf("Set boot params = %s\n", params->commandline);
    }

    printf("Load Kernel...\n"); 

苦心人天不负啊!!,这不就是在设置启动参数么,找下boot_params的定义和结构如下:

BootParams boot_params = {
    {"auto-run", 3},    //0=boot without parameters,1=boot with parameters
    //{"cpuclk", 2}, //0=200M, 1=300M, 2=400M, 3=440M
    {"rundelay", 0},    //0 seconds
    {"serial",   0},    //0=serial port 0, 1=serial port 1
    {"AppRunAddr",   0x32000000},
    {"baudrate", 115200},
    {"machine",  193},
    {"runAddr",  0x30201000},
    {"rootfs",   3},
    {"tty",      0},
    {"displayS",  0},   //0=320*240 1=640*480 2 = 800*600
    {"displayM",  0},   //0= lcd 1=vga 2=tv
    {"initrdA",  0x30200000},
    {"initrdL",  0x02000000},
    {"memsize",  0x04000000},
    //{"devfs", 1},
    //{"ostore", 0}, //0=nand, 1=nor
    {"userpara", sizeof(DEFAULT_USER_PARAMS)},
    DEFAULT_USER_PARAMS,
    {0}
};
typedef struct {
    ParamItem start;
    //ParamItem cpu_clk;
    ParamItem boot_delay;
    ParamItem serial_sel;
    ParamItem AppRun_addr;
    ParamItem serial_baud;
    ParamItem machine;
    ParamItem run_addr;
    ParamItem root_sel;
    ParamItem tty_sel;
    ParamItem display_sel;
    ParamItem display_mode;
    ParamItem initrd_addr;
    ParamItem initrd_len;
    ParamItem mem_cfg;
    //ParamItem devfs_sel;
    //ParamItem osstor;
    ParamItem user_params;
    char string[128];
    unsigned int bpage[50];
} BootParams;

看着很眼熟呀,这不是7么

+————————————————————+
| [0] Download & Run |
| [1] Download to flash |
| [2] Download From UART |
| [3] Boot My Application |
| [4] Boot Linux |
| [5] Boot Wince |
| [6] Erase Flash Partition |
| [7] Config parameters |
+————————————————————+

+————————————————————+
| Config parameters |
+————————————————————+
[ 0] auto-run : 0xffffffff (-1)
[ 1] rundelay : 0x00000007 (7)
[ 2] serial : 0x00000000 (0)
[ 3] AppRunAddr : 0x32000000 (838860800)
[ 4] baudrate : 0x0001c200 (115200)
[ 5] machine : 0x000000c1 (193)
[ 6] runAddr : 0x30201000 (807407616)
[ 7] rootfs : 0x00000003 (3)
[ 8] tty : 0x00000000 (0)
[ 9] displayS : 0x00000004 (4)
[10] displayM : 0x00000000 (0)
[11] initrdA : 0x30200000 (807403520)
[12] initrdL : 0x02000000 (33554432)
[13] memsize : 0x04000000 (67108864)
[14] board : 0x00000000 (0)
[15] pic_mode : 0x00000000 (0)
[16] userpara : 0x00000000 (0)
[17] : Exit

偿试修改7选项为如下
[ 7] rootfs : 0x00000007 (7) //让root=”“就行,因为是要设为root=/dev/nfs的,它自认的是 root=nfs 不知道行不行,我没试了
再修改 16选项,选中后输入
root=/dev/nfs nfsroot=192.168.1.221:/home/anzyelay/Desktop
/arm/rootfs ip=192.168.1.15:::::eth0
这里介绍下NFS启动参数设置:
console=ttySAC0 root=/dev/nfs nfsroot=主机IP:/共享目录 ip=开发板IP:主机IP:网关:子网掩码:主机名:网卡:off

ip只填个开发板的IP和网卡就好,其它可以省略,此处开发板IP可以自己随意设,只要与主机IP在同一网段即可。
重启后发现如下:

Set boot params = root= init=/linuxrc load_ramdisk=0 console=ttySAC0,115200 mem=
65536K devfs=mount display=lcd480 root=/dev/nfs nfsroot=192.168.1.221:/home/anzy
elay/Desktop/arm/rootfs ip=192.168.1.115:::::eth0
Load Kernel…

dm9000 dm9000.0: WARNING: no IRQ resource flags set.
eth0: link up, 100Mbps, full-duplex, lpa 0xCDE1
IP-Config: Guessing netmask 255.255.255.0
IP-Config: Complete:
device=eth0, addr=192.168.1.115, mask=255.255.255.0, gw=255.255.255.255,
host=192.168.1.115, domain=, nis-domain=(none),
bootserver=255.255.255.255, rootserver=192.168.1.221, rootpath=
Looking up port of RPC 100003/2 on 192.168.1.221
Looking up port of RPC 100005/1 on 192.168.1.221
VFS: Mounted root (nfs filesystem) on device 0:12.
Freeing init memory: 140K

这就说明成功了


总结:

  1. 设好PC机的NFS配置:

    • 没有NFS就安装,

      sudo apt-get install nfs-kernel-server
      anzyelay@ubuntu:arm$ vi /etc/exports
    • 在/etc/exports尾加入共享目录:

      /共享目录 *(rw,sync,no_root_squash)

    • 重启NFS服务:

      anzyelay@ubuntu:arm$ /etc/init.d/nfs-kernel-server restart 
    • 可以试试能不能正常mount,查看主机IP

  2. 修改bootloader启动参数:

    • 启动开发板进入bootloader

      +————————————————————+
      | Select Menu |
      +————————————————————+
      | [0] Download & Run |
      | [1] Download to flash |
      | [2] Download From UART |
      | [3] Boot My Application |
      | [4] Boot Linux |
      | [5] Boot Wince |
      | [6] Erase Flash Partition |
      | [7] Config parameters |
      +————————————————————+

    • 选7进入参数设置

      +————————————————————+
      | Config parameters |
      +————————————————————+
      [ 0] auto-run : 0xffffffff (-1)
      [ 1] rundelay : 0x00000007 (7)
      [ 2] serial : 0x00000000 (0)
      [ 3] AppRunAddr : 0x32000000 (838860800)
      [ 4] baudrate : 0x0001c200 (115200)
      [ 5] machine : 0x000000c1 (193)
      [ 6] runAddr : 0x30201000 (807407616)
      [ 7] rootfs : 0x00000007 (7)
      [ 8] tty : 0x00000000 (0)
      [ 9] displayS : 0x00000004 (4)
      [10] displayM : 0x00000000 (0)
      [11] initrdA : 0x30200000 (807403520)
      [12] initrdL : 0x02000000 (33554432)
      [13] memsize : 0x04000000 (67108864)
      [14] board : 0x00000000 (0)
      [15] pic_mode : 0x00000000 (0)
      [16] userpara : 0x0000005f (95)
      [17] : Exit

    • 修改7 rootfs参数,大于5都行

    • 修改 16 用户自定义命令,这里是字符串,所以把boot params的其它参数设置好。eg:

      root=/dev/nfs nfsroot=上面查到的主机IP:/共享目录 ip=自行设置同网段可板子IP:::::eth0

  3. OK,启动linux。完


其实这里的其它几个参数也挺有用的,比如

  • [ 5] machine : 0x000000c1 (193)
    这不就是移植内核时要修改的机器码么,如果内核不改就可以改这里的bootloader的机器码,我没试可以偿试,
  • [ 9] displayS : 0x00000004 (4)
  • [10] displayM : 0x00000000 (0)
    这两个用来设置 屏的大小和类型。