Red de conocimiento informático - Material del sitio web - Cómo leer mac desde uboot y pasarlo al kernel

Cómo leer mac desde uboot y pasarlo al kernel

U-boot pasa una gran cantidad de parámetros al kernel de Linux, como puerto serie, memoria, videofb, etc. El kernel de Linux lee y procesa estos parámetros. Los parámetros se pasan entre los dos a través de etiquetas de estructura. U-boot guarda las cosas que se pasarán al kernel en la estructura de datos de la etiqueta de estructura. Al iniciar el kernel, la dirección física de esta estructura se pasa al kernel y usa parse_tags para analizar los parámetros pasados; .

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;