Cómo implementar el paso de parámetros entre uboot y Linux
Este artículo toma principalmente como ejemplos U-boot que pasa RAM y parámetros de lectura del kernel de Linux.
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), el comando bootm corresponde a. la función do_bootm Al analizar Cuando la información en uImage encuentra que el sistema operativo es Linux, se llama.
En la función do_bootm_linux:
void do_bootm_linux (cmd_tbl_t *cmdtp, int. bandera, int argc, char *argv[] ,\
ulong addr, ulong *len_ptr, int verificar)
{
......
#si está definido (CONFIG_SETUP_MEMORY_TAGS) ||\
definido (CONFIG_CMDLINE_TAG) ||
definido (CONFIG_INITRD_TAG) ||\
definido(CONFIG_SERIAL_TAG) ||\
definido (CONFIG_REVISION_TAG) ||\
definido (CONFIG_LCD) ||
definido (CONFIG_VFD)
setup_start_tag (bd); //inicializar etiqueta struct start
#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 &&
# ifdefinido (CONFIG_VFD) ||definido (CONFIG_LCD)
setup_videolfb_tag ((gd_t *) gd) ;
#endif
setup_end_tag (bd); //estructura de etiqueta final de inicialización
#endif
.
.....
......
theKernel (0, machid, bd->bi-boot_params
// pasado a); Parámetros del kernel = (etiqueta de estructura *) -tipo bd->bi-boot_params
// bd->bi-boot_params se usa en board_boot_structure. los parámetros se inicializan en la función board_init, por ejemplo, para at91rm9200, los parámetros se inicializan en la función board_init. Para at91rm9200, la inicialización se completa en board_init de at91rm9200dk.c: bd->bi-boot_params=PHYS_SDRAM + 0x100;
// Esta dirección también es la primera dirección de todas las listas de etiquetas; consulte setup_start_tag a continuación Funciones
}
Las funciones setup_start_tag y setup_memory_tags se describen a continuación.
La función setup_start_tag también se define en el 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. funciones (como las siguientes Los datos de setup_memory_tags) se colocan en la dirección de desplazamiento de esta dirección.
Parámetro->hdr.tag = ATAG_CORE;
Parámetro->hdr.size = tag_size (tag_core);
Parámetro->u.core.flags = 0;
Parámetros->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 bootm en la función setup_memory_tags:
static void setup_memory_tags (bd_t * bd )
{
int i;
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
params->hdr.tag = ATAG_MEM ;
Parámetro->hdr.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);
} // La inicialización está relacionada a la función de memoria.
//Inicializar marcadores relacionados con la memoria
}
2. El kernel lee los parámetros relevantes pasados por U-boot
Para el kernel de Linux, cuando el ARM se inicia la plataforma, primero ejecuta arch/arm/kernel/head.S, llama a funciones en arch/arm/kernel/head-common.S y arch/arm/mm/proc-arm920, y finalmente llama a start_kernel:
......
b start_kernel
......
La función start_kernel en init/main.c llama a setup_arch función para procesar cada operación relacionada con la plataforma, incluido el análisis y el guardado de parámetros pasados por u-boot:
start_kernel()
{
.... ..
setup_arch(&command_line);
......
}
La función setup_arch está en arch/arm /kernel/setup La función setup_arch en el archivo .c se implementa de la siguiente manera:
void __init setup_arch(char**cmdline_p)
{
etiqueta de estructura *tags = (struct tag * )&init_tags;
struct machine_desc *mdesc;
char *from = default_command_line;
setup_processor() ;
mdesc = setup_machine( machine_arch_type);
nombre_máquina = mdesc->nombre;
if (mdesc->soft_reboot)
reboot_ setup("s ");
if (__atags_pointer)
// Punteros a las posiciones iniciales de varias etiquetas, definidos de la siguiente manera:
///unsigned int __atags_pointer __initdata ;
/// Este puntero apunta al segmento __ initdata, que almacena diversa información de etiquetas.
etiquetas = phys_to_virt(__atags_pointer);
else if (mdesc->boot_params)
etiquetas = phys_to_virt(mdesc->boot_params
);if (etiquetas->hdr.tag ! = ATAG_CORE)
convert_to_tag_list(etiquetas);
if (etiquetas->hdr.tag ! = ATAG_CORE)
convert_to_tag_list(etiquetas);
if (etiquetas->hdr.tag ! = ATAG_CORE)
if (etiquetas->hdr.tag !tag ! = ATAG_CORE) p>
etiquetas = (estructura etiqueta *)&init_tags;
if (mdesc->fixup)
mdesc->fixup(mdesc, etiquetas, &from, &. meminfo) ;
if (tags->hdr.tag == ATAG_CORE) {
if (meminfo.nr_banks !
// 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;