Cómo entender el código fuente de uboot
1. Bootm carga la imagen de Linux cargando uIamge, lo cual se realiza mediante mkimage. La diferencia con zIamge es que uIamge está comprimido por zIamge. bootm necesita descomprimir uIamge primero y la dirección de descompresión es la dirección de entrada del kernel. Una vez completada la descompresión, uIamge y zIamge son casi iguales. Se pueden discutir las diferencias específicas. Actualmente, uboot solo admite el inicio de uImage, pero no admite el inicio de zImage.
2.Proceso de descompresión de bootm
-
##Arrancar la imagen en 08808000...
Nombre de la imagen: Linux-2.6 .14.7
Tipo de imagen: imagen del kernel ARM Linux (sin comprimir)
Tamaño de datos: 989172 bytes = 966 kB
Dirección de carga: 08008000
Punto de entrada: 08008000
Verificar suma de comprobación... OK
Extraer uIamge mediante el comando OK UBOOT BOOM
-
Iniciar el kernel...
Pasar los parámetros del kernel le da control a arch\arm\boot\compressed]head.s.
-
Por ejemplo, la dirección inicial de la memoria del equipo mx1ADS es 0x0000_0000 y se descarga a 0x 0800_800offset a través de tftp. El desplazamiento es mayor que 0x80_0000, que es. tftp 0x0880_8000, luego bootm 0x0880_8000 descomprime uIamge en 0x0080_8000 y la dirección de descompresión es MK.
La diferencia entre zImage y uImage 1. vmlinuz
Vmlinuz es un kernel comprimido de arranque. "vm" significa "memoria virtual". Linux admite memoria virtual, a diferencia de los sistemas operativos antiguos como DOS, que tienen un límite de memoria de 640 KB. Linux puede utilizar el espacio del disco duro como memoria virtual, de ahí el nombre "vm".
Hay dos formas de crear vmlinuz. Primero cree el kernel mediante "make zImage" en el momento de la compilación y luego generelo mediante "CP/usr/src/Linux-2.4/arch/i386/Linux/boot/zImage/boot/vmlinuz". ZImage es adecuado para núcleos pequeños y existe para compatibilidad con versiones anteriores.
En segundo lugar, el kernel se crea usando el comando make bzImage al compilar y luego se genera usando "CP/USR/SRC/Linux-2.4/ARCH/I386/Linux/boot/bzImage/boot/vmlinuz". . BzImage es una imagen del kernel comprimida. Cabe señalar que bzImage no está comprimido por bzip2. El bz en bzImage se malinterpreta fácilmente y bz significa "big zImage". La b en bzImage significa "grande". Tanto ZImage(vmlinuz) como bzImage(vmlinuz) están comprimidos con gzip. No sólo son un archivo comprimido, sino que el código de descompresión gzip también está incrustado al principio de ambos archivos. Por lo tanto, no puede usar gunzip o gzip -dc para descomprimir vmlinuz.
Dos. initrd-x.x.x.img
Initrd es la abreviatura de "disco ram inicial". Initiatrd se utiliza normalmente para iniciar temporalmente el hardware en un estado en el que el kernel vmlinuz real pueda tomar el control y continuar con el inicio.
El archivo de imagen initrd se crea usando mkinitrd. La utilidad mkinitrd crea un archivo de imagen initrd. Este comando es propiedad de RedHat. Otras distribuciones de Linux pueden tener comandos correspondientes. Esta es una utilidad muy útil.
Consulte la ayuda para obtener más información: man mkinitrd Utilice el siguiente comando para crear un archivo de imagen initrd.
Finalmente se generaron dos imágenes del kernel: zImage y uImage. Después de descargar zImage en la placa de destino, puede usar directamente el comando uboot para saltar. En este momento, el kernel se descomprime e inicia directamente. Sin embargo, el sistema de archivos no se puede montar porque el comando go no pasa los parámetros de inicio relevantes requeridos por el kernel al kernel. Para pasar los parámetros de arranque, debemos usar el comando bootm para saltar. El salto del comando Bootm solo procesa imágenes de uImage.
Existe la herramienta mkimage en el directorio tools/ del código fuente de uboot, que se puede utilizar para crear varios archivos de imagen de arranque comprimidos o sin comprimir.
Al crear un archivo de imagen, Mkimage agrega un encabezado de 0x40 bytes delante del archivo de imagen ejecutable original para registrar la información especificada por los parámetros, de modo que uboot pueda identificar qué estructura de sistema de CPU, qué sistema operativo, qué tipo e imagen. Dónde se carga en la memoria, dónde está el punto de entrada en la memoria y cuál es el nombre de la imagen.
El uso es el siguiente:
. /mkimage-A arch-O OS-T tipo-C comp-A dirección EP-n nombre-d datos _ archivo[:datos _ archivo...]imagen
-A == > Establecer arquitectura en "arch"
-O == >Establecer sistema operativo en "os"
-T == >Establecer tipo de imagen en "type" p>
-C == >Establecer tipo de compresión "comprimido"
-a == >Establecer dirección de carga en "dirección" (hexadecimal)
- e == >Establecer punto de entrada en "ep" (hexadecimal)
-n == >Establecer el nombre de la imagen en "nombre"
-d == > Usar datos de imagen en "archivo de datos"
-x ==>Establecer XIP (ejecución in situ)
Descripción del parámetro:
-A especifica la arquitectura de la CPU:
Estructura del sistema representada por valor
Alpha Alpha
Armado Arm
x86 Intel x86
ia64 IA64
mips
MIPS 64 64 bits
ppc
IBM S390
sh SuperH
sparc SPARC
sparc64 SPARC 64-bit
m68k MC68000
-O especifica el tipo de sistema operativo, se pueden utilizar los siguientes valores:
openbsd, netbsd, freebsd, 4_4bsd, linux, svr4, esix, solaris, irix, sco, dell, ncr, lynxos, vxworks, psos, qnx, u-boot, rtems, artos
-T Para especificar el tipo de imagen, lo siguiente se pueden utilizar valores:
Máquina única, kernel, disco de memoria, múltiple, firmware, script, sistema de archivos
-C Para especificar la fórmula de compresión de imágenes, se utilizan los siguientes valores se puede utilizar:
Sin compresión
Gzip utiliza el método de compresión gzip.
La fórmula de compresión de bzip2 es bzip2
-a especifica la dirección de carga de la imagen en la memoria. Cuando la imagen se descarga a la memoria, se debe descargar de acuerdo con el valor de dirección especificado por este parámetro al crear la imagen con mkimage.
-e especifica la dirección del punto de entrada donde se ejecuta la imagen, que es el valor especificado por el parámetro -a más 0x40 (porque se agrega un encabezado de 0x40 bytes delante de mkimage).
-n especifica el nombre de la imagen.
-d especifica el archivo fuente utilizado para el mapeo.
Los comandos que utilicé durante la compilación son los siguientes:
#Make zImage //Generar imagen zImage
#/usr/local/arm/K9 uboot/ herramientas /mkimage-n 'Linux 2 4 27 '-A arm-O Linux-T
kernel-C none-a 0x 20007 fc0-e 0x 20008000-d zi mage uImage
.La imagen del kernel está lista, en este punto prepararemos el sistema de archivos. Debido a limitaciones de tiempo, utilizo temporalmente k9.img.gz, un sistema de archivos desarrollado por otros. Lo que debemos hacer en este momento es escribir un programa hello.c simple nosotros mismos, compilarlo y agregarlo al sistema de archivos, y luego descargarlo a la placa de destino y ejecutarlo.
Escribe hello.c primero;
Compila:
#/usr/local/arm/2. 95. 3/bin/arm-Linux-gcc. –o start-hello hola. c
El archivo ejecutable start-hello se genera después de la compilación.
A continuación, debemos agregar el archivo ejecutable al sistema de archivos, de la siguiente manera:
#ganz·k9.img.gz//Descompresión
#mount –olooopk9.img/mnt/new disk//mount
#cp start-hello /mnt/new_disk //Copiar archivos al sistema de archivos.
# CD/mnt/nuevo disco
# umount/mnt/nuevo_disco//desinstalar
# gzip–c–v9k 9 . ;K9.img.gz//la compresión genera el sistema de archivos final.
A continuación, descargaremos el kernel y prepararemos el sistema de archivos. Permítanme explicar mi asignación de memoria de la siguiente manera:
flash:
0x 10000000--0x 10020000 boot
0x 10020000--0x 10040000 uboot
0x 10040000――0x 10060000
0x 10060000――0x 10200000 núcleo
0x 10200000――0x 11000000 disco de memoria
Sdram:
p>
0x 20007 fc0――0x20a 00000 kernel
0x20a00000――Disco de memoria
Loadb descarga datos a la RAM a través del puerto serie.
Cp.b copia los datos de la ram al flash.
Después de descargar el kernel y el disco ram del sistema de archivos, también necesitamos configurar las variables de entorno de uboot para que uboot pueda iniciar el kernel y otras operaciones cuando esté encendido. Las variables de entorno se configuran de la siguiente manera:
set cpfltoram CP b 10200000 20a 00000 18 ffff//Copie el sistema de archivos en la RAM.
Establecer bootm 20007fc0 //Iniciar el kernel.
set bootcmd run cpfltoker \; run cpfltoram \; run boot//uboot reset comando de ejecución.
Establezca cpfltoker CP . b 10060000 20007 fc 0 f 4 fff//Copie el kernel a la RAM.
set bootargs root =/dev/ram rw initrd = 0x20a 00000, 4M init=/linuxrc console=ttyS0, 11520
0, mem = 32m//uboot pasado al kernel Parámetros de arranque.
Una vez completada la configuración, saveenv almacena las variables de entorno.
Experiencia de aprendizaje: zImage y uImage son archivos de imagen del kernel ejecutables generados.
La forma de iniciarlos en u-boot es ir a addr y bootm addr respectivamente para implementar el proceso de inicio.
En otras palabras, zImage se inicia con go y uImage se inicia con m.
La relación entre zImage y uImage 2 es que uImage es generado por zImage a través de mkimage (una herramienta en herramientas en u-boot).
El resultado es que el encabezado de este último tiene 64 bytes más que el primero, y los 64 bytes adicionales se utilizan para notificar a u-boot. Cuéntale esto a Uber;
Entonces, cuando u-boot arranca el kernel, hay dos direcciones: dirección de carga y dirección de entrada 2. La diferencia entre ellas es solo 0x40 (64 bytes).
Cuando se usa bootm loadaddress de esta manera, u-boot se ajustará de acuerdo con la dirección de carga correspondiente. Hay dos situaciones
1) Cuando loadaddress y mkimage son iguales:
p>
Luego, al cargar ldrpc y la dirección de entrada, se seleccionará la dirección de entrada de mkinage; es decir, PC = dirección de carga+4, luego el proceso de control de la PC salta a la memoria RAM inversa para su ejecución;
2) Cuando loadaddress Cuando es inconsistente con mkimage:
Luego, después de comparar las direcciones, u-bbot restará 64 bytes de la dirección de carga actual y convertirá la imagen real del kernel (el kernel con 64 bytes). encabezado de bytes eliminado) Copie a la dirección de carga preestablecida y luego inicie el kernel directamente desde esta dirección de carga;
En resumen, ¿cuál es la diferencia real entre las dos situaciones anteriores? De hecho, al ejecutar el código final, si la dirección no coincide con la especificada en mkinage, u-boot copiará el código del kernel, eliminará el archivo de encabezado y lo ejecutará directamente. Si no se procesa, el kernel se ejecutará con loadaddress+0x40;
Descargue zImage o uImage a través del servicio tftp;
Cuando tftp falla, Loadb usa el puerto serie para descargar el kernel. Espero que este método no se utilice.
Cp.b\. w\. l Complete la copia de la memoria a la memoria flash.
Finalmente, puede configurar la variable de entorno bootcmd para permitir que u-boot inicie automáticamente el kernel.
En cuanto a las dos formas de sistema de archivos: ramdisk y nfs, se recomienda que los desarrolladores utilicen nfs para facilitar la modificación.
Cuando utilicen ramdisk,
#; Gonz· k9.img.gz//Descomprimir
# mount–olooopk9.img/mnt/new _disk//suspension load
# umount/mnt/new_disk//uninstall
# gzip–c–v9k 9. img & gt; K9.img.gz//la compresión genera el sistema de archivos final.
No olvides lo poderosos que son estos cuatro comandos para ti.
No quiero que vuelvas a construir el sistema de archivos raíz.