Cómo iniciar el sistema WINCE y ejecutar su propio programa directamente
Análisis del proceso de inicio de Windows CE6.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, entre las que se encuentra el proceso de inicio. código (inicio) La parte de implementación de la capa OAL ya no está vinculada con el kernel para generar NK.exe. En cambio, el código de inicio (inicio) y la parte de implementación de la capa OAL están relacionados con el hardware y son independientes del kernel. se compilan en oal.exe, que está relacionado con el kernel y es independiente del kernel. El código de la capa OAL del hardware se incluye en kernel.dll y el código de soporte para la capa de transporte independiente del kernel (KITL) está separado del. Capa OAL y compilada en kitl.dll. En la superficie, parece que es solo una reorganización del código. Desde el proceso de trasplante de BSP en el documento de ayuda, parece que lo mismo es cierto, de hecho, todo el diseño del kernel de Windows CE 6.0 ha sufrido grandes cambios. Lo mismo ocurre con el proceso de inicio de Windows CE 6.0. Si desea analizar la secuencia de inicio de Windows CE 6.0 de acuerdo con la secuencia de inicio de Windows CE 5.0, puede llegar a un callejón sin salida. Principalmente porque Windows CE 6.0 llama a las dos bibliotecas de vínculos dinámicos kernel.dll y kitl.dll durante el proceso de inicio, y Windows CE6.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 WinCE6.0 solo está relacionado con oal.exe y kernel.dll. En cuanto a kitl.dll, solo se usa cuando el sistema operativo está compilado para tener el. Función KITL. Al analizar el proceso de inicio de Windows CE 6.0, se encuentra la ubicación del código fuente donde se compilan oal.exe y kernel.dll. Primero, echemos un vistazo a la situación de compilar WinCE6.0 en un kernel básico como WinCE5.0, es decir, kern.exe. Es relativamente fácil encontrar la ubicación del código fuente de oal.exe, porque oal.exe se compila a partir del código de inicio y los archivos de implementación de la capa OAL relacionados con el hardware, por lo que solo 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.
El siguiente es el archivo de salida del registro de compilación de WinCE 6.0: makeimg.out como parte del proceso de copia del archivo: Copiar E:\WINCE600\OSDesigns\xsbase270\xsbase270\RelDir\XSBase270_ARMV4I_Release\oal.exe a E:\WINCE600\OSDesigns\xsbase270 \xsbase270 \ RelDir\ XSBase270_ARMV4I_Release\kernel.dll para el depurador Se puede ver en el archivo de salida del registro que durante el proceso de copia del archivo, el compilador WinCE6.0 cambió el nombre de oal.exe a nk.exe y el nombre del archivo kern.dll a kernel.dll En otras palabras, el archivo kern.dll La parte de implementación es el cuerpo de implementación de kernel.dll. Según el análisis anterior, oal.exe es la parte de implementación de la capa OAL que es independiente del kernel y está relacionada con el hardware, mientras que kernel.dll es la parte de implementación de la capa OAL que es independiente del hardware y está relacionado con el núcleo. La pista también se puede ver en el archivo ce.bib del archivo de configuración binaria integrado final. ; @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\XSBase27 0_A RMV4I_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 no tiene un proceso de compilación explícito en todo Windows CE6.0, es decir, no hay nadie El archivo fuente tiene el proceso de compilación de kern.dll, por lo que solo puede encontrar el proceso de compilación en el archivo de compilación Makefile del sistema operativo.
Echemos un vistazo a algunos de los contenidos en $(_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 establecer DLLENTRY=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 Del código anterior, podemos encontrar que la biblioteca dinámica kern.dll está compilada desde oemstub.lib y está relacionada con nkmain.lib. Después de aclarar la relación entre los archivos anteriores, puede resultar 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 cualquier Windows CE 6.0 basado en un microprocesador ARM. Ahora tome la plataforma de desarrollo ARM PXA270 desarrollada por Shenzhen Yidao Electronic Technology Co., Ltd. como ejemplo para analizar Windows CE. Proceso de inicio del sistema operativo 6.0. 1. Función de inicio: se puede ver en el documento de ayuda de Windows CE 6.0 que el inicio de WinCE6.0 solo está relacionado con oal.exe y kernel.dll. En cuanto a kitl.dll, solo se usa cuando el sistema operativo. Se compila con la función KITL. Al analizar el proceso de inicio de Windows CE 6.0, se encuentra 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 se utiliza con el código de inicio del cargador de arranque de la plataforma de hardware. La función PreInit cambia principalmente el modo de trabajo del procesador ARM al modo de administrador, cierra la MMU al mismo tiempo y detecta la causa del inicio del sistema. es un inicio en caliente, es decir, el programa Bootloader se inició antes de llamar a esta función y se completó la inicialización básica del hardware, por lo que salta directamente a la función OALStartUp; de lo contrario, el proceso de inicialización básico del enmascaramiento de interrupciones del hardware, la memoria, Se requiere frecuencia de reloj del sistema, administración de energía y otro hardware.
(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 Continue_StartUp bl xlli_mem_init; controlador ldr r0, =xlli_PMRCREGS_PHYSICAL_BASE; ldr r0, [r0, #xlli_PSPR_offset]; mov r1, r10; bl XllpPmValidateFromSleep; cmp r0, #0; licenciado en derecho xlli_mem_Topt bl xlli_mem_restart; Restablece la memoria para ponerla en el modo de trabajo bl xlli_ost_init; Inicializa el temporizador del sistema operativo bl xlli_pwrmgr_init; Inicializa la administración de energía bl xlli_IMpwr_init; El inicio llama a la función OALStartUp, que principalmente completa la transferencia de la tabla OEMAddressTable al kernel; luego llama a la función KernelStart para saltar a la función principal de la tabla OEMAddressTable del kernel. Cada entrada en la tabla define una ubicación física en la memoria. tamaño de la memoria y el mapeo La dirección virtual estática de esta dirección física ◆ La dirección de la memoria virtual estática se define dentro del rango de la memoria intermedia ◆ El núcleo puede crear una dirección de memoria sin búfer que apunte a la misma dirección física; ◆ Para la misma dirección física, hay una dirección de memoria virtual almacenada en el búfer, también hay una dirección de memoria virtual sin búfer; ◆OEMAddressTable debe terminar en 0 ◆Para CPU de tipo MIPS y SHx, la asignación de la dirección física y la dirección virtual es; completado por la CPU, no es necesario crear OEMAddressTable $(_PLATFORMROOT)\xsbase270 \src\Inc\ Oemaddrtab_cfg.inc): $(_PLATFORMROOT)\xsbase270\src\oal\OalLib\Startup.s 3. La función principal de la función KernelStart : ◆Complete 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 Mapeo entre la tabla de páginas de memoria y el espacio de almacenamiento del área de parámetros del kernel (RAM o DRAM);
Realizar procesamiento de compensación. ◆Leer el número de ID de la CPU. El núcleo necesita decidir el procesamiento de MMU de ARM en función de este ID, porque el proceso de procesamiento de MMU de los procesadores ARMV6 y ARM anteriores a ARMV6 es diferente. ◆Configurar y habilitar MMU y caché, porque la MMU. está desactivado en la función Inicio y Caché ◆ Configure el puntero SP del modo de trabajo del procesador ARM. El procesador ARM utiliza 7 modos de trabajo diferentes (USUARIO, FIQ, IRQ, Supervisor, Abortar, Indefinido, Sistema), excepto el modo de usuario. (USUARIO) y Además del modo de sistema (Sistema), los otros cinco modos de trabajo tienen registros de puntero SP específicos (los procesadores ARM los llaman registros ocultos); ◆ Lea la estructura KDataStruct requerida para el inicio del kernel; ◆ Llame a la función ARMInit para reposicionar Windows; Parámetro del kernel CE pTOC e inicialización de la variable global OEMInitGlobals ◆ Utilice mov pc, la instrucción r12 salta a la posición de entrada de kernel.dll, es decir, la función NKStartup. $(_PRIVATEROOT)WINCEOS\COREOS\NK\LDR\ARM\armstart.s 4. Función ARMInit: antes de ARMInit, el sistema aún no puede usar variables globales, porque las globales del sistema todavía están en el área ROM Para el sistema operativo, debido. Por razones de seguridad, sólo los programas XIP tienen derecho a leer los datos del área ROM. Para la mayoría de los sistemas operativos Windows CE, los datos sólo se pueden leer y escribir después de copiarlos en el área RAM. En la función ARMInit, la variable global pTOC se reubica. llamando a la función KernelRelocate, después del posicionamiento, inicialice la estructura KDataStruct requerida para el inicio del kernel, en la que OEMInitGlobals debe intercambiar el puntero global entre oal.exe y kernel.dll, y la función ARMInit devuelve la posición de entrada de kernel.dll. Y al final de la función KernelStart, se usa mov pc y la instrucción r12 salta a la posición de entrada de kernel.dll, que es la función NKStartup. $(_PRIVATEROOT)WINCEOS\COREOS\NK\LDR\ARM\arminit.c 5. Función NKStartup: una vez completada la inicialización de la plataforma de hardware, la tarea de inicio de oal.exe básicamente se completa y el trabajo de inicio restante lo realiza el OAL relacionado e independiente del kernel. El cuerpo de implementación de la capa kernel.dll se hace cargo. Las funciones principales de kernel.dll: ◆ Extraer las variables globales necesarias para el inicio del kernel de los parámetros de estructura KDataStruct * pKData e inicializar las variables globales del kernel al mismo tiempo. ◆ Localizar la dirección de la función de inicialización OEMInitGlobals de la estructura OEMGLOBAL exclusiva de Windows; CE 6.0 Esta estructura Se construye un puente para la comunicación entre el kernel y la capa OAL. Las funciones necesarias para la capa OAL se definen en la estructura OEMGLOBAL. La estructura se inicializa en el archivo oemglobal.c y se compila en dos bibliotecas: OEMMain.lib y OEMMain_StaticKITL.lib. Si OAL vincula estas dos bibliotecas, entonces debe haber una. cuerpo de implementación de la función en esta estructura; ◆ Establecer el mapeo de la dirección física y la dirección de memoria virtual sin búfer, el vector de interrupción ARM y la pila requerida por el modo kernel llamando a ARMSetup.
◆Llame a la función OEMInitDebugSerial para inicializar el puerto serie de depuración; ◆Llame a OEMInit para inicializar la plataforma. Cabe señalar que el proceso de llamada a las funciones OEMInitDebugSerial y OEMInit mediante la función NKStartup es completamente diferente de la versión anterior a Windows CE 6.0. Esto se debe a que en la versión anterior a Windows CE 6.0, dado que el kernel, OAL y KITL están compilados en un archivo ejecutable, se puede acceder a las variables compartidas entre ellos simplemente usando la declaración de palabra clave extern, y en Windows CE 6.0 desde el kernel, OAL y KITL se compilan en diferentes archivos ejecutables, el acceso mutuo entre variables no se puede lograr usando la palabra clave externa, es decir, el kernel no puede usar el método externo DWORD varX para acceder a la variable varX de la capa OAL, por supuesto, el cuerpo de implementación. de la capa OAL no pueden acceder a las variables del kernel de la misma manera. Para permitir que el kernel y OAL accedan a información compartida, Windows CE 6.0 define dos estructuras, OEMGLOBAL y GLOBAL. Cuando se inicia el kernel de Windows CE 6.0, el sistema operativo encuentra la ubicación de entrada de OAL y luego llama 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 y la capa OAL pueda También accede a funciones exportadas por el kernel. Entonces, las llamadas a las dos 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, echemos un vistazo a la situación de compilar WinCE6.0 en el kernel básico como WinCE5.0, es decir, kern.exe. Es relativamente fácil encontrar la ubicación del código fuente de oal.exe, porque oal.exe se compila a partir del código de inicio y los archivos de implementación de la capa OAL relacionados con el hardware, por lo que solo 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 de RAM se divide principalmente en memoria de almacenamiento y memoria de programa. La memoria de almacenamiento es principalmente el espacio de almacenamiento para archivos, incluidos los archivos del kernel y todos los archivos de destino copiados. al sistema y la memoria del programa. El espacio de almacenamiento necesario para ejecutar el programa. ◆KernelStart () inicia el kernel. $(_PRIVATEROOT)\WINCEOS\COREOS\NK\KERNEL\ARM\mdarm.c void NKStartup (struct KDataStruct * pKData) { . . . . } 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 en la función NKStartup es $(_PRIVATEROOT)\WINCEOS\COREOS\NK \KERNEL\ARM\armtrap.s. La función KernelStart en el archivo completa principalmente la tarea de llamar a la función de inicialización del kernel KernelInit y saltar al primer inicio del sistema operativo.
LEAF_ENTRY KernelStart ldr r4, =KData; (r4) = ptr a KDataStruct ldr r0, =APIRet str r0, [r4, #pAPIReturn]; establecer la dirección de retorno de API mov r1, #SVC_MODE msr cpsr_c, r1; IRQ habilitadas CALL KernelInit; inicializa 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 otros versiones, principalmente Complete la inicialización del kernel antes de iniciar el primer subproceso, que incluye principalmente operaciones como la inicialización del conjunto de funciones API, la inicialización del montón, la inicialización del grupo de memoria, la inicialización del proceso, la inicialización del subproceso y la inicialización del mapeo de archivos. void KernelInit (nulo). . . { } 8. FirstSchedule: la función FirstSchedule es la última función de salto incondicional durante el proceso de inicio del sistema operativo Windows CE. Windows CE realiza la primera programación, que en realidad es un subproceso inactivo, porque el sistema Windows CE aún no ha completado el inicio. CE se inicia por completo y entra en un estado estable, y luego inicia el sistema de archivos filesys.dll, el dispositivo de administración de dispositivos.dll, el subsistema de imágenes gews.dll y el programa shell explore.exe.