国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

查看: 4050|回復(fù): 3
打印 上一主題 下一主題

修改我們自己的uboot,實(shí)現(xiàn)快捷更新Linux系統(tǒng)(基于S3C6410,源文件+注釋?zhuān)?/span>

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2011-8-20 13:37:46 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
關(guān)鍵詞: uboot
很客觀的說(shuō),ok6410的硬件相比mini6410強(qiáng)大許多(同樣的價(jià)錢(qián)),但是ok6410的uboot制作用起來(lái)不太方便,需要輸入很多命令才可以燒寫(xiě)完一個(gè)系統(tǒng)。我還是比較懷念在2440上方便、靈活的燒寫(xiě)方式。
      
下面我們就來(lái)修改出一個(gè)簡(jiǎn)單的uboot,實(shí)現(xiàn)快速更新系統(tǒng)。

點(diǎn)擊此處下載 u-boot.rar (79.19 KB)
點(diǎn)擊此處下載   main.rar (9.87 KB)

點(diǎn)擊此處進(jìn)入飛凌官網(wǎng)下載:http://www.witech.com.cn/

一、首先簡(jiǎn)單的說(shuō)明uboot的啟動(dòng)過(guò)程:

1)、從文件層面上看主要流程是在兩個(gè)文件中:cpu/xxxx/start.s,lib_arm/board.c。
Start.s  
在flash中執(zhí)行的引導(dǎo)代碼,也就是bootloader中的stage1,負(fù)責(zé)初始化硬件環(huán)境,把u-boot從flash加載到RAM中去,然后跳到lib_arm/board.c中的start_armboot中去執(zhí)行。
1.1.6版本的start.s流程:
硬件環(huán)境初始化:
進(jìn)入svc模式-->關(guān)閉watch dog-->屏蔽所有IRQ掩碼-->設(shè)置時(shí)鐘頻率FCLK、HCLK、PCLK-->清I/D cache-->禁止MMU和CACHE-->配置memory control-->重定位:如果當(dāng)前代碼不在連接指定的地址上(對(duì)smdk2410是0x3f000000)則需要把u-boot從當(dāng)前位置拷貝到RAM指定位置中;-->建立堆棧,堆棧是進(jìn)入C函數(shù)前必須初始化的。-->清.bss區(qū)。-->跳到start_armboot函數(shù)中執(zhí)行。(lib_arm/board.c)

2)、lib_arm/board.c:
start_armboot是U-Boot執(zhí)行的第一個(gè)C語(yǔ)言函數(shù),完成系統(tǒng)初始化工作,進(jìn)入主循環(huán),處理用戶(hù)輸入的命令。這里只簡(jiǎn)要列出了主要執(zhí)行的函數(shù)流程:
void start_armboot (void)
   {
       //全局?jǐn)?shù)據(jù)變量指針gd占用r8。
DECLARE_GLOBAL_DATA_PTR;
          /* 給全局?jǐn)?shù)據(jù)變量gd安排空間*/
          gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
          memset ((void*)gd, 0, sizeof (gd_t));
          /* 給板子數(shù)據(jù)變量gd->bd安排空間*/
          gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
          memset (gd->bd, 0, sizeof (bd_t));
          monitor_flash_len = _bss_start - _armboot_start;//取u-boot的長(zhǎng)度。
          /* 順序執(zhí)行init_sequence數(shù)組中的初始化函數(shù) */
          for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr)  
if ((*init_fnc_ptr)() != 0) { hang ();}
/*配置可用的Flash */
  size = flash_init ();
        ……
          /* 初始化堆空間 */
          mem_malloc_init (_armboot_start - CFG_MALLOC_LEN);
          /* 重新定位環(huán)境變量, */
          env_relocate ();
          /* 從環(huán)境變量中獲取IP地址 */
          gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");
          /* 以太網(wǎng)接口MAC 地址 */
          ……
          devices_init ();      /* 設(shè)備初始化 */
          jumptable_init ();  //跳轉(zhuǎn)表初始化
          console_init_r ();    /* 完整地初始化控制臺(tái)設(shè)備 */
          enable_interrupts (); /* 使能中斷處理 */
          /* 通過(guò)環(huán)境變量初始化 */
          if ((s = getenv ("loadaddr")) != NULL)  
                  load_addr = simple_strtoul (s, NULL, 16);
         /* main_loop()循環(huán)不斷執(zhí)行 */
          for (;;)  
          main_loop (); /* 主循環(huán)函數(shù)處理執(zhí)行用戶(hù)命令 -- common/main.c */
   }

其中,初始化函數(shù)序列init_sequence[]
  init_sequence[]數(shù)組保存著基本的初始化函數(shù)指針。這些函數(shù)名稱(chēng)和實(shí)現(xiàn)的程序文件在下列注釋中。
init_fnc_t *init_sequence[] = {
   cpu_init,     /* 基本的處理器相關(guān)配置 -- cpu/arm920t/cpu.c */
   board_init,   /* 基本的板級(jí)相關(guān)配置 -- board/smdk2410/smdk2410.c */
   interrupt_init,  /* 初始化例外處理 -- cpu/arm920t/s3c24x0/interrupt.c */
   env_init,             /* 初始化環(huán)境變量 -- common/env_flash.c */
   init_baudrate,        /* 初始化波特率設(shè)置 -- lib_arm/board.c */
   serial_init,          /* 串口通訊設(shè)置 -- cpu/arm920t/s3c24x0/serial.c */
   console_init_f,       /* 控制臺(tái)初始化階段1 -- common/console.c */
   display_banner,       /* 打印u-boot信息 -- lib_arm/board.c */
   dram_init,            /* 配置可用的RAM -- board/smdk2410/smdk2410.c */
    display_dram_config,  /* 顯示RAM的配置大小 -- lib_arm/board.c */
    NULL,
};

整個(gè)u-boot的執(zhí)行就進(jìn)入等待用戶(hù)輸入命令,解析并執(zhí)行命令的死循環(huán)中。

二、修改main_loop()函數(shù)

我們期望此時(shí)能進(jìn)入一個(gè)菜單,通過(guò)輸入一些簡(jiǎn)單的指令來(lái)更新uboot、kernel、fs等。

1)、分析/common/main.c的main_loop函數(shù):系統(tǒng)進(jìn)入到main_loop

后首先判斷在3秒內(nèi)是否有輸入。如果有輸入就進(jìn)入命令行模式,我們可以在此命令行下通過(guò)輸入指令來(lái)更新系統(tǒng)。如果沒(méi)有輸入則執(zhí)行bootm 指令。
首先,我自己試過(guò)幾次,如果用run_command來(lái)保持環(huán)境變量“setenv bootcmd nand read 0xc0008000 0x100000 0x300000\;bootm 0xc0008000 ”,系統(tǒng)會(huì)直接重啟。比較郁悶,想了變通的方法就是在/include/configs/smdk6410.h文件里直接修改CONFIG_BOOTCOMMAND 為nand read c0008000 100000 300000;bootm c0008000。據(jù)我分析系統(tǒng)啟動(dòng)后會(huì)從這個(gè)宏里讀取bootcmd參數(shù)。(如果有不對(duì)的,請(qǐng)高手指出) 那么我們后面就不用再設(shè)定這個(gè)參數(shù)了。  

void main_loop (void)
{
        …….
s = getenv ("bootcmd");         //獲取bootcmd指令
debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "");
if (bootdelay >= 0 && s && !abortboot (bootdelay)) {  
// abortboot()主要是判斷bootdelay的時(shí)間內(nèi),是否有按鍵輸入。
……
run_command (s, 0); //如果沒(méi)有輸入就執(zhí)行bootcmd指令
      }
//進(jìn)入一個(gè)命令行模式,循環(huán)接受用戶(hù)指令。
//我們就在這里加入一個(gè)我們自己的函數(shù)MainMenu()用來(lái)執(zhí)行菜單。
MainMenu();
/*
* Main Loop for Monitor Command Processing
*/
……
}

2)、在該文件的開(kāi)頭申明一個(gè)函數(shù)MainMenu():void MainMenu()

3)、定義我們的MainMenu()  

void main_menu_usage(void)
{
    printf("\r\n##### ok6410 Bootloader #####\r\n");
    printf("[ u] Download u-boot\r\n");
    printf("[k] Download Linux kernel\r\n");
    //printf("[y] Download YAFFS image\r\n");
    printf("[c] Download cramfs image\r\n");
    //printf("[d] Download to SDRAM & Run\r\n");
    printf("[ b] Boot the system\r\n");
    printf("[f] Format the Nand Flash\r\n");
    printf(" Set the boot parameters\r\n");
    printf("[r] Reboot u-boot\r\n");
    printf("[q] Quit from menu\r\n");
    printf("Enter your selection: ");
}
void MainMenu()
{
        char c;
    char cmd_buf[256];
    char name_buf[20];
    char val_buf[256];
         while (1)
    {
        main_menu_usage();        //輸出菜單的函數(shù)
        c = getc();                                //獲取輸入的字符
        printf("%c\n", c);
        switch (c)
        {
case 'u':                                         //燒寫(xiě)uboot
    printf("nand erase nand and write uboot \n");
    strcpy(cmd_buf, "dnw c0008000 ; nand erase 0 100000 ; nand write 0xc0008000 0 100000");
    printf("%s \n",cmd_buf);
    run_command(cmd_buf, 0);
    break;
case 'k':                                        //燒寫(xiě)kernel
//先設(shè)定環(huán)境變量
    strcpy(cmd_buf,"setenv bootargs \"root=/dev/mtdblock2 console=ttySAC0,115200\"“);
    run_command(cmd_buf,0);
    run_command("saveenv",0);
    strcpy(cmd_buf, "dnw c0008000; nand erase 100000 300000 ; nand write.e 0xc0008000 100000 300000");
    printf("%s \n",cmd_buf);
    run_command(cmd_buf, 0);
    break;
case 'c':                //燒寫(xiě)cramfs文件系統(tǒng)
    strcpy(cmd_buf, "dnw 0xc0008000; nand erase 400000 5000000 ; nand write.e 0xc0008000 400000 5000000");
        printf("%s \n",cmd_buf);
    run_command(cmd_buf, 0);
        strcpy(cmd_buf, "setenv bootargs \"root=/dev/mtdblock2 rootfstype=cramfs console=ttySAC0,115200\"");
        printf("%s \n",cmd_buf);
    run_command(cmd_buf, 0);
        strcpy(cmd_buf, "saveenv");
        printf("%s \n",cmd_buf);
    run_command(cmd_buf, 0);
    break;
case 'b':                //bootm 重啟
    printf("Booting Linux ...\n");
    strcpy(cmd_buf, "nand read 0xc0008000 0x100000 0x300000;bootm 0xc0008000");
        printf("%s\n",cmd_buf);
    run_command(cmd_buf, 0);
    break;
case 'f':                //format flash
    strcpy(cmd_buf, "nand scrub");
        printf("%s\n",cmd_buf);
    run_command(cmd_buf, 0);
    break;
case 's':                //更改環(huán)境參數(shù)
    param_menu_shell();  這部分函數(shù)需要自己寫(xiě) :)
    break;
case 'q':                //退出菜單
    return;     
    break;
        }               
    }
}

4)、加入?yún)?shù)修改的菜單函數(shù)  

void param_menu_usage()
{
    printf("\r\n##### Parameter Menu #####\r\n");
    printf("[v] View the parameters\r\n");
    printf(" Set parameter \r\n");
    printf("[d] Delete parameter \r\n");
    printf("[w] Write the parameters to flash memeory \r\n");
    printf("[q] Quit \r\n");
    printf("[l] load env 1 \r\n");        //設(shè)置參數(shù)1,跟新系統(tǒng)時(shí)用
    printf("[m] load env 2 \r\n");        //設(shè)置參數(shù)2,更新完系統(tǒng)后恢復(fù)的參數(shù)
    printf("Enter your selection: ");
}
void param_menu_shell(void)
{
    char c;
    char cmd_buf[256];
    char name_buf[20];
    char val_buf[256];
    while (1)
    {
        param_menu_usage();
        c = getc();
        printf("%c\n", c);
        switch (c)
        {
            case 'v':
            strcpy(cmd_buf, "printenv ");
            run_command(cmd_buf, 0);
            break;
            
            case 's':
            sprintf(cmd_buf, "setenv ");
        printf("Name: ");
            readline(NULL);
            strcat(cmd_buf, console_buffer);
            run_command(cmd_buf, 0);
             break;
            
            case 'd':
                sprintf(cmd_buf, "setenv ");
                printf("Name: ");
                readline(NULL);
                strcat(cmd_buf, console_buffer);
                run_command(cmd_buf, 0);
                break;
            case 'w':
            sprintf(cmd_buf, "saveenv");
            run_command(cmd_buf, 0);
            break;
        
        case 'l':
        sprintf(cmd_buf, "setenv bootargs \"root=/dev/mtdblock2 console=ttySAC0,115200\"");
        printf("%s\n",cmd_buf);
        run_command(cmd_buf, 0);
//保存參數(shù)
        run_command("saveenv", 0);
        break;
            case 'm':
        sprintf(cmd_buf, "setenv bootargs \"root=/dev/mtdblock2 rootfstype=cramfs console=ttySAC0,115200\"");
        printf("%s\n",cmd_buf);
        run_command(cmd_buf, 0);
        run_command("saveenv", 0);
        break;
            case 'q':
                return;
                break;
        }
    }
}

三、重新編譯uboot,燒寫(xiě)進(jìn)入nand

第一次燒寫(xiě)需要按照手冊(cè)上的要求來(lái)做。燒寫(xiě)完后,從nand啟動(dòng),在讀秒時(shí)按空格就進(jìn)入我們上面設(shè)定的菜單了。可以很方便的進(jìn)行系統(tǒng)的更新。
沙發(fā)
發(fā)表于 2012-2-25 11:28:28 | 只看該作者
不錯(cuò)
板凳
發(fā)表于 2012-5-23 13:02:21 | 只看該作者
試一試
地板
發(fā)表于 2012-8-9 21:40:32 | 只看該作者
學(xué)習(xí)了

本版積分規(guī)則

關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點(diǎn)地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權(quán)所有   京ICP備16069177號(hào) | 京公網(wǎng)安備11010502021702
快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 天天干天天插天天 | 免费在线不卡视频 | 国产精品手机网站 | 亚洲欧美在线一区二区 | 毛片激情 | 久久网免费视频 | 热最近热久点 | 国产自产在线 | 美女在线网站视频免费观看 | 国产精品国产三级国产专业不 | 欧美日韩视频 | 麻豆精品视频在线 | 欧美日韩中文视频 | 亚洲免费综合色在线视频 | 久久国产精品国产自线拍免费 | 四虎影院永久网址 | 亚洲成人影院在线 | 四虎影视app| 美国性大片在线观看免费 | 高清视频 一区二区三区四区 | 日韩一区二区三区不卡视频 | 亚洲综合偷自成人网第页色 | 亚洲成年人在线 | 久久99精品久久久久久h | 国产精品久久毛片完整版 | xxxx性欧美| 香蕉视频在线播放 | 欧美性视频一区二区三区 | h视频免费看 | 老鸡视频91 | 日韩区 | 两个人免费完整高清视频中国 | 国产成人免费不卡在线观看 | 四虎影院新地址 | 男人天堂网www | 综合精品一区 | 欧美人体在线 | 国产精品99久久久 | 日韩在线视频线视频免费网站 | 极品美女国产精品免费一区 | 欧美日韩在线播放一区二区三区 |