¿Explicación detallada del proceso de inicio del sistema WinCE 6.0?
En Windows CE 6.0, el kernel (Kenerl) y el código OEM se dividen en tres partes: oal.exe, kernel.dll y kitl.dll. el código de inicio y la implementación de la capa OAL ya no están vinculados con el kernel para generar NK .exe. En cambio, el código de inicio (inicio) y la implementación de la capa OAL dependiente del hardware e independiente del kernel se compilan en oal.exe. exe, en cambio, el código de inicio (inicio) y la implementación de la capa OAL relacionada con el hardware e independiente del kernel se compilan en oal.exe, mientras que la implementación de la capa OAL relacionada con el kernel e independiente del hardware se incluyen en el kernel. dll; el código de soporte de la capa de transporte independiente del kernel (KITL) se separa de la capa OAL y se compila en kitl.dll.
En la superficie, parece que el kernel no está vinculado al kernel para generar NK.dll, sino que la implementación de la capa OAL se compila en kitl.dll junto con kernel.dll y kitl. dll.
En la superficie, el código parece haber sido reensamblado y el puerto BSP en la documentación de ayuda parece el mismo, pero de hecho, todo el diseño del kernel de Windows CE 6.0 ha sufrido cambios significativos y Windows CE 6.0 El proceso de inicio es el mismo. Si intenta analizar la secuencia de inicio de Windows CE 6.0 en términos de Windows CE 5.0, puede llegar a un callejón sin salida. La razón principal es que Windows CE 6.0 llama a dos bibliotecas de vínculos dinámicos (kernel.dll y kitl.dll) durante el proceso de inicio, y Windows CE 6.0 ya no compila ni genera el archivo del kernel KernKitlProf.exe.
Se puede ver en el documento de ayuda de Windows CE 6.0 que el inicio de WinCE 6.0 solo está relacionado con oal.exe y kernel.dll. En cuanto a kitl.dll, solo se usa al compilar un. Sistema operativo con función KITL. Al analizar el proceso de inicio de Windows CE 6.0, encontramos la ubicación del código fuente donde se compilan oal.exe y kernel.dll.
Primero, compila WinCE 6.0 en un caso de kernel básico, como WinCE 5.0, que es kernel.exe. Encontrar la ubicación de origen de oal.exe es más fácil porque oal.exe es un código de inicio compilado con los archivos de implementación de la capa OAL dependientes del hardware, así que búsquelo en el directorio OAL del BSP. En cuanto a kernel.dll, es básicamente imposible encontrar el archivo compilado kernel.dll en la estructura del directorio BSP, por lo que debemos comenzar desde otros aspectos.
El siguiente archivo de salida del registro de compilación para WinCE 6.0: makeimg.out es parte del proceso de copia del archivo:
Copiar E:\WINCE600\OSDesigns\xsbase270\xsbase270\RelDir\XSBase270_ARMV4I _Release\ oal.Copiar E:\WINCE600\OSDesigns\xsbase270\xsbase270/RelDir\XSBase270_ARMV4I_Release\nk.exe a E:\WINCE600\OSDesigns\xsbase270\xsbase270/RelDir\XSBase270_ARMV4I_Release\kern.dll a E:\W INCE60 0\OSDiseños \xsbase270\ xsbase270\RelDir\XSBase270 _ARMV4I_Release\kernel.dll para usar con el depurador
Como se puede ver en el archivo de salida del registro, el compilador WinCE 6.0 cambió el nombre de oal.dll a oal durante el proceso de copia del archivo .dll. 0 El compilador cambió el nombre de oal.exe a nk.exe y kernel.dll a kernel.dll, lo que significa que la parte de implementación del archivo kernel.dll es kernel.dll. En otras palabras, la implementación de kernel.dll es la implementación de kernel.dll. Según el análisis anterior, oal.exe es la implementación de la capa OAL independiente del hardware en el kernel, y kernel.dll es la implementación de la capa OAL independiente del hardware en el kernel. Lo mismo se puede ver en el archivo de configuración binaria de integración final, el archivo ce.bib.
; @CESYSGEN IF CE_MODULES_NK
nk.exe E:\WINCE600\OSDesigns\xsbase270\xsbase270\RelDir\XSBase270_ARMV4I_Release\oal.exe NK SHZ
kitl .dll E:\WINCE600\OSDesigns\xsbase270\xsbase270\RelDir\XSBase270_ARMV4I_Release\kitl.dll NK SHZ
kernel.dll E:\WINCE600\OSDesigns\xsbase270\xsbase270\RelDir\XSBase270_ARMV4I_Release \kern. dll NK SHZ
; @CESYSGEN ENDIF
La biblioteca dinámica kern.dll se utilizará en todo Windows CE 6.0, por lo que sólo podrá encontrarla en el archivo compilado Makefile del sistema operativo. proceso de compilación.
A continuación se muestra parte de $(_PUBLICROOT)\common\CESYSGEN\makefile:
nk::$(NK_COMPONENTS) $(NK_REPLACE_COMPONENTS)
@copy $(SG_INPUT_LIB)\ oemstub.pdb $(SG_OUTPUT_OAKLIB)
@copy $(SG_INPUT_LIB)\oemstub.lib $(SG_OUTPUT_OAKLIB)
establecer TARGETTYPE=DYNLINK
establecer TARGETNAME=kern
establecer RELEASETYPE=OAK
setDLLENTRY=NKStartup
establecer DEFFILE=NO_DEF_FILE
establecer TARGETLIBS=
establecer SOURCELIBS=NKLIBS $(SG_INPUT_LIB)\nkmain.lib $(SG_INPUT_LIB)\fulllibc.lib
$(MAKECMD) /NOLOGO NOLIBC=1 kern.dll
Desde el código anterior, puede Se descubrió que la biblioteca dinámica kern.dll original fue compilada a partir de oemstub.lib y relacionada con nkmain.lib.
Después de aclarar la relación entre los archivos anteriores, puede ser más fácil analizar el proceso de inicio de Windows CE 6.0.
Después de aclarar la relación entre los archivos anteriores, puede analizar el proceso de inicio de Windows CE 6.0 basado en cualquier microprocesador ARM y analizar el desarrollo ARM PXA270 basado en Shenzhen Yidao Electronic Technology Co., Ltd. Proceso de inicio del sistema operativo Windows CE 6.0 de la plataforma.
1. Función de inicio:
Como se puede ver en el documento de ayuda de Windows CE 6.0, el inicio de WinCE 6.0 solo está relacionado con oaal.exe y kernel.dll As. para kitl.dll, solo se usa al compilar el sistema operativo en un sistema operativo con funcionalidad KITL. Al analizar el proceso de inicio de Windows CE 6.0, encontramos la ubicación del código fuente donde se compilan oal.exe y kernel.dll.
oal.exe completa la inicialización del hardware a través de la función de inicio. El código Startup.s y el código de inicio del cargador de arranque de la plataforma de hardware *** cooperan con él. La función PreInit completa principalmente el cambio del modo de trabajo del procesador ARM al modo de administrador, apaga la MMU al mismo tiempo y detecta el motivo. inicio del sistemaSi es un inicio en caliente, es decir, cuando la llamada a la función llega a un inicio en caliente, es decir, el programa Bootloader se inició antes de la llamada a la función y se completó la inicialización básica del hardware, saltará directamente a. la función OALStartUp; de lo contrario, el enmascaramiento de interrupciones de hardware, la memoria, la frecuencia del reloj del sistema y el proceso de inicialización de hardware básico, como la administración de energía.
(Consulte el análisis de código para el proceso específico)
$(_PLATFORMROOT)\xsbase270\src\common\Startup\Startup.s
LEAF_ENTRY StartUp
bl PreInit
tst r10, # RCSR_HARD_RESET
beq OALStartUp
tst r10, #RCSR_GPIO_RESET
bne Continuar_StartUp
bl xlli_mem_init ;Inicializar controlador de memoria
ldr r0, =xlli_PMRCREGS_PHYSICAL_BASE;
ldr r0, [r0, #xlli_PSPR_offset];
mov r1, r10; /p >
bl ;
ldr r0, [r0, #xlli_PSPR _offset];
mov r1, r10
b XllpPmGoToContextRestoration
p>
Failed_Sleep_Resume
ldr r1, =xlli_RCSR_SMR
bic r10, r10, r1
Continuar_Inicio
bl xlli_intr_init; Inicializar el controlador de interrupciones
bl EnableClks; habilitar los relojes del kernel (requerido para la memoria/temporizador del sistema operativo/reloj FFART)
bl OALXScaleSetFrequencies
bl xlli_mem_Topt;
bl xlli_mem_restart; Restablece la memoria al modo de trabajo
bl xlli_ost_init; Inicializa el temporizador del sistema operativo
bl xlli_pwrmgr_init; bl xlli_IMpwr_init; Inicializar la memoria interna
b
ENTRY_END
2. Función OALStartUp:
Una vez completada la inicialización del hardware del sistema, el Se llama a la función OALStartUp La función OALStartUp Principalmente completa el paso de la tabla OEMAddressTable al kernel y luego llama a la función KernelStart para saltar a la función principal de la tabla OEMAddressTable del kernel. tamaño de la memoria y la dirección física de la tabla de mapeo.
◆Las direcciones de memoria virtual estática se definen dentro del rango de la memoria almacenada en el buffer;
◆El kernel puede crear direcciones de memoria sin buffer que apunten a la misma dirección física;
◆Las mismas direcciones físicas tienen direcciones de memoria virtual con buffer y direcciones de memoria virtual sin buffer;
◆OEMADdressTable se puede utilizar para crear direcciones virtuales con buffer o sin buffer para la misma dirección física;
◆OEMADdressTable debe comenzar con Terminar con 0;
◆ Para las CPU de tipo MIPS y SHx, la asignación de direcciones físicas a direcciones virtuales la realiza la CPU, por lo que no es necesario crear una OEMAddressTable
$(_PLATFORMROOT)\xsbase270\src\ Inc\ Oemaddrtab_cfg.
$(_PLATFORMROOT)\xsbase270\src\oal\OalLib\Startup.s
3. La función principal de la función KernelStart es:
◆ Completar la asignación entre la dirección física a la dirección virtual y la dirección virtual a la dirección física en la tabla OEMAddressTable
◆ Borrar la memoria; Tabla de páginas y espacio de almacenamiento del área de parámetros del kernel (RAM o DRAM). )
◆ Lea el número de ID de la CPU. El kernel necesita decidir el procesamiento MMU de ARM en función de este ID, porque el procesamiento MMU de los procesadores ARM anteriores a ARMV6 y ARMV6 es diferente;
◆ Configuración Y active MMU y Caché, porque MMU y Caché están desactivados en la función de inicio;
◆ Configure el puntero SP del modo de trabajo del procesador ARM. El procesador ARM**** utiliza siete modos de funcionamiento diferentes (USUARIO, FIQ, IRQ, Supervisor, Abortar, Indefinido y Sistema). Excepto el modo de usuario (USUARIO) y el modo de sistema (Sistema), los otros cinco modos de funcionamiento tienen los suyos propios. Registro de puntero SP (configuración del procesador ARM
y activa MMU y caché, porque la función de inicio desactivará MMU y caché. Además de USUARIO y SISTEMA, los otros cinco modos de funcionamiento tienen punteros SP específicos registro (el procesador ARM se llama registro oculto);
◆Lea la estructura KDataStruct requerida para el inicio del kernel;
◆Llame a la función ARMInit para reubicar el parámetro del kernel de Windows CE pTOC e inicializar la variable global OEMInitGlobals;
◆Utilice las instrucciones mov pc y r12 para saltar al siguiente parámetro del kernel de Windows CE pTOC. Utilice las instrucciones mov pc y r12 para saltar a la posición de entrada de kernel.dll, que. es la función NKStartup
$(_PRIVATEROOT)WINCEOS\COREOS\NKL\DR\ARM\armstart.s
4. >Antes de ARInit, el sistema aún no puede usar variables globales porque las variables globales del sistema todavía están en el área ROM. Para el sistema operativo, después de esto, se inicializa la estructura KDataStruct requerida para el inicio del kernel, donde OEMInitGlobals intercambia punteros globales entre oal.exe y. kernel.dll.
Los punteros globales entre exe y kernel.dll se intercambian y luego la función ARMInit regresa a la ubicación de entrada de kernel.dll. La función ARMInit devuelve el punto de entrada de kernel.dll. Al final de la función KernelStart, use las instrucciones mov pc y r12 para saltar al punto de entrada de kernel.dll, que es la función NKStartup.
$(_PRIVATEROOT)WINCEOS\COREOS\NKL\DR\ARM\arminit.c
5. Función NKStartup:
Después de completar la inicialización del hardware plataforma, el inicio de oaal.exe básicamente se completa y el inicio restante lo implementa la capa OAL relacionada con el kernel y es independiente del kernel. Las funciones principales de kernel.dll:
◆ Extraer las variables globales requeridas para el inicio del kernel de los parámetros de estructura KDataStruct * pKData e inicializar las variables globales del kernel al mismo tiempo;
◆ Encuentre la estructura OEMGLOBAL única de Windows CE 6.0. La estructura OEMGLOBAL es la dirección de la función de inicialización OEMInitGlobals. Esta estructura construye un puente de comunicación entre el kernel y la capa OAL. La estructura OEMGLOBAL define las funciones requeridas por la capa OAL. Estas funciones se inicializan en el archivo oemglobal.c y se compilan en las bibliotecas OEMMain.lib y OEMMain_StaticKITL.lib. Si OAL está vinculado a estas dos bibliotecas, debe usar la función. implementación;
◆ Configure el mapeo de direcciones de memoria virtual física y sin búfer, vectores de interrupción ARM y pilas requeridas por el modo kernel llamando a ARMSetup.
◆ Inicialice el puerto serie de depuración llamando a la función OEMInitDebugSerial
◆ Inicialice la plataforma llamando a OEMInit
Tenga en cuenta que la función NKStartup llama a OEMInitDebugSerial y; OEMInit funciona de la misma manera. Windows CE 6.0 y versiones anteriores son idénticas. Esto se debe a que antes de Windows CE 6.0, dado que el kernel, OAL y KITL se compilaban en un archivo ejecutable, solo necesitaba declararlos con la palabra clave extern para acceder a las variables compartidas entre ellos, mientras que en Windows CE 6.0, desde el kernel, OAL y KITL se compilan en un archivo ejecutable; se puede acceder a las variables compartidas entre ellos simplemente declarándolas con la palabra clave extern. Sin embargo, en Windows CE 6.0, dado que el kernel, OAL y KITL se compilan en diferentes archivos ejecutables, no se puede lograr el acceso mutuo entre variables usando la palabra clave extern, es decir, el kernel no puede acceder a OAL usando el método externo DWORD varX. La variable de capa varX, por supuesto, la implementación de la capa OAL no puede acceder a las variables del kernel de la misma manera. Windows CE 6.0 define dos estructuras, OEMGLOBAL y GLOBAL, para permitir el acceso del kernel y OAL a la información ***.
Cuando se inicia el kernel de Windows CE 6.0, el sistema operativo encontrará la ubicación de entrada de OAL y luego llamará a la función de entrada para intercambiar punteros con el bloque global, de modo que el kernel pueda usar la información en la capa OAL De manera similar, la capa OAL también puede acceder a funciones exportadas por el kernel.
Por lo tanto, las dos llamadas a funciones anteriores en realidad se implementan a través de la estructura OEMGLOBAL.
La ubicación de llamada real es OEMInitDebugSerial y OEMInit en $(_PRIVATEROOT)\winceos\coreos \nk\oemstub\oemstub.c. Estas dos funciones acceden a OEMInitDebugSerial y OEMInit en la capa OAL a través del puntero de estructura OEMGLOBAL.
Primero, eche un vistazo a la situación básica del kernel descrita en Compilación de WinCE 6.0 en WinCE 5.0, que es kern.exe. Es relativamente fácil encontrar la ubicación del código fuente de oal.exe porque oal.exe es el archivo de implementación de la capa OAL del código de inicio dependiente del hardware. Una vez compilado, simplemente se puede encontrar en el directorio OAL del BSP. En cuanto a kernel.dll, es básicamente imposible encontrar el archivo compilado de kernel.dll en la estructura del directorio BSP, por lo que debemos comenzar desde otros aspectos.
Llame a la función KernelFindMemory() para dividir el área de RAM. En el sistema operativo Windows CE, el espacio RAM se divide principalmente en memoria de almacenamiento y memoria de programa. La memoria de almacenamiento se usa principalmente para almacenar espacio de archivos, incluidos los archivos del kernel y todos los archivos de destino copiados al sistema, mientras que la memoria de programa se usa para ejecutar programas. de espacio de almacenamiento.
◆KernelStart() inicia el kernel.
$(_PRIVATEROOT)/WINCEOS\COREOS\NK\KERNEL\ARM\mdarm.c
void NKStartup (struct KDataStruct * pKData)
{ p>
. . . .
}
6. Función KernelSstart:
La función KernelStart aquí y la función KernelStart anterior pertenecen a dos funciones completamente diferentes. La función KernelStart llamada por NKStartup. función Es la función KernelStart en el archivo $(_PRIVATEROOT)\WINCEOS\COREOS\NK\KERNEL\ARM\armtrap.s, que principalmente completa la llamada de la función de inicialización del kernel KernelInit y salta a la primera tarea de inicio del sistema operativo. .
LEAF_ENTRY KernelStart
ldr r4, =KData (r4) = ptr a KDataStruct
ldr r0, =APIRet
str r0 , [r4, #pAPIReturn] ; Establecer dirección de retorno de API
mov r1, #SVC_MODE
msr cpsr_c, r1 ; Cambiar al modo de supervisión habilitado para IRQ
LLAMAR a KernelInit; inicializar el programador, etc.
mov r0, #0; No hay hilo actual
mov r1, #ID_RESCHEDULE
b FirstSchedule
ENTRY_END
7, función KernelInit
La función de inicialización del kernel de Windows CE 6.0 es básicamente similar a la función de inicialización del kernel de otras versiones. Principalmente completa la inicialización del kernel antes de que comience el primer subproceso, incluida la inicialización del conjunto de funciones API. inicialización del montón, Operaciones como inicialización del grupo de memoria, inicialización de procesos, inicialización de subprocesos e inicialización de mapeo de archivos.
void KernelInit (void)
.{
.}
8, FirstSchedule:
Función FirstSchedule Es una función que es el último salto incondicional durante el proceso de inicio del sistema operativo Windows CE. Windows CE es la primera programación y en realidad es un hilo inactivo, porque el sistema Windows CE aún no se ha iniciado por completo. se inicia y entra en un estado estable. Solo entonces se iniciarán el sistema de archivos filesys.dll, el dispositivo de administración de dispositivos.dll, el subsistema de imágenes de Windows gews.dll y el programa shell explore.exe.