Cómo leer mac desde uboot y pasarlo al kernel
Este artículo toma principalmente como ejemplos el U-boot que pasa la RAM y el kernel de Linux que lee los parámetros de la RAM.
1. U-boot pasa los parámetros de RAM al kernel
En el archivo /common/cmd_bootm.c (refiriéndose al directorio raíz de Uboot), la función do_bootm corresponde a. comando bootm Al analizar uImage La información en Discovery se llama cuando el sistema operativo es Linux.
En la función do_bootm_linux:
void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],\
ulong addr, ulong *len_ptr, int verificar)
{
......
#if definido (CONFIG_SETUP _MEMORY_TAGS) ||
definido (CONFIG_CMDLINE_TAG) ||
definido (CONFIG_INITRD_TAG) ||
definido (CONFIG_SERIAL_TAG)||
definido (CONFIG_SERIAL_TAG) ||
definido (CONFIG_REVISION_TAG) ||
definido (CONFIG_LCD) ||
definido (CONFIG_VFD)
setup_start_tag (bd); //inicializa el inicio de la etiqueta struct
#ifdef CONFIG_SERIAL_TAG
setup_serial_tag (?ms);
#endif
#ifdef CONFIG_REVISION_TAG
setup_revision_tag (?ms);
#endif
#ifdef CONFIG_SETUP_MEMORY_TAGS
setup_memory_tags (bd);/ Establecer parámetros de RAM
#endif
#ifdef CONFIG_ CMDLINE_TAG
setup_commandline_tag (bd, línea de comando);
#endif
#ifdef CONFIG_INITRD_TAG
if (initrd_start && initrd_end)
setup_initrd_tag (bd, initrd_start, initrd_end);
#endif
#if definido ( CONFIG_VFD) || definido (CONFIG_LCD)
setup_videolfb_tag ((gd_t *) gd);
#endif
setup_end_tag (bd); de la estructura de la etiqueta de inicialización
#endif
.
...
......
theKernel (0, machid, bd->bi_boot_params);
// Parámetros pasados al Kernel = ( etiqueta struct *) de tipo bd->bi-boot_params
// bd->bi-boot_params se inicializa en la función board_init. Por ejemplo, para at91rm9200, la inicialización se completa en board_init de at91rm9200dk.c. of: bd->bi-boot _params=PHYS_SDRAM + 0x100;
// Esta dirección también es la primera dirección de todas las listas de etiquetas; consulte la función setup_start_tag a continuación
}
Para las funciones setup_start_tag y setup_memory_tags, se proporcionan las siguientes descripciones.
La función setup_start_tag también se define en este archivo de la siguiente manera:
static void setup_start_tag (bd_t *bd)
{
params = ( struct tag *) bd->bi_boot_ params;
// Inicializa los parámetros de la variable global del tipo (struct tag *) en la dirección de bd->bi_boot_params y luego configura los parámetros relacionados con la etiqueta. Las funciones (como las siguientes setup_memory_tags) colocan los datos de otras etiquetas en la dirección de desplazamiento de esta dirección.
params->hdr.tag = ATAG_CORE;
params->hdr.size = tag_size (tag_core);
params->u.core.flags; = 0;
params->u.core.gt;u.core.pagesize = 0;
params->u.core.rootdev = 0;
params = tag_next (params);
}
Los parámetros relacionados con la RAM se inicializan en la función bootm.c setup_memory_tags.
c:
setup_memory_tags vacío estático (bd_t *bd)
{
int i;
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
params->hdr.tag = ATAG_MEM;
params->hdr.size = tag_size (tagmags)size = tag_size (tag_mem32);
params ->u.mem.start = bd->bi_dram[i].start;
params->u.mem.size = bd->bi_dram[i].size;
params = tag_next (params);
}//Inicializar etiquetas relacionadas con la memoria
}
2. boot
Para el kernel de Linux, cuando se inicia la plataforma ARM, primero ejecuta arch/arm/kernel/head.S, llamando a arch/arm/kernel/head-common.S y arch/arm/mm. /proc-arm920.S y funciones en arch/arm/mm/proc-arm920.S. La función start_kernel llama a la función setup_arch para manejar varias operaciones relacionadas con la plataforma, incluido el análisis y guardar los parámetros pasados por u-boot:
start_kernel()
{
......
setup_arch (&command_line);
......
}
Entre ellos , setup_arch La función se implementa en el archivo arch/arm/kernel/setup.c de la siguiente manera:
void __init setup_arch (char **cmdline_p)
{
struct tag * tags = (struct tag *)&init_tags;
struct machine_desc * mdesc;
char *from = default_command_line;
setup_processor();
mdesc = setup_machine (machine_arch_type);
machine_ name = mdesc->nombre;
if (mdesc->soft_reboot)
reboot_setup("s" );
if (__atags_pointer)//Puntero a la posición inicial de varias etiquetas, definida de la siguiente manera:
// unsigned int __atags_pointer __initdata;
/ / Este puntero apunta al segmento __initdata, que almacena diversa información de etiquetas.
tags = phys_to_virt(__atags_pointer);
else if (mdesc->boot_params)
tags = phys_to_virt(mdesc->boot_params
);if (etiquetas->hdr.tag ! = ATAG_CORE)
convert_to_tag_list (etiquetas
if (etiquetas->hdr.tag ! = ATAG_CORE)
tags = (struct tag *)&init_tags;
if (mdesc->fixup)
mdesc->fixup(mdesc, tags, &from, &.meminfo);
if (etiquetas->hdr.tag == ATAG_CORE) {
if (meminfo.nr_banks ! = 0)
squash_mem_tags (etiquetas);
save_atags (etiquetas);
parse_tags (etiquetas);
// Procesa varias etiquetas, incluido el procesamiento de parámetros de RAM.
// Esta función maneja las siguientes etiquetas:
__tagtable(ATAG_MEM, parse_tag_mem32);
__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext); > __tagtable (ATAG_RAMDISK, parse_tag_ramdisk);
__tagtable (ATAG_SERIAL, parse_tag_serialnr);
__tagtable (ATAG_REVISION, parse_tag_revision);
__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
}
init_mm.start_code = (largo sin firmar) &_text;
init_mm.end_code = (largo sin firmar) &_etext;
init_mm .end_data = (largo sin firmar) &_edata;
init_mm.end_code = (largo sin firmar) &_etext;
init_mm.end_data = (largo sin firmar) &_edata;