
Los que siguen nuestro proyecto pueden haber notado que una carpeta e2k ha aparecido en el directorio de arquitecturas, que contiene soporte para procesadores domésticos con
arquitectura Elbrus .
Una serie de artículos sobre portar
Embox a plataformas domésticas no estaría completa sin una historia sobre esta arquitectura.
Haré un par de comentarios sobre el contenido del artículo. En primer lugar, el proceso de dominar esta arquitectura por nosotros está en la etapa inicial, logramos lanzar Embox en esta plataforma, pero aún no hemos implementado muchas de las partes necesarias, que se discutirán en futuras publicaciones. En segundo lugar, esta arquitectura es compleja y
Una descripción detallada requiere mucho más texto del que permite el formato
un articulo Por lo tanto, sugerimos tomar este artículo como introducción,
que contiene un mínimo de información técnica sobre la arquitectura en sí.
Empecemos
Objeto de investigación: diseño del sistema integrado en Elbrus
Dado que estamos involucrados en Embox (y si alguien no lo sabe, se centra en los sistemas integrados), nos interesó principalmente la opción de posicionar el MTsST en sí, incluso para los sistemas integrados. En cuanto al MCST, descubrimos que la compañía está interesada en usar sus procesadores para sistemas integrados. Una de las últimas soluciones para este segmento es
la placa E4C-COM . En el proceso de comunicación con el MCST, quedó claro que para portar y dominar la arquitectura, puede usar cualquiera de las máquinas disponibles, y nos dieron una computadora llamada
Temperamento para uso temporal. En general, un monocubo no es exactamente lo que estamos acostumbrados en los sistemas integrados. Por lo general, los sistemas integrados utilizan computadoras de una sola placa, un chip, un sistema en un chip o incluso un microcontrolador, pero el monocubo es una computadora completa, pero dado que ha sido probado en "clima y mecánica", todavía puede considerarse un sistema integrado.
Compilador, compilar, llenar imagen
Después de recibir la unidad del sistema, naturalmente surgió la pregunta: cómo completar la imagen. El MCST utiliza su propio BIOS (cargador de arranque del sistema de primer nivel). Por defecto, el sistema operativo Elbrus está instalado (es decir, Debian con modificaciones). Estamos interesados en lanzar nuestra propia imagen. Afortunadamente, el cargador MTST puede ejecutar imágenes a través de la red. Para hacer esto, use el
protocolo ATA sobre Ethernet .
Después de que nos ayudaron a configurar un stand y lanzar una imagen externa a través de la red, comenzamos a desarrollar nuestra propia imagen. Para hacer esto, necesitábamos un compilador. No encontramos el compilador en el dominio público, pero desde que firmamos el NDA, nos dieron binarios para Linux. El compilador resultó ser bastante compatible con gcc, y no tuvimos que cambiar nada, por supuesto, con la excepción de los indicadores de compilación, que pusimos en un archivo de configuración separado. Lo cual es muy predecible, porque Linux, aunque con modificaciones, es ensamblado por este compilador.
Un par de preguntas técnicas.
Aquellos que se dedican a actividades tan específicas como portar el sistema operativo a una plataforma saben que lo primero que debe hacer es colocar correctamente el código del programa en la memoria. Es decir, escriba un script vinculador (lds) e implemente el código de inicio. Rápidamente descubrimos el script del enlazador, pero al implementar el código de inicio, nos encontramos con la primera magia, que no entendimos completamente. El hecho es que Elbrus tiene un modo de compatibilidad x86 y en 0x00FF0000 hay un código al que simplemente le daré un
enlace , ya que lo tomamos prestado del ejemplo MCST. El script de enlazador contiene
.bootinfo : { _bootinfo_start = .; *(.x86_boot) . = _bootinfo_start + 0x10000; _bootinfo_end = .; } SECTION_REGION(bootinfo) .text : { _start = .; *(.e2k_entry);
El código de inicio en sí mismo ni siquiera está escrito en ensamblador, sino simplemente en
C. Se coloca en la sección ubicada en 0x01000000, que, por cierto, corresponde a la dirección de inicio de las máquinas x86 normales: allí el encabezado de
arranque múltiple u otro encabezado se encuentra en esa dirección.
Para asegurarse de que el código de inicio y las direcciones sean correctos, necesita obtener algún resultado. Si puede imprimir cualquier carácter, lo más probable es que no haya problemas con la salida de las cadenas. Usando esta salida, ya será posible usar printf () para la depuración. Además, la mayoría de las plataformas proporcionan la capacidad de generar caracteres al hacer una entrada simple en un registro específico (ya que el gestor de arranque probablemente ha configurado UART según sea necesario).
Nuestra computadora usa el controlador de puerto serie am85c30 (también
conocido como
z85c30 , lo suficientemente rápido como encontramos la impresión de un carácter, y esto es suficiente para que nuestro printf funcione. Inmediatamente enfrentamos un problema extraño: algunos de los caracteres impresos por printf parecían duplicados, pero a veces confundido. Por ejemplo, cuando traté de generar Hello, world! Resultó algo así como Hhelellloo ,, woworrlldd. Ahora parece obvio que el asunto es multinúcleo, pero al principio hurgamos en el controlador. En nuestro monocub hay un Elbrus-2C de doble núcleo. + (1891VM7YA) ( cuatro núcleos DSP no cuentan) y el gestor de arranque activa todos los núcleos del procesador. Como resultado, para no meterse con multinúcleo (SMP), todos los núcleos, excepto el primero, se envían a un bucle infinito. Para hacer esto, introdujimos una variable para el número de procesador y la incrementamos usando la suma atómica Zero core continúa funcionando, mientras que otros núcleos se repiten.
cpuid = __e2k_atomic32_add(1, &last_cpuid); if (cpuid > 1) { while(1); } memcpy((void*)0, &_t_entry, 0x1800); kernel_start();
La llamada kernel_start () ya es una transferencia de control a nuestro código.
También tomamos prestada una suma atómica, para nosotros parece mágica. Pero, como sabes, funciona, ¡no lo toques!
#define WMB_AFTER_ATOMIC ".word 0x00008001\n" \ ".word 0x30000084\n" #define __e2k_atomic32_add(__val, __addr) \ ({ \ int __rval; \ asm volatile ("\n1:" \ "\n\tldw,0 %[addr], %[rval], mas=0x7" \ "\n\tadds %[rval], %[val], %[rval]" \ "\n\t{"\ "\n\tstw,2 %[addr], %[rval], mas=0x2" \ "\n\tibranch 1b ? %%MLOCK" \ "\n\t}" \ WMB_AFTER_ATOMIC \ : [rval] "=&r" (__rval), [addr] "+m" (*(__addr)) \ : [val] "ir" (__val) \ : "memory"); \ __rval; \ })
Otra magia que tuve que pedir prestado es un código, que se requiere para todos los núcleos. A saber
static inline void e2k_wait_all(void) { _Pragma ("no_asm_inline") asm volatile ("wait \ttrap = %0, ma_c = %1, fl_c = %2, ld_c = %3, " "st_c = %4, all_e = %5, all_c = %6" : : "i" (0), "i" (1), "i" (1), "i" (0), "i" (0), "i" (1), "i" (1) : "memory"); }
Como resultado, después de escribir el código de inicio, no solo mostramos los mensajes usando printk, sino que también comenzamos a cargar módulos, lo que generalmente no es muy trivial para compiladores no bastante estándar. Así que una vez más noto que esta vez la compatibilidad con gcc fue muy satisfactoria.
El siguiente paso generalmente es iniciar el controlador de interrupción y el temporizador, pero pensando que tendremos que implementar no solo soporte para estos dispositivos, sino también el código arquitectónico para los manejadores de interrupciones, decidimos que podemos comenzar desde la periferia. El monocub tiene un bus PCIe, para los programadores parece un PCI normal. Estábamos principalmente interesados en dos dispositivos: un controlador de pantalla y un controlador de red.
El monocubo utiliza un controlador gráfico de la serie
sm750 . Este es un controlador de gráficos para aplicaciones integradas, tiene soporte integrado para gráficos 2D. El chip se suelda directamente a la placa base, según tengo entendido. Las fuentes para el controlador para Linux se pueden encontrar
aquí .
Después de encontrar el controlador, parecía que nuestros problemas habían terminado, solo quedaba implementar el controlador para PCI. más precisamente, operaciones de lectura / escritura del espacio de configuración PCI para conocer los parámetros. La implementación de estas funciones tuvo que ser prestada nuevamente. Como resultado, la lectura de registros se redujo a macros como
#define _E2K_READ_MAS(addr, mas, type, size_letter, chan_letter) \ ({ \ register type res; \ asm volatile ("ld" #size_letter "," #chan_letter " \t0x0, [%1] %2, %0" \ : "=r" (res) \ : "r" ((__e2k_ptr_t) (addr)), \ "i" (mas)); \ res; \ }) #define _E2K_WRITE_MAS(addr, val, mas, type, size_letter, chan_letter) \ ({ \ asm volatile ("st" #size_letter "," #chan_letter " \t0x0, [%0] %2, %1" \ : \ : "r" ((__e2k_ptr_t) (addr)), \ "r" ((type) (val)), \ "i" (mas) \ : "memory"); \ })
Hay cierta comprensión de lo que está sucediendo. Elbrus tiene varios espacios de direcciones alternativos, como, por ejemplo, en la
arquitectura SPARC . La identificación se realiza utilizando el identificador de espacio de direcciones. Es decir, el mismo comando ld llega a diferentes direcciones internas, también genera operaciones de lectura de diferentes longitudes (8, 16, 32, 64 bits). Si en SPARC este es un comando lda / sta separado, entonces en Elbrus debido a los parámetros, este es el comando ld. Las
ventanas de registro se tomaron prestadas de la arquitectura SPARC. Pospondré una historia más detallada para artículos posteriores.
Como resultado, todo resultó con PCI. Pudimos obtener todos los datos necesarios, transferimos el controlador de gráficos a nosotros mismos, pero luego nos encontramos con el siguiente problema. Para dibujar una imagen en la memoria de video, tenía que escribir dos veces. Todo apuntaba al caché. Para resolver este problema, fue necesario lidiar con MMU, y esto, como dicen, no se puede resolver con el condachka, ya que, en principio, hay muchos otros problemas que encontramos y que encontraremos más de una vez durante el desarrollo de esta arquitectura.
Hemos progresado en otras direcciones: interrupciones y llamadas al sistema, pero también hablaremos de esto en los próximos artículos de esta subserie. Al final de este artículo, simplemente llevaré la salida a la consola (a través del puerto serie).

Conclusiones
Como dije en la introducción, quiero centrarme principalmente no en detalles técnicos, sino en sentimientos generales. Entonces, los sentimientos son contradictorios, aunque ciertamente más positivos. Por un lado, el procesador existe y es muy interesante en términos de características arquitectónicas. Basado en este procesador, se producen sistemas informáticos, hay un software de bastante alta calidad. Como dije, no hubo quejas sobre el compilador (hasta cierto punto, que describiré un poco más adelante), hay un Linux completo (SO "Elbrus"). Personalmente, vi cómo en el propio ICST, el desarrollador creó directamente en el escritorio con la arquitectura Elbrus.
Pero, por otro lado, no entiendo por qué con tanta persistencia están tratando de hacer un reemplazo banal de Intel x86 de este procesador. De hecho, en ninguna parte del mundo usan procesadores basados en la arquitectura
VLIW como computadoras personales universales. VLIW, debido a sus características arquitectónicas, es una "trituradora de números" genial, hacen DSP en ella, hicieron servidores de itanium, hicieron tarjetas gráficas. No, con una excavadora, por supuesto, puedes cavar un hoyo para plantar un árbol, pero vale la pena.
El principal problema que impide el desarrollo de la arquitectura, en mi opinión, es la naturaleza cerrada de todo el ecosistema. Sí, para obtener una descripción del sistema de comando, solo necesita firmar el NDA, pero esto no es suficiente. La arquitectura es desconocida y muy compleja. Sí, siempre pensé que algún software básico debería desarrollarse directamente del fabricante del procesador, bien, o en estrecha colaboración con él. De acuerdo con este principio, una PC en Elbrus tiene un paquete de software con
el sistema operativo Elbrus . Pero aún así es demasiado ingenuo creer que una compañía, incluso una grande, puede proporcionar soporte de calidad a todos los componentes: un procesador, un compilador, herramientas de desarrollo y depuración, software del sistema (varios SO), software de aplicación, ... incluso Intel no puede hacer eso. El mundo lleva mucho tiempo avanzando hacia la llamada colaboración o desarrollo conjunto.
Déjame darte un ejemplo de un problema de compilación con el que nos topamos. El controlador del puerto serie en algún momento dejó de mostrar caracteres y, a primera vista, nada ha cambiado. Resultó que eliminamos la función de depuración no utilizada, que insertamos para comprender a través del desensamblador cómo pasar argumentos a la función en ensamblador. Es decir, si la función está presente, todo está bien, si no, entonces la salida desaparece. Al principio, pecaron por la alineación, pero resultó que la función se puede transferir al final de C-Schnick, por lo que todos los personajes del controlador estaban en los mismos lugares que antes, pero el problema se reprodujo. Si bien este problema no se ha resuelto, continuamos investigando para mostrar a los desarrolladores del compilador del MCST o para entender dónde cometimos un error.
El problema anterior, en mi opinión, podría haberse evitado si hubiera más usuarios de terceros. Como mínimo, el problema habría salido a la luz antes, o uno podría googlear lo que hicimos mal.
El ICST también es consciente del problema del cierre, ya que el proceso de descubrir cosas no clasificadas ha comenzado. Por ejemplo, vi a Alt-Linux trabajar en varias PC Elbrus en varias conferencias. Aquí hay fotos de la exhibición de una de las conferencias de este año (perdón por ver mal, estaba oscuro). También nos conectamos con el desarrollo. Esperamos que seamos útiles para el ICST, porque, como resultado, algunos de los aspectos más destacados de la arquitectura de Elbrus no pueden ser compatibles con Linux (o los costos son muy grandes), por ejemplo, memoria etiquetada.


Otro punto importante cuando discutimos el problema del cierre con los desarrolladores del MCST, objetaron que, por ejemplo, las fuentes del kernel de Linux estuvieron abiertas durante mucho tiempo, pero solo nosotros y los desarrolladores de Dolomant hicimos preguntas y las usamos de alguna manera.
Además, según mi información, el MCST organizará un stand
accesible de forma remota. En el cual será posible ensamblar y ejecutar software en una PC con arquitectura Elbrus. Si existe un interés similar y desea utilizar el soporte, debe comunicarse, por ejemplo, conmigo: describa cómo se planea usarlo, cuánto tiempo lleva, etc., porque para compartir con el cambio de software, debe organizar un cronograma. Transferiré los datos al ICST o conectaré a quienes deseen con los organizadores.
Enlaces utiles:
La dirección de correo de los usuarios es user [at] mcst.ru
Una breve descripción de la arquitectura de Elbrus.Fuentes de emboxPD:
Mostraremos a todos los que quieran lo que obtuvimos en el festival
TechTrain IT
del 1 al 2 de septiembre.