The embedded linux Development uboot transplant ( 6、 ... and )——uboot environment variable

One 、uboot Introduction to environment variables

    u-boot By default, there are some basic environment variables , When executed saveenv when , Environment variables are saved to flash In the storage device . If the value of the environment variable is empty , be uboot Will use uboot Values in the code ; If the environment variable is not empty , The values of environment variables are preferred . The default environment variable is in uboot Source code common/Env_common.c In file .

 

  1. uchar default_environment[CFG_ENV_SIZE] = {

  2. #ifdef CONFIG_BOOTARGS

  3. "bootargs="CONFIG_BOOTARGS"\0"

  4. #endif

  5. #ifde fCONFIG_BOOTCOMMAND

  6. "bootcmd="CONFIG_BOOTCOMMAND"\0"

  7. #endif

  8. #ifdef CONFIG_MTDPARTITION

  9. "mtdpart="CONFIG_MTDPARTITION"\0"

  10. #endif

  11. #ifdef CONFIG_RAMBOOTCOMMAND

  12. "ramboot="CONFIG_RAMBOOTCOMMAND"\0"

  13. #endif

  14. #ifdef CONFIG_NFSBOOTCOMMAND

  15. "nfsboot="CONFIG_NFSBOOTCOMMAND"\0"

  16. #endif

  17. #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)

  18. "bootdelay="MK_STR(CONFIG_BOOTDELAY)"\0"

  19. #endif

  20. #if defined(CONFIG_BAUDRATE) && (CONFIG_BAUDRATE >= 0)

  21. "baudrate="MK_STR(CONFIG_BAUDRATE)"\0"

  22. #endif

  23. #ifdef CONFIG_ETHADDR

  24. "ethaddr="MK_STR(CONFIG_ETHADDR)"\0"

  25. #endif

  26. #ifdef CONFIG_IPADDR

  27. "ipaddr="MK_STR(CONFIG_IPADDR)"\0"

  28. #endif

  29. #ifdef CONFIG_SERVERIP

  30. "serverip="MK_STR(CONFIG_SERVERIP)"\0"

  31. #endif

  32. #ifdef CONFIG_GATEWAYIP

  33. "gatewayip="MK_STR(CONFIG_GATEWAYIP)"\0"

  34. #endif

  35. #ifdef CONFIG_NETMASK

  36. "netmask="MK_STR(CONFIG_NETMASK)"\0"

  37. #endif

  38. #ifdef CONFIG_HOSTNAME

  39. "hostname="MK_STR(CONFIG_HOSTNAME)"\0"

  40. #endif

  41. #ifdef  CONFIG_EXTRA_ENV_SETTINGS

  42. CONFIG_EXTRA_ENV_SETTINGS

  43. #endif

  44. "\0"

  45. };

     All environment variables are stored in a 16KB In a one-dimensional array of sizes , Each environment variable is represented by "\0" end .uboot When it starts , In traversal call execution init_sequence In an array of function pointers env_init Function has checked the environment variables , By calling env_relocate function , Change the environment variable from Flash Start device relocation to SDRAM in .uboot The initialization of environment variables at startup is as follows :

wKioL1dvNqTzTZ1CAAFp2SBs5qA066.png

Examples of using environment variables :

setenv  bootcmd "nand read 0x20008000 0x80000 0x500000;bootm 0x30008000"

saveenv

common uboot environment variable :

bootdelay     Automatic execution in seconds
 baudrate     Baud rate of serial console
 netmask     The mask of the Ethernet Interface
 ethaddr      The physical address of the Ethernet card
 bootfile     The default download file
 bootargs     Boot parameters passed to the kernel
 bootcmd     Commands executed at auto start
 serverip     Server side ip Address
 ipaddr      Local ip Address
 stdin       Standard input devices
 stdout      Standard output equipment
 stderr      Standard error device

 

Two 、 Source code analysis of environment variable operation

     In the operation of environment variables ,u-boot The general function interface called to operate on environment variables is located at common/env_common.c file , Environment variables are stored in different startup devices, and operation function interfaces are stored in different files , Such as common/env_epprom.c、common/env_flash.c、common/env_nand.c, The operation function interface for environment variables is stored in common/env_nvedit.c.

1、printenv

 

  1. int do_printenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])

  2. {

  3. int i, j, k, nxt;

  4. int rcode = 0;

  5. if (argc == 1) {//printenv When the command has no parameters, all variable information is printed out

  6. for (i=0; env_get_char(i) != '\0'; i=nxt+1) {// Traversing variables in an environment variable array

  7. for (nxt=i; env_get_char(nxt) != '\0'; ++nxt)// Traverse the variable to get the number of characters

  8. ;

  9. for (k=i; k<nxt; ++k) Traverse and print out the variable information

  10. putc(env_get_char(k));

  11. putc  ('\n');// After the output of variable information, print the new line

  12. if (ctrlc()) {

  13. puts ("\n ** Abort\n");

  14. return 1;

  15. }

  16. }

  17. printf("\nEnvironment size: %d/%ld bytes\n",

  18. i, (ulong)ENV_SIZE);

  19. return 0;

  20. }

  21. for (i=1; i<argc; ++i) {// Traversal prints information about a single or multiple variables

  22. char *name = argv[i];

  23. k = -1;

  24. for (j=0; env_get_char(j) != '\0'; j=nxt+1) {// Traversing multiple environment variables for printing

  25. for (nxt=j; env_get_char(nxt) != '\0'; ++nxt)// Traversal calculates the number of characters in a variable

  26. ;

  27. k = envmatch((uchar *)name, j);// Find out if the variable exists

  28. if (k < 0) {

  29. continue;

  30. }

  31. puts (name);

  32. putc ('=');

  33. while (k < nxt)// Print variable information

  34. putc(env_get_char(k++));

  35. putc ('\n');

  36. break;

  37. }

  38. if (k < 0) {

  39. printf ("## Error: \"%s\" not defined\n", name);

  40. rcode ++;

  41. }

  42. }

  43. return rcode;

  44. }

2、setenv

 

  1. int do_setenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])

  2. {

  3. if (argc < 2) {//setenv Command input processing without parameters

  4. printf ("Usage:\n%s\n", cmdtp->usage);

  5. return 1;

  6. }

  7. return _do_setenv (flag, argc, argv);

  8. }

3、saveenv

 

  1. int do_saveenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])

  2. {

  3. extern char * env_name_spec;

  4. printf ("Saving Environment to %s...\n", env_name_spec);

  5. return (saveenv() ? 1 : 0);

  6. }

  7. int saveenv(void)

  8. {

  9. movi_write_env(virt_to_phys((ulong)env_ptr));// Write the listed environment variables to SD card

  10. puts ("done\n");

  11. return 1;

  12. }

4、 String parsing

uboot The operation of environment variable in makes full use of the parsing of environment variable string . This part will extract the string analysis for analysis .

Environment variables are stored in default_environment[CFG_ENV_SIZE] Array , Each environment variable is represented by "\0" end . Through the array of environment variables default_environment[CFG_ENV_SIZE] To analyze , Print out the environment variables separately .

Experiment source code :

 

  1. #include <stdio.h>

  2. unsigned char environment[] = 

  3. {

  4.     "bootdelay="    "10"    "\0"

  5.     "ipaddr="   "192.168.1.210" "\0"

  6.     "serverip=" "192.168.1.200" "\0"

  7.     "bootcmd="  "tftp 0x20008000 uImage;bootm 0x20008000"   "\0"

  8.     "baudrate=" "115200"    "\0"

  9. };

  10. int main(int argc, char **argv)

  11. {

  12.     int i, s,k;

  13.     for(i = 0; *(environment+i) != '\0'; i = s + 1) // Traverse environment variable array according to variable

  14.     {   //

  15.         for(s = i; *(environment + s) != '\0'; s++)// Calculate the number of characters in the variable

  16.             ;   

  17.         for(k = i; k < s; k++)// Print out the variable information

  18.             putc( *(environment + k), stdout);

  19.         putc('\n', stdout);

  20.     }   

  21.     return 0;

  22. }

Compile run results :

bootdelay=10

ipaddr=192.168.1.210

serverip=192.168.1.200

bootcmd=tftp 0x20008000 uImage;bootm 0x20008000

baudrate=115200

3、 ... and 、uboot Medium SD/MMC Device drivers

1、uboot Medium SD/MMC Initialization of the device

    uboot In the second phase of the launch BL2 Of start_armboot Function in the initialization part of the development board mmc_initialize Function pair SD/MMC Device initialization , Initialization is divided into two parts :

 

A、cpu_mmc_init

cpu_mmc_init Function completion to SoC Inside SD/MMC Initialization of the controller , Including the use of setup_hsmmc_clock Function initialization SD/MMC The clock of the controller ,setup_hsmmc_cfg_gpio Function initialization SoC in SD/MMC Controller GPIO Pin .

On return smdk_s3c_hsmmc_init function ,smdk_s3c_hsmmc_init according to SD/MMC Channel calls function s3c_hsmmc_initialize initialization struct mmc Properties and operation methods of structure instances .struct mmc The operation method of the structure instance specifies SD/MMC Methods and functions for operating hardware devices .

 

B、mmc_init

mmc_init Function completion to SD/MMC Initialization of hardware devices .mmc_init Function internal through the call mmc_go_idle、mmc_send_if_cond、mmc_send_app_op_cond、mmc_send_cmd And so on struct mmc Operation method in structure instance send_cmd、set_ios、init Attached s3c_hsmmc_send_command、s3c_hsmmc_set_ios、s3c_hsmmc_init Hardware operation function , Finally, yes SD/MMC Initialization of hardware devices .

SD/MMC Device drivers stuct mmc The structure encapsulates SD/MMC The properties and operation methods of the device .

 

  1. struct mmc {

  2. struct list_head link;

  3. char name[32];

  4. void *priv;

  5. uint voltages;

  6. uint version;

  7. uint f_min;

  8. uint f_max;

  9. int high_capacity;

  10. uint bus_width;

  11. uint clock;

  12. uint card_caps;

  13. uint host_caps;

  14. uint ocr;

  15. uint scr[2];

  16. uint csd[4];

  17. uint cid[4];

  18. ushort rca;

  19. uint tran_speed;

  20. uint read_bl_len;

  21. uint write_bl_len;

  22. u32 capacity;

  23. struct mmc_ext_csdext_csd;/* mmc v4 extended card specific */

  24. block_dev_desc_t block_dev;

  25. int (*send_cmd)(struct mmc *mmc,

  26. struct mmc_cmd *cmd, struct mmc_data *data);

  27. void (*set_ios)(struct mmc *mmc);

  28. int (*init)(struct mmc *mmc);

  29. };

SD/MMC Device driver building is about SD/MMC Equipment structure struct mmc Initialization of type instances .

 

2、uboot Chinese vs SD/MMC Operation of equipment

saveenv Command to save environment variables to Flash The device needs to call the driver operation Flash equipment .uboot The hardware driver is from linux kernel Transplanted .saveenv The command function of is do_saveenv.saveenv The workflow of saving environment variables with the command is as follows :

A、 call common/cmd_nvedit.c in do_saveenv function

int do_saveenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])

{

extern char * env_name_spec;

printf ("Saving Environment to %s...\n", env_name_spec);

return (saveenv() ? 1 : 0);

}

B、 call common/env_auto.c In file saveenv function :

 

  1. int saveenv(void)

  2. {

  3. #if defined(CONFIG_S5PC100) || defined(CONFIG_S5PC110) || defined(CONFIG_S5P6442)

  4. if (INF_REG3_REG == 2)

  5. saveenv_nand();// Environment variables are saved to nand equipment

  6. else if (INF_REG3_REG == 3)

  7. saveenv_movinand();// Environment variables are saved to SD/MMC equipment

  8. else if (INF_REG3_REG == 1)

  9. saveenv_onenand();

  10. else if (INF_REG3_REG == 4)

  11. saveenv_nor();

  12. #elifdefined(CONFIG_SMDK6440)

  13. if (INF_REG3_REG == 3)

  14. saveenv_nand();

  15. else if (INF_REG3_REG == 4 || INF_REG3_REG == 5 || INF_REG3_REG == 6)

  16. saveenv_nand_adv();

  17. else if (INF_REG3_REG == 0 || INF_REG3_REG == 1 || INF_REG3_REG == 7)

  18. saveenv_movinand();

  19. #else   // others

  20. if (INF_REG3_REG == 2 || INF_REG3_REG == 3)

  21. saveenv_nand();

  22. else if (INF_REG3_REG == 4 || INF_REG3_REG == 5 || INF_REG3_REG == 6)

  23. saveenv_nand_adv();

  24. else if (INF_REG3_REG == 0 || INF_REG3_REG == 7)

  25. saveenv_movinand();

  26. else if (INF_REG3_REG == 1)

  27. saveenv_onenand();

  28. #endif

  29. else

  30. printf("Unknown boot device\n");

  31. return 0;

  32. }


 

C、 call common/env_auto.c In file saveenv_movinand function

int saveenv_movinand(void)

{

#if defined(CONFIG_CMD_MOVINAND)

        movi_write_env(virt_to_phys((ulong)env_ptr));

        puts("done\n");

 

        return 1;

#else

return 0;

#endif/* CONFIG_CMD_MOVINAND */

}

 

E、 call cpu/s5pc11x/movi.c In the document movi_write_env function

void movi_write_env(ulong addr)

{

movi_write(raw_area_control.p_w_picpath[2].start_blk,

   raw_area_control.p_w_picpath[2].used_blk, addr);

}

 

F、 call drivers/mmc/mmc.c In file movi_write function

ulong movi_write(ulong start, lbaint_t blkcnt, void *src)

{

return mmc_bwrite(0, start, blkcnt, src);

}

 

G、 call drivers/mmc/mmc.c In file mmc_bwrite function , The final call drivers/mmc/s3c_hsmmc.c In file s3c_hsmmc_send_command Function to save and write data .

3、uboot Driver layering in

    uboot China and SD/MMC The device related operation interface functions are located in drivers/mmc/mmc.c In file , These interface functions eventually point to struct mmc Function pointer members of structs . And SD/MMC The device hardware related operation function interface is located in drivers/mmc/s3c_hsmmc.c In file , Mainly SoC Inside SD/MMC The controller is right SD/MMC Operation of equipment , Such as SD/MMC The device's command sending function s3c_hsmmc_send_command、SD/MMC The data read and write function of the device s3c_hsmmc_set_ios.SD/MMC The device driver builds the initialization function in the driver s3c_hsmmc_initialize Lieutenant general struct mmc The function pointer in the struct instance corresponds to SD/MMC The interface of equipment operation method is connected .

    uboot Will be right SoC Internal and SD/MMC Initialization functions related to the device, such as setup_hsmmc_clock、setup_hsmmc_cfg_gpio It's in the relationship with SoC Related file directory cpu/s5pc11x/setup_hsmmc.c In file .

uboot For in the linux The inheritance and transplantation of device driver layer greatly facilitates the developers to uboot Transplantation .