精华内容
下载资源
问答
  • 1、今天在调试freescale开发板,因为其他同事用过拿到手后就出现以下问题。 VFS: Cannot open root device "mmcblk0p1" or unknown-block(179,1) ...4、把SD卡写保护去掉系统就运行正常了。

    1、今天在调试freescale开发板,因为其他同事用过拿到手后就出现以下问题。

    VFS: Cannot open root device "mmcblk0p1" or unknown-block(179,1)

    Please append a correct "root=" boot option; here are the available partitions:
    1f00             256 mtdblock0 (driver?)
    1f01            3840 mtdblock1 (driver?)
    b300         3872256 mmcblk0 driver: mmcblk
      b301         3868160 mmcblk0p1
    Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(179,1)
    [<8002e4c0>] (unwind_backtrace+0x0/0xf0) from [<80375504>] (panic+0x6c/0xe0)
    [<80375504>] (panic+0x6c/0xe0) from [<80008d90>] (mount_block_root+0x258/0x2a8)
    [<80008d90>] (mount_block_root+0x258/0x2a8) from [<80008f5c>] (prepare_namespace+0x11c/0x174)
    [<80008f5c>] (prepare_namespace+0x11c/0x174) from [<80008480>] (kernel_init+0x120/0x168)

    [<80008480>] (kernel_init+0x120/0x168) from [<8002a9c0>] (kernel_thread_exit+0x0/0x8)


    2、一直是上述问题,说明找不到”mmcblk0p1“分区,调试了一会也没有任何解决的迹象。


    3、拔下SD卡发现是SD卡写保护了,导致kernel无法挂载mmcblk0p1分区


    4、把SD卡写保护去掉系统就运行正常了。

    展开全文
  • zed board 启动linux-qspi启动、sd卡启动

    1,qspiboot  bif:

    the_ROM_image:
    {
        [bootloader]./zynq_fsbl.elf
        ./system.bit
        ./u-boot.elf
        [offset = 0x800000]./zImage
        [offset = 0xC00000]./devicetree.dtb
        [offset = 0xC10000]./ramdisk8M.image.gz
    }

    2,sdboot  bif:

    the_ROM_image:
    {
        [bootloader]./zynq_fsbl.elf
        ./system.bit
        ./u-boot.elf
    }

    3,makeboot.bat文件格式和内容:
        bootgen -image  OUTPUT.bif -o i BOOT.BIN -w on   //sd卡启动必须命名为BOOT.BIN
        bootgen -image  OUTPUT.bif -o i BOOT.mcs -w on //命名可以不为boot.mcs

    4,写好bif,make.bat文件后,点击makeboot.bat文件,.bat文件则调用bootgen.exe生成bin/mcs文件

    5,烧写mcs到flash或者copy bin到sd卡

    6,设置跳线,r上电启动

    7,串口查看输出信息

    8,串口调试

    展开全文
  • 一、工作流程 mmc驱动主要文件包括 drivers/mmc/card/block.c drivers/mmc/card/queue.c drivers/mmc/core/core.c ...内核启动时,首先执行core/core.c的mmc_init,注册mmc、sd总线,以及一个host class设备

    一、工作流程

    mmc驱动主要文件包括

    drivers/mmc/card/block.c
    drivers/mmc/card/queue.c
    drivers/mmc/core/core.c
    drivers/mmc/core/host.c
    drivers/mmc/core/

    内核启动时,首先执行core/core.c的mmc_init,注册mmc、sd总线,以及一个host class设备。接着执行card/block.c中,申请一个块设备

    二、数据结构:

    这里涉及三种总线

    1. platform bus //MMC host controller 作为一种 platform device, 它是需要注册到 platform bus上 的  
    driver/base/platform.c  
    struct bus_type platform_bus_type = {  
        .name        = "platform",  
        .dev_attrs    = platform_dev_attrs,  
        .match        = platform_match,  
        .uevent        = platform_uevent,  
        .pm        = &platform_dev_pm_ops,  
    };  
      
    2. mmc bus type  //在mmc_init()中被创建的.通过调用 mmc_register_bus() 来注册 MMC 总线  
    drivers\mmc\core\bus.c  
    static struct bus_type mmc_bus_type = {  
        .name        = "mmc",  
        .dev_attrs    = mmc_dev_attrs,  
        .match        = mmc_bus_match,  
        .uevent        = mmc_bus_uevent,  
        .probe        = mmc_bus_probe,  
        .remove        = mmc_bus_remove,  
        .shutdown        = mmc_bus_shutdown,  
        .pm        = &mmc_bus_pm_ops,  
    };  
      
    3. sdio bus type    //在mmc_init()中被创建的.通过调用sdio_register_bus() 来注册 SDIO 总线  
    drivers\mmc\core\sdio_bus.c  
    static struct bus_type sdio_bus_type = {  
        .name        = "sdio",  
        .dev_attrs    = sdio_dev_attrs,  
        .match        = sdio_bus_match,  
        .uevent        = sdio_bus_uevent,  
        .probe        = sdio_bus_probe,  
        .remove        = sdio_bus_remove,  
        .pm        = SDIO_PM_OPS_PTR,  
    };  
         其中mmc总线操作相关函数,由于mmc卡支持多种总数据线,如SPI、SDIO、8LineMMC而不同的总线的操作控制方式不尽相同,所以通过此结构与相应的总线回调函数相关联。
    //总线操作结构
    struct mmc_bus_ops {
        void (*remove)(struct mmc_host *);
        void (*detect)(struct mmc_host *);
        int (*sysfs_add)(struct mmc_host *, struct mmc_card *card);
        void (*sysfs_remove)(struct mmc_host *, struct mmc_card *card);
        void (*suspend)(struct mmc_host *);
        void (*resume)(struct mmc_host *);
    };
    //  mmc卡的总线操作 core/mmc.c
    static const struct mmc_bus_ops mmc_ops = {
        .remove = mmc_remove,
        .detect = mmc_detect,
        .sysfs_add = mmc_sysfs_add,
        .sysfs_remove = mmc_sysfs_remove,
        .suspend = mmc_suspend,
        .resume = mmc_resume,
    };
    // sd卡的总线操作 core/sd.c
    static const struct mmc_bus_ops mmc_sd_ops = {
        .remove = mmc_sd_remove,
        .detect = mmc_sd_detect,
        .sysfs_add = mmc_sd_sysfs_add,
        .sysfs_remove = mmc_sd_sysfs_remove,
        .suspend = mmc_sd_suspend,
        .resume = mmc_sd_resume,
    };
    // sdio的总线操作 core/sdio.c
    static const struct mmc_bus_ops mmc_sdio_ops = {
        .remove = mmc_sdio_remove,
        .detect = mmc_sdio_detect,
    };

    关于总线操作的函数:

    .detect,驱动程序经常需要调用此函数去检测mmc卡的状态,具体实现是发送CMD13命令,并读回响应,如果响应错误,则依次调用.remove、detach_bus来移除卡及释放总线。


    三、总体架构

    1、kernel启动时,先后执行mmc_init()及mmc_blk_init(),以对mmc设备及mmc块模块进行初始化

    mmc/core/core.c  
    static int __init mmc_init(void)  
        workqueue = alloc_ordered_workqueue("kmmcd", 0);//建立了一个工作队列workqueue,这个工作队列的作用主要是用来支持热插拔  
        ret = mmc_register_bus();//注册一个mmc总线  
        ret = mmc_register_host_class();//注册了一个 mmc_host 类  
        ret = sdio_register_bus();//注册了一个 sdio_bus_type  
          
    *******   
    mmc/card/block.c  
    static int __init mmc_blk_init(void)  
        res = register_blkdev(MMC_BLOCK_MAJOR, "mmc");//注册一个块设备  
        res = mmc_register_driver(&mmc_driver);//注册一个mmc设备驱动  
      
    static struct mmc_driver mmc_driver =  
        .probe      = mmc_blk_probe,  
          
    static int mmc_blk_probe(struct mmc_card *card)  
        mmc_set_bus_resume_policy(card->host, 1);//*host 该指针指向一个mmc主机实例,块设备中的读写操作就是调用这个mmc主机的操作函数host->ops->request来实现对实际硬件的操作。  

    2、core部分会做两件事

    a -- 取得总线

    b -- 检查总线操作结构指针bus_ops,如果为空,则重新利用各总线对端口进行扫描,检测顺序依次为:SDIO、Normal SD、MMC。当检测到相应的卡类型后,就使用mmc_attach_bus()把相对应的总线操作与host连接起来

    void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops)
    {
        ...
        host->bus_ops = ops;
        ...
    }

    3、然后在挂载mmc设备驱动时,执行驱动程序中的xx_mmc_probe(),检测host设备中挂载的sd设备

    kernel\arch\arm\configs\msm9625_defconfig  
    CONFIG_MMC_MSM=y  
      
    kernel\drivers\mmc\host\Makefile  
    obj-$(CONFIG_MMC_MSM)        += msm_sdcc.o      
      
    msm_sdcc.c (drivers\mmc\host)  
    //系统初始化时扫描 platform 总线上是否有名为该SD主控制器名字"msm_sdcc"的设备,如果有, 驱动程序将主控制器挂载到 platform 总线上,并注册该驱动程序  
    static int __init msmsdcc_init(void)  
        platform_driver_register(&msmsdcc_driver);    //注册 platform driver  
          
    static struct platform_driver msmsdcc_driver = {  
        .probe        = msmsdcc_probe,  
        .remove        = msmsdcc_remove,  
        .driver        = {  
            .name    = "msm_sdcc",  
            .pm    = &msmsdcc_dev_pm_ops,  
            .of_match_table = msmsdcc_dt_match,  
        },  
    };      
          
    //整个设备驱动的 probe()函数,其本质就是是为设备建立起数据结构并对其赋初值  
    //msmsdcc_probe 所有赋值中,我们重点关注从 platform_device *pdev里得到的数据,即设备树里的数据  
    //platform_device *pdev是在系统初始化的时候扫描 platform 总线发现SD主控制器后所得到的数据  
    static int msmsdcc_probe(struct platform_device *pdev)      
    {      
        //初始化设备的数据结构  
        if (pdev->dev.of_node) {  
        plat = msmsdcc_populate_pdata(&pdev->dev);        //获取设备树信息  
        of_property_read_u32((&pdev->dev)->of_node,"cell-index", &pdev->id);  
        } else {  
            plat = pdev->dev.platform_data;  
        }  
        //为主设备控制器建立数据结构,建立kobject,并初始化等待队列,工作队列,以及一些控制器的配置  
        mmc = mmc_alloc_host(sizeof(struct msmsdcc_host), &pdev->dev);            ---- 1  
        //实现设备驱动的功能函数,如mmc->ops = &pxamci_ops;  
        mmc->ops = &msmsdcc_ops;  
        //申请中断函数 request_irq()  
        ret = request_irq(core_irqres->start, msmsdcc_irq, IRQF_SHARED,DRIVER_NAME " (cmd)", host);  
        //注册设备,即注册kobject,建立sys文件,发送uevent等  
        mmc_add_host(mmc);                                                        ---- 2  
        //其他需求,如在/proc/driver下建立用户交互文件等  
        ret = device_create_file(&pdev->dev, &host->auto_cmd21_attr);  
    }      

    4、此时probe函数会创建一个host设备,然后开启一个延时任务mmc_rescan()

    1:    
    core/host.c   
    //重要函数mmc_alloc_host , 用于分配mmc_host结构体指针的内存空间大小  
    struct mmc_host *mmc_alloc_host(int extra, struct device *dev)----创建一个 mmc_host 和 mmc_spi_host ,且mmc_host的最后一个成员指针private指向mmc_spi_host  
        //建立数据结构  
        struct mmc_host *host;    
        host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);  
        //建立kobject  
        host->parent = dev;  
        host->class_dev.parent = dev;  
        host->class_dev.class = &mmc_host_class;  
        device_initialize(&host->class_dev);  
        //初始化等待队列,工作队列  
        init_waitqueue_head(&host->wq);  
        INIT_DELAYED_WORK(&host->detect, mmc_rescan);    //建立了一个工作队列任务 structdelayed_work detect。工作队列任务执行的函数为mmc_rescan  
        //配置控制器  
        host->max_segs = 1;  
        host->max_seg_size = PAGE_CACHE_SIZE;  
        return host;  

    5、驱动挂载成功后,mmc_rescan()函数被执行,然后对卡进行初始化(步骤后面详细讲述)

    core/core.c  
    //mmc_rescan 函数是需要重点关注的,因为SD卡协议中的检测,以及卡识别等都是在此函数中实现  
    void mmc_rescan(struct work_struct *work)  
        if (host->bus_ops && host->bus_ops->detect && !host->bus_dead && !(host->caps & MMC_CAP_NONREMOVABLE))    //存在热插拔卡,不包括emmc,调用探测函数  
        host->bus_ops->detect(host);  
        mmc_bus_put(host);    //减少引用技术,就释放  
        mmc_bus_get(host);    //增加bus引用计数  
        if (host->bus_ops != NULL) {  
            mmc_bus_put(host);    //如果卡仍然存在,减少引用计数,不必探测了  
            goto out;  
        }  
        if (host->ops->get_cd && host->ops->get_cd(host) == 0)  //有卡,退出  
        goto out;  
        mmc_claim_host(host);                   //用于检测host是否被占用,占用则退出,否则标记成占用  
          
        if (!mmc_rescan_try_freq(host, host->f_min))  
    初始化卡接以下流程初始化:

    a、发送CMD0使卡进入IDLE状态
    b、发送CMD8,检查卡是否SD2.0。SD1.1是不支持CMD8的,因此在SD2.0 Spec中提出了先发送CMD8,如响应为无效命令,则卡为SD1.1,否则就是SD2.0(请参考SD2.0 Spec)。
    c、发送CMD5读取OCR寄存器。
    d、发送ACMD55、CMD41,使卡进入工作状态。MMC卡并不支持ACMD55、CMD41,如果这步通过了,则证明这张卡是SD卡。
    e、如果d步骤错误,则发送CMD1判断卡是否为MMC。SD卡不支持CMD1,而MMC卡支持,这就是SD和MMC类型的判断依据。
    f、如果ACMD41和CMD1都不能通过,那这张卡恐怕就是无效卡了,初始化失败。

          假如扫描到总线上挂有有效的设备,就调用相对应的函数把设备装到系统中,mmc_attach_sdio()、mmc_attach_sd()、mmc_attach_mmc()这三个函数分别是装载sdio设备,sd卡和mmc卡的。

         在 sd卡中,驱动循环发送ACMD41、CMD55给卡,读取OCR寄存器,成功后,依次发送CMD2(读CID)、CMD3(得到RCA)、CMD9(读 CSD)、CMD7(选择卡)。后面还有几个命令分别是ACMD41&CMD51,使用CMD6切换一些功能,如切换到高速模式。

         经过上述步骤,已经确定当前插入的卡是一张有效、可识别的存储卡。然后调用mmc_add_card()把存储卡加到系统中。正式与系统驱动连接在一起

    static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq)  
        host->f_init = freq;                 //设置某一个时钟频率  
        mmc_power_up(host);                     //与 mmc_power_off 类似,不过设置了启动时需要的 ios  
        mmc_go_idle(host);          ----1a      //CMD0 ,SD卡从 inactive 到 idle          
        mmc_send_if_cond(host, host->ocr_avail);//检测SD卡是否支持SD2.0       
        if (!mmc_attach_sd(host))   ----1b      //然后对mmc或者sd发送一些命令进行探测,这里以 sd 为例  
      
    1a:  
    int mmc_go_idle(struct mmc_host *host)    
        struct mmc_command cmd = {0};  
        cmd.opcode = MMC_GO_IDLE_STATE; //即CMD0  
        cmd.arg = 0;                    //此命令无参数  
        err = mmc_wait_for_cmd(host, &cmd, 0)  
          
    int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries)  
        memset(cmd->resp, 0, sizeof(cmd->resp));  //调用了 mmc_start_request,   
        cmd->retries = retries;  
        mrq.cmd = cmd;                                
        mmc_wait_for_req(host, &mrq);  
          
    void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)   ----重要函数  
        __mmc_start_req(host, mrq);  
      
    static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)  
        mmc_start_request(host, mrq);  
              
    static void mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)  
        host->ops->request(host, mrq);    //即 msmsdcc_request, MMC 核心与核HOST 层握手了  
      
          
    1b:   
    core/mmc.c  
    int mmc_attach_sd(struct mmc_host *host)                    //完成匹配,和初始化卡的功能  
        err = mmc_send_app_op_cond(host, 0, &ocr);      ----1b1 //检测是否是支持SD卡  
        host->ocr = mmc_select_voltage(host, ocr);               //设置MMC电压  
        err = mmc_init_card(host, host->ocr, NULL);              //对mmc卡进行初始化,主要是读取mmc卡里的一些寄存器信息,且对这些寄存器的值进行设置  
        err = mmc_sd_init_card(host, host->ocr, NULL);   ----1b2  
        err = mmc_add_card(host->card);                  ----1b3 //调用 mmc_add_card 来把 mmc_card 挂载到 mmc_bus_type 总线去  
          
          
    1b1:  
    int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)  
        cmd.opcode = SD_APP_OP_COND;    //ACMD41,获取 SDcard 的允许电压范围值,保存在 ocr 中. 所有发送它之前需要发送 CMD_55 命令。执行完后 card 状态变为 READY  
      
          
          
    1b2:  
    static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,struct mmc_card *oldcard)  
        err = mmc_sd_get_cid(host, ocr, cid, &rocr);        //发送 CMD2 ,获取卡的身份信息,进入到身份状态  
        card = mmc_alloc_card(host, &sd_type);              //分配一张 SD 类型的 card 结构  
        err = mmc_send_relative_addr(host, &card->rca);      //获取卡的相对地址,注意一前卡和主机通信都采用默认地址,现在有了自己的地址了,进入到 stand_by 状态  
        err = mmc_sd_get_csd(host, card); ----mmc_send_csd(card, card->raw_csd);//CMD9, 获取 CSD 寄存器的信息,包括 block 长度,卡容量等信息  
        err = mmc_select_card(card);                        //发送 CMD7, 选中目前 RADD 地址上的卡,任何时候总线上只有一张卡被选中,进入了传输状态   
        err = mmc_sd_setup_card(host, card, oldcard != NULL);     
      
    int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,bool reinit)  
        mmc_app_send_scr(card, card->raw_scr);   //发送命令 ACMD51 获取 SRC 寄存器的内容,进入到 SENDING-DATA 状态  
        if (host->ops->get_ro(host) > 0 )      // get_ro(host) 即是 msmsdcc_get_ro   
            mmc_card_set_readonly(card);        //是否写保护,如果是的,将 card 状态设置为只读状态  
          
    1b3:  
    core/bus.c  
    int mmc_add_card(struct mmc_card *card)     //  /sys/devices/msm_sdcc.2/mmc_host/mmc0  
        ret = device_add(&card->dev);  
      
    drivers/base/core.c  
    int device_add(struct device *dev)  
        dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id); //  
        bus_probe_device(dev);  
      
    void bus_probe_device(struct device *dev)  
            if (bus->p->drivers_autoprobe)   
            ret = device_attach(dev);           //这样,在总线 mmc_bus_type 中就有了 mmc 设备 mmc_card 了      
          
          
    ***********   
    2:  
    //完成kobject的注册,并调用 mmc_rescan,目的在于在系统初始化的时候就扫描SD总线查看是否存在SD卡  
    int mmc_add_host(struct mmc_host *host)  
        err = device_add(&host->class_dev);//将设备注册进linux设备模型,最终的结果就是在 sys/bus/platform/devices 目录下能见到 mmc 设备节点  
        mmc_start_host(host);  
          
          
    void mmc_start_host(struct mmc_host *host)    
        mmc_power_off(host);                ----2a  
        mmc_detect_change(host, 0);         ----2b  
      
    2a:  
    void mmc_power_off(struct mmc_host *host)     
        host->ios.power_mode = MMC_POWER_OFF;    //对 ios 进行了设置  
        ...  
        mmc_set_ios(host);  
      
    void mmc_set_ios(struct mmc_host *host)  
        host->ops->set_ios(host, ios);            // set_ios 实际上就是 mmc_host_ops 的 .set_ios  = msmsdcc_set_ios,  
      
    2b:  
    void mmc_detect_change(struct mmc_host *host, unsigned long delay)  
            mmc_schedule_delayed_work(&host->detect, delay); //实际上就是调用我们前面说的延时函数 mmc_rescan  

    6、卡设备加到系统中后,通知mmc块设备驱动。块设备驱动此时调用probe函数,即mmc_blk_probe()函数,mmc_blk_probe()首 先分配一个新的mmc_blk_data结构变量,然后调用mmc_init_queue,初始化blk队列。然后建立一个线程 mmc_queue_thread()


    7、然后就可以进行传输命令和数据了

    struct mmc_host_ops {         
        //用于SD卡命令的传输,比如发送和接收命令,CMD0,CMD8,ACMD41诸如此类的都是在这个函数去实现  
        void    (*request)(struct mmc_host *host, struct mmc_request *req);  
      
    }  
      
    static const struct mmc_host_ops msmsdcc_ops = {  
        .enable     = msmsdcc_enable,  
        .disable    = msmsdcc_disable,  
        .pre_req        = msmsdcc_pre_req,  
        .post_req       = msmsdcc_post_req,  
        .request    = msmsdcc_request,  
        .set_ios    = msmsdcc_set_ios,  
        .get_ro     = msmsdcc_get_ro,  
        .enable_sdio_irq = msmsdcc_enable_sdio_irq,  
        .start_signal_voltage_switch = msmsdcc_switch_io_voltage,  
        .execute_tuning = msmsdcc_execute_tuning,  
        .hw_reset = msmsdcc_hw_reset,  
        .stop_request = msmsdcc_stop_request,  
        .get_xfer_remain = msmsdcc_get_xfer_remain,  
        .notify_load = msmsdcc_notify_load,  
    };  
      
    /*这个函数实现了命令和数据的发送和接收, 
    当 CORE 部分需要发送命令或者传输数据时,都会调用这个函数,并传递 mrq 请求*/  
    static void msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq)  
        mmc_request_done(mmc, mrq);             // 如果卡不存在,就终止请求  
        msmsdcc_request_start(host, mrq);         
      
    static void msmsdcc_request_start (struct msmsdcc_host *host, struct mmc_request *mrq)  
        if ((mrq->data->flags & MMC_DATA_READ) ||host->curr.use_wr_data_pend)      //判断发送数据还是命令  
            msmsdcc_start_data(host, mrq->data,mrq->sbc ? mrq->sbc : mrq->cmd,0);   //发送数据  
        else  
            msmsdcc_start_command(host,mrq->sbc ? mrq->sbc : mrq->cmd,0);          //发送命令  
      
      
    static void msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data,struct mmc_command *cmd, u32 c)  
        //对某些 寄存器进行设置, 使能某些中断, 如 pio_irqmask  
        ...  
        if (is_dma_mode(host) && (datactrl & MCI_DPSM_DMAENABLE))   //采用 DMA 进行数据传输还是采用 FIFO 进行数据传输  
            msmsdcc_start_command_deferred(host, cmd, &c);          //启动了数据传输模式  
        else      
            msmsdcc_start_command(host, cmd, c)  
      
    static void msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd, u32 c)  
    {  
        msmsdcc_start_command_deferred(host, cmd, &c);  
        msmsdcc_start_command_exec(host, cmd->arg, c);  
    }  
      
    static void msmsdcc_start_command_deferred(struct msmsdcc_host *host,struct mmc_command *cmd, u32 *c)  
        cmd->opcode ----对应SD卡命令 ,如 CMD0:复位SD 卡  



    展开全文
  • SD卡启动是开发板系统启动方式的一种。SD系统启动卡共有FAT32、EXT4两个格式分区。其中FAT32格式分区在Windows系统下可见,EXT4格式分区在Windows系统下不可见,两分区在Linux系统下均可见。FAT32格式分区存放U-Boot...

    1SD系统启动卡说明
    SD卡启动是开发板系统启动方式的一种。SD系统启动卡共有FAT32、EXT4两个格式分区。其中FAT32格式分区在Windows系统下可见,EXT4格式分区在Windows系统下不可见,两分区在Linux系统下均可见。FAT32格式分区存放U-Boot、内核、设备树等,EXT4格式分区存放文件系统。
    开发板出厂时已经提供一个正常使用的Linux SD系统启动卡。以下步骤是Linux SD系统启动卡的制作过程。
    操作环境:
    Ubuntu 14.04.3 64bit
    执行如下命令创建"/home/tronlong/AM335x/mksdboot"目录,用于存放SD系统启动卡制作文件,如下图所示:
    Host# mkdir -p /home/tronlong/AM335x/mksdboot

    在这里插入图片描述
    2基于Linux-4.4.12内核的SD系统启动卡制作步骤
    2.1拷贝SD系统启动卡制作文件
    将光盘"Shell\Linux-4.4.12-mksdboot"拷贝到"/home/tronlong/AM335x/mksdboot"目录下。
    Linux-4.4.12-mksdboot文件夹内容结构大致如下:

    在这里插入图片描述

    MLO:U-Boot一级启动镜像。
    u-boot.img:U-Boot二级启动镜像。
    zImage:Linux内核镜像。
    .dtb文件,设备树文件,由内核编译步骤产生:
    am335x-icev2.dtb对应ROM为eMMC的设备树文件;
    am335x-icev2-nand.dtb对应ROM为NAND FLASH的设备树文件。
    flash_nand.sh:固化文件系统到NAND FLASH对应的脚本文件。
    mk-eMMC-boot.sh:固化文件系统到eMMC对应的脚本文件。
    filesystem目录内容:文件系统压缩包。
    mksdboot.sh:Linux SD系统启动卡制作脚本。
    modules目录内容:内核模块。
    以上文件如需替换,务必保证名字、格式和原文件一致。
    2.2识别SD卡
    将Micro SD卡通过读卡器连接到计算机,虚拟机Ubuntu系统识别后会自动识别SD卡分区,如下图所示:

    在这里插入图片描述

    如果没有自动识别,请右击右下角的USB大容量存储设备图标,再点击"Connect (Disconnect from Host)"。

    在这里插入图片描述

    如果没有以上图标或者连接不成功,请尝试如下方法:
    请将Micro SD卡通过读卡器插到USB2.0接口,而不是USB3.0接口,部分版本VMware可能不支持USB3.0。
    请将Micro SD卡插在PC上,然后重启Ubuntu,在Ubuntu重启过程中不要拨出来,开机后图标会重新出现。
    2.3确认SD卡设备节点名
    执行如下命令:
    Host# sudo fdisk -l

    在这里插入图片描述

    可以看到SD卡设备节点是sdb,其中有1个分区,分区名字是sdb1。SD卡设备节点名字是可变的,一般插拔多次或者不同的卡插拔后,可能会显示sdc或者sdd甚至sde。
    2.4运行SD系统启动卡制作脚本
    SD系统启动卡制作脚本mksdboot.sh主要有如下作用:
    将SD卡格式化为boot分区和rootfs分区。
    将filesystem文件夹中的文件系统压缩包解压安装到rootfs分区。
    将boot目录下的U-Boot镜像文件MLO、u-boot.img拷贝到boot分区。SD卡模式启动时,系统会使用boot分区U-Boot镜像文件。
    将Linux-4.4.12-mksdboot的boot目录下对应开发板的设备树文件,拷贝到rootfs分区“/boot”目录,并重命名为am335x-icev2.dtb。SD卡模式启动时,系统会使用rootfs分区“/boot”目录下的设备树文件。
    将Linux-4.4.12-mksdboot的boot目录下的内核镜像文件zImage拷贝到rootfs分区“/boot”目录。SD卡模式启动时,系统会使用rootfs分区“/boot”目录下的内核镜像文件。
    使用SD系统启动卡启动系统时,如需替换U-Boot镜像、设备树、内核镜像、文件系统,有如下方法:
    使用新的U-Boot镜像文件,保持文件名与原文件一致,替换SD系统启动卡boot分区下的对应文件;
    使用新的设备树文件,重命名为am335x-icev2.dtb,替换SD系统启动卡rootfs分区“/boot”目录下的对应文件;
    使用新的内核镜像文件,保持文件名与原文件一致,替换SD系统启动卡rootfs分区“/boot”目录下的对应文件;先删除SD系统启动卡rootfs分区所有内容,再使用新的文件系统压缩包,将其解压到SD系统启动卡rootfs分区,并将设备树文件、内核镜像文件拷贝到SD系统启动卡rootfs分区“/boot”目录,确保设备树文件名为am335x-icev2.dtb。
    使用新的U-Boot镜像文件、设备树文件、内核镜像文件、文件系统压缩包,保持文件名与原文件一致,替换SD系统启动卡制作文件目录下的对应文件,然后重新制作SD系统启动卡。
    进入Linux-4.4.12-mksdboot目录,执行如下命令,运行SD系统启动卡制作脚本。不同型号开发板的参数不同,以参数”–board”识别不同型号开发板。
    核心板ROM为NAND FLASH版本:–board tl335x-idk_nand
    核心板ROM为eMMC版本:–board tl335x-idk_emmc
    以核心板ROM为eMMC版本为例,如下图所示:
    Host# cd /home/tronlong/AM335x/mksdboot/Linux-4.4.12-mksdboot
    Host# sudo ./mksdboot.sh --device /dev/sdb --board tl335x-idk_emmc
    “/dev/sdb”为SD卡设备节点。请再次确认SD卡设备节点一致,如错误输入其他存储介质设备节点,将会造成存储介质数据损坏。

    在这里插入图片描述

    后续详细帮助在官网
    销售邮箱:sales@tronlong.com
    技术邮箱:support@tronlong.com
    创龙总机:020-8998-6280
    技术热线:020-3893-9734
    创龙官网:www.tronlong.com
    技术论坛:www.51ele.net
    线上商城:https://tronlong.taobao.com

    展开全文
  • 嵌入式Linux SD系统启动卡制作方法

    千次阅读 2017-01-04 10:04:54
    SD 卡启动是开发板系统启动方式的一种。 SD 系统启动卡共有 FAT32、 EXT3 两个格式分区,还包含 RAW 格式的无名分区。其中 FAT32 格式分区在 Windows 系统下可见,EXT3 格式分区在 Windows 系统下不可见,两分区在 ...
  • LinuxSD卡启动制作

    千次阅读 2015-06-24 16:18:14
    材料:sd_fusing源码,制作好的bootloader镜像文件,一张sd卡,读卡器 步骤: 1.连接SD卡到Ubuntu上。 2.把镜像拷贝到sd_fusing源码目录下。 3.make clean,清除一下。 4.make编译出相应的文件。 5.执行一...
  • Linux制作SD卡启动

    2019-09-28 16:56:11
    第一步 dd iflag=dsync oflag=dsync if=/dev/zero of=uboot.img bs=516k count=1 if:输入文件 of:输出文件 bs: 读取输入文件/写入输出文件,每次读取/写入的数据大小 count:执行几次读写操作。...
  • # SD卡有多大容量 sudo dd if=/dev/zero of=xrz.img bs=1M count=7580 # 开始对SD卡分区 # 磁头255 扇区63 柱面966 # 格式 ,,, # 第一个分区,从0开始 9个柱面 类型0x0C bootable # 第二个分区,从...
  • linux SD卡驱动

    2019-11-07 16:36:10
    Linux SD卡驱动开发(一) —— SD 相关基础概念 https://blog.csdn.net/zqixiao_09/article/details/51039378 Linux SD卡驱动开发(二) —— SD 卡驱动分析HOST篇 ...
  • linux mmc sd卡启动过程详解

    千次阅读 2013-06-03 20:37:53
    工作流程: mmc驱动主要文件包括 drivers/mmc/card/block.c drivers/mmc/card/queue.c drivers/mmc/core/core.c ...内核启动时,首先执行core/core.c的mmc_init,注册mmc、sd总线,以及一个host class设备。
  • SD卡烧写镜像 上电启动 uboot启动 linux内核启动 串口终端输出信息:
  • linux sd卡驱动分析

    千次阅读 2012-04-28 18:11:51
    原文地址:linux sd卡驱动分析 作者:shark888 linux sd卡驱动分析 (2012-01-30 16:48)转载 标签: linux class normal color Linux  分类: 驱动系列 基于S3C2410的SD卡linux驱动工作原理  ...
  • https://blog.csdn.net/tech_pro/article/details/80269751...一、对SD卡进行分区并格式化SD卡 首先从emmc中启动系统,然后执行如下命令来对SD卡进行分区和格式化:fdisk -c 1 320 2057 520 fatformat mmc 1:1 ext3...
  • SD卡文件系统启动linux

    2017-04-11 15:41:43
    s3c6410 完全由SD卡启动Linux流程 S3C6410 完全由SD卡启动Linux流程 linux启动参数详解
  • ZYNQ的Linux Linaro系统镜像制作SD卡启动 0. 概述 ZYNQ生成uboot的时候和正常的ARM设备不太一样,ZYNQ属于二次辅助启动uboot然后由uboot启动内核,大概意思就是 ZYNQ内部有一个机制,该机制不可修改,可以通过拨...
  • 前面已经将网卡配置好,也已经可以通过tftp下载程序到nand flash,也可以通过nfs挂载根文件系统,可以说基本的开发环境已经搭建好。本节介绍如何从sd卡启动自己已有源码的uboot
  • linux SD卡分区

    2012-07-15 20:11:44
    DM8148 SD卡启动,需要SD卡提供两个分区,一个用于存放镜像,一个用于文件系统: $mount ;#获取信息 /dev/sdb on/media/FC9A-7690,在/media文件夹下可以发现这个FC9A-7690,显然是sd卡得。 $umount /dev/sdb ;#...
  • 关于SD卡启动linux的问题

    千次阅读 2017-01-04 10:45:06
    (2013年5月14日)经过前段时间的折腾,到今天为止,对于uboot终于有点头绪了,虽然上星期已经成功...本次对linux下为SD卡烧写uboot.bin的原理与方法进行一个讲解             一、对于网上关于SD卡烧写的问题,
  • 此处我们将网口IP设置成静态IP,以方便我们测试 由于硬件设计,此处我们使用串口1,波特率115200 设置完成后,保存并退出 注意:配置中默认是SD1卡启动 编译 petalinux-build 打包生成BIN文件 cd images/linux/ ...
  •  Linux在内核源码的drivers/mmc/core文件夹下为我们的提供了一系列SD卡的接口服务函数。可以查看Makefile如下 可见,core文件夹下有针对总线的服务bus.c,针对主控制器的服务host.c,针对SD卡的服务sd.c, sd_ops...
  • Linux SD卡驱动开发(二) —— SD 卡驱动分析HOST篇

    万次阅读 多人点赞 2016-04-01 22:19:18
    回顾一下前面的知识,MMC 子系统范围三个部分: HOST 部分是针对不同主机的驱动程序,...CARD 部分:因为这些记忆都是块设备,当然需要提供块设备的驱动程序,这部分就是实现了将你的SD 如何实现为块设备的。 它们
  • 1. s3c6410 SD启动原理 ... s3c6410 支持Nand Flash本地启动Linux,包括内核,根文件系统,bootloader均写入在Nand Flash.这样可以独立运行.  很多情况下,Nand Flash的某种原因无法写
  • 嵌入式Linux裸机开发(十)——SD卡启动存储设备分类:磁存储设备:软盘、硬盘、光盘、CD、磁带Flash:NandFlash、NorFlash缺点:时序复杂,无坏块处理机制,接口不统一NandFlash:MLC(可靠性差,容量大)、SLC...
  • 在ZYNQ-7000系列Soc上启动Linux操作系统需要两个文件,一个为BOOT.mcs(QSPI启动所需,SD卡启动为BOOT.bin)和image.ub。其中image.ub为Linux系统镜像文件,由petalinux工具编译而成,BOOT文件由三个文件合成,分别...
  • Linux启动SD卡的格式化方法

    千次阅读 2012-06-14 11:12:01
    要在OMAP3530上运行Linux,首先要知道... OMAP3530提供了两种启动方式,NAND FLASH启动和SD卡启动。对于第一次烧写程序,在没有JTAG的情况下,我们采用了SD卡启动的方式较为方便。  Linux下的SD启动和WINCE下的SD卡
  • linux SD卡驱动分析

    千次阅读 2012-04-24 10:24:05
    SD 是一种 flash memory card 的标准,也就是一般常见的 SD 记忆,而 MMC 则是较早的一种记忆标准,目前已经被 SD 标准所取代。  SDIO 是目前我们比较关心的技术,SDIO 故名思义,就是 SD

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 26,083
精华内容 10,433
关键字:

linuxsd卡启动

linux 订阅