2019/12/29

Para estudiar The Zynq Book


Es un libro muy atado al producto... claro, se llama The Zynq Book, alguien en los comentarios de algún sitio que reclama por ello, pero ¿qué esperabas? Dice "con la colaboración de Xilinx" en la tapa.

Se puede obtener gratis, probablemente en http://www.zynqbook.com/download-book.php.



Tiene el problema de un fuerte sabor a marketing, muchas veces dice lo flexible, óptimo y adaptable que es Zynq. Luego hay un montón de información que es de algún modo genérica. Si tuviera la mitad de lo genérico y el cuádruple de lo de Zynq como para mantener la cantidad de páginas, hubiese sido excelente. La realidad es que a mi no me quedaron claras cosas como si el componente ethernet se puede acceder directamente desde la PL.

Lo bueno es que no explica nada de VHDL/Verilog/C/Assembly, supone que ya sabés.

Lo malo es que hay varios lugares donde se dan explicaciones de conceptos donde hubiese estado bueno un ejemplito en VHDL/Verilog.

Intel tiene algo parecido, con nombres como Arria, Stratix y Cyclone.

En apariencia, este tipo de SoC facilita esta evolución: de programar una CPU y diseñar hardware por separado a diseñar un sistema y con la ayuda de la herramienta implementar algunas partes en hardware y otras en software.

La idea es que lo simple y paralelizable va al hardware, lo complicado se queda en la CPU.


La verdad es que sea usando este tipo de SoC o los componentes separados no hace diferencia desde el punto de vista de la programación, incluso estoy seguro que el libro dice que lo que hagas en C/C++/SystemC sólo se va a ejecutar en un softcore, no es que generás código y la herramienta elige si ponerlo en los cores ARM. O al menos así era en 2014, tengo el "libro siguiente", motivo por el cual leí este pese a la mala crítica, quizás haya cambiado.

Me quedo con la idea de que el objetivo es hacer aceleradores para ser utilizados desde las CPU ARM, pero simplificando el diseño en la PL.


Zynq te permite desarrollar cosas que yo al menos no podría pues no tengo el conocimiento para interconectar una fpga con una cpu. Algo parecido a pasar de un micro + memoria(ram/rom) + uart a un microcontrolador que ya tiene todo adentro y sólo hay que configurar o ni eso.

De todos modos yo no puedo hacer nada con un zynq, necesito una Parallella, PYNQ o equivalente donde todo el hardware ya esté resuelto.

Los "ok" son relativos, para alguien que tiene experiencia de cada tema quizás estén de sobra, pero para mi siempre es un buen repaso.

  • 1 Intro ok
  • 2 Detalles hardware ok
  • 3 Detalles software, aplica a cualquier otro FPGA, ok
  • 4 Criterios de elección, ok
  • 5 Humo, completamente en vano
  • 6 Zedboard, ok para quien la tiene
  • 7 En vano
  • 8 Ejercicio
  • 9 Arquitectura de harware, modo superficial y adaptados a la arquitectura, ok
  • 10 Más detalles hardware, lo anterior aplicado a zynq, ok
  • 11 Más detalles software, aplica a cualquier otro FPGA, ok
  • 12 Ejercicio
  • 13 - 15 HLS, aplicable a cualquier FPGA, ok
  • 16 Ejercicio
  • 17 Ejercicio
  • 18 IP ok
  • 19 AXI ok
  • 20 Ejercicio
  • 21 Sistemas operativos ok
  • 22 - 24 Linux ok


Se complementa con unos tutoriales que están en http://www.zynqbook.com/download-tuts.html

Lo que me he propuesto es adaptar a mis placas PYNQ-Z2 ahora y algún día Parallella la experiencia desarrollada en los ejemplos prácticos.

Ejercicios

 

Te recomiendo que saltées esta parte y vayas directo a las conclusiones, a menos que estés siguiendo los tutoriales y te trabes, quizás algo te ayude.

Tambien si tenés una Zed o Zybo. En caso de otras placas, quizás quizás te sirva mirar por arriba lo que hice.


Estos son los pasos tomados de The_Zynq_Book_Tutorials_Aug_15.pdf, utilizando primero Vivado 2015.4, luego pasé a 2018.2 debido a que no vé la placa PYNQ.

Los dos primeros ejercicios consisten en pegarle unos IPs al Zynq y ejecutar un programa baremetal para prender los leds, luego leer los push buttons generando interrupciones y finalmente incorporar un timer, todo esto con AXI.

El tercero es de optimización, es un tanto avanzado para los básicos como yo, lo entiendo pero me dificultaría aplicarlo, pese a haber transitado el uso de PIPELINE en Forzando Brutalmente MD5.

El cuarto es crear tus propios IP, para usarlos en el quinto.


Todo versionado en github pero mal versionado pues está sin el .gitingore y además moví los ejercicios uno a tres así que no deben andar ni a palos, es más por backup que por proceso de desarrollo.



Exercise 1, First Designs on Zynq


Exercise 1A Creating a First IP Integrator Design


Registro los pasos tipo machete para futura referencia, te conviene seguir el tutorial, va todo igual salvo que hay que elegir la placa PYNQ.



Agregar la PYNQ a Vivado, con ayuda de https://pynq.readthedocs.io/en/v2.5/overlay_design_methodology/board_settings.html

dice que

<Xilinx installation directory>\Vivado\<version>\data\boards

y ahi hay dos carpetas, va en boards_files

Acá está la descripción para Vivado y acá el XDC


  • Create New Project
  • Elegir el board

Exercise 1B Creating a Zynq System in Vivado (2018.2)


  • Create Block Design (IP INTEGRATOR -> ...)
  • Add IP -> ZYNQ7 Processing System (Diagram -> ...)
  • Run Block Automation -> Apply Board Preset
  • Add IP -> GPIO (Diagram -> Add IP -> AXI GPIO)
  • Run Connection Automation -> S_AXI
  • Run Connection Automation - leds_4bits
  • File -> Save Block Design
  • Toos -> Validate Design
  • Windows -> sources
  • botón derecho -> Create HDL Wrapper
  • Generate Bitstream
  • Open Implemented Design
  • File -> Export -> Export Hardware -> include bitstream
  • File -> Launch SDK

Exercise 1C Creating a Software Application in the SDK

en particular en Import se usa lo de

The_Zynq_Book_Tutorial_Sources_Aug_15.zip,

la diferencia entre zybo y zed es el ancho de los leds, como PYNQ es 4 igual que Zybo, usé Zybo


kdiff3  zybo/first_zynq_design/LED_test_tut_1C.c zedboard/first_zynq_design/LED_test_tut_1C.c siempre ayuda para estos casos.

  • File -> New -> Application Project
  • Next -> Empty Application
  • Project Explorer -> el proyecto -> src -> Import -> ....
  • Xilinx Tools -> Program FPGA
  • Project Explorer -> el proyecto -> Run As -> Launch on Hardware

¡Anda!, ¡¡¡no lo puedo creer!!!




Exercise 2, Next Steps in Zynq SoC Design

2A-C Expanding the Basic IP Integrator Design

Podría continuar sobre el ejercicio 1 o empezar de cero, mejor para fijar los conocimientos. Las instrucciones ya están adaptadas a Vivado 2018.2


Es todo igual pero hay que agregar un AXI-GPIO extra y conectarle los botones.

Luego

  • Doble click axi_gpio_0 -> IP Configuration -> enable interrupt
  • Doble click processing_system_7 -> Page Navigator -> Interrupts -> 
    • Check Fabric Interrupts
    • Check Pl-PS Interrupt Ports -> IRQ_F2P[15:0]
  • Block Design -> Diagram -> connect
    • axi_gpio_0/ip2intc_irpt
    • processing_system_7/IRQ_F2P[0:0]
  • File -> Save Block Design
  • Tools -> Validate Block Design
y volvemos al caminito normal

  • Project Manager -> Sources -> right click on design -> Create HDL wrapper
  • Generate bitstream
  • (paciencia)
  • Open Implemented Design
  • File -> Export Hardware -> include bitstream
  • File -> Launch SDK
  • File -> New -> Application Project -> empty application
  • import...
  • Program FPGA
  • Y vuelve a andar, increible


Exercise2D Adding a Further Interrupt Source


Nada nuevo, sólo agregar un axi timer con la novedad de que hay que conectarlo a mano usando el IP concat, al pasar al SDK eliminar el proyecto e importar lo nuevo, interrupt_counter_tut_2D.c. Como me olvidé de versionar y taggear hasta el paso anterior, en mi código quedó con esta última versión.


Exercise 3 Designing With Vivado HLS


Exercise 3A Creating Projects in Vivado HLS

Van los pasos macheteados

  • Copiar sources/hls a tu workspace
  • Create New Project, con Project Location -> lo anterior
  • Add Files (Design Files) -> matrix_mult.cpp, matrix_mult.h
    • Top Function -> matrix_mult
  • Add Files (Testbench Files) -> matrix_mult_test.cpp
  • Solution Configuration
    • Clock Period -> 5
    • Boards -> elegí board
  • Close HLS
  • Open HLS Command Prompt
  • cd hasta tut3A
  • Otra vez kdiff3 al rescate, pues dice que ejecutes run_hls_zed.tcl o run_hls_zybo.tcl. La diferencia es part. De algún modo te enteras que es xc7z020clg400-1, con lo cual creás un run_hls_pynq.tcl 
  • vivado_hls -f run_hls_pynq.tcl
  • vivado_hls -p matrix_multlplier

Exercise 3B Design Optimisation in Vivado HLS

Lo que se hace es probar distintas soluciones de optimización hasta que alguna sea factible por timing.

  • Run C Simulation
  • C Synthesis
  • C/RTL Co-simulation -> VHDL
  • Project -> New Solution
    • Acá hay un problema con Part, no ve los boards, tuve que ponerle vía Part el correcto, xc7z020clg400-1
  • Select matrix_mult.cpp
  • Directives -> punto de inserción -> Insert Directive -> PIPELINE / ARRAY RESHAPE
  • C Synthesis 
    • Va a ir fallando según "punto de inserción" y la directiva que se use
  • Project -> Compare Reports -> Seleccionar los últimos y comparar...

Exercise 3C Interface Synthesis

  • cd tut3C
  • copiar run_hls_pynq.tcl de tut3A
  • vivado_hls -f run_hls_pynq.tcl
  • vivado_hls -p matrix_mult_prj
  • mirar el summary de la interface

Exercise 4 IP Creation

Exercise 4A Creating IP in HDL

  • Create New Project
    • no olvides poner VHDL como lenguaje que yo siempre me olvidé, esta vez sí hace diferencia
  • Tools -> Create and Package New IP
    • Create a new AXI4 peripheral 
    • Create Peripheral -> Edit IP
    •  se abrirá otra instancia
  •  Open led_controller_v1_0_S00_AXI.vhd
    • Agregar los ports de Zybo por el ancho de 4 bits
    • File -> Save
  • Open led_controller_v1_0.vhd
    • algo parecido

  • Package IP - led_controller
    • Customization Parameters
      • Merge changes from Customization Parameters Wizard
    • Ports and Interfaces -> check está ok
    • Review and Package -> edit packaging settings
    • Automatic behaviour, enable all (but Include source project archive in 2018.2)
    • Re-Package IP

  • Volver al proyecto original 
  • IP Integrator -> Create Block Design
    • Diagram -> Add IP -> led_controller
    • LEDs_out -> Right click -> Make external (ahi pone out_0)

Tip salvador para 2018.2, le pone al pin el nombre LEDs_out_0, hay que cambiarlo por LEDs_out
    • Add IP -> zynq7 processing system
    • Run Block Automation
    • Run Connection Automation
    • Tools -> Validate
  • Project Manager -> Sources -> Design Sources -> led_test_system -> Create HLD Wrapper 


  • Add Sources -> Constraints -> Create -> XDC -> pynq-z2_v1.0.xdc
  • Y acá hay que buscar en el XDC que bajamos en algún momento los nombres de los pines correspondientes a los leds:


set_property PACKAGE_PIN R14   [get_ports { LEDs_out[0] }]
set_property IOSTANDARD LVCMOS33  [get_ports { LEDs_out[0] }]

set_property PACKAGE_PIN P14   [get_ports { LEDs_out[1] }]
set_property IOSTANDARD LVCMOS33 [get_ports { LEDs_out[1] }]

set_property PACKAGE_PIN N16   [get_ports { LEDs_out[2] }]
set_property IOSTANDARD LVCMOS33 [get_ports { LEDs_out[2] }]

set_property PACKAGE_PIN M14   [get_ports { LEDs_out[3] }]
set_property IOSTANDARD LVCMOS33 [get_ports { LEDs_out[3] }]


  • Generate Bitstream
  • Open Implemented Design
  • File -> Export -> Export Hardware -> Include Bitstream
  • File -> Launch SDK

  • Luego en el SDK
  • File -> New -> Application Project
  • Empty Application
  • Xilinx Tool -> Repositories -> New
  • ip_repo -> led_controller (lo creado antes)
  • system.mss -> modify this BSP's Settings -> drivers -> led_controller
  • Project Explorer -> src -> import -> file system -> zybo -> led_controller
Aqui falla por undefined referencie to Xil_Out32, se corrige agregando a led_controller_test_tut_4A.c

#include "xil_io.h"

Sigamos
  • Xilinx -> Program FPGA
  • SDK Teminal -> Connect 
    • /dev/ttyUSB1 (o lo que haya)
  • Project Explorer -> Right Click -> Rus As -> Launch on Hardware(GDB)

Listo...

Exercise 4B Creating IP in MathWorks HDL Coder

Este implica usar MatLab, todo bien pero me aleja demasiado de mis propósitos, quizás algún día si me sobra tiempo lo haga. O eso es lo que había pensado hasta que ví que en la última parte hace falta lo generado por esta, así que a bajar el Matlab DEMO por 30 días.



  • Copiá la carpeta hdl_coder_lms a donde te guste
  • Dice que configures HDL Toolpath, no sé por qué con ISE, le puse directo Vivado:


hdlsetuptoolpath('ToolName', 'Xilinx Vivado', 'ToolPath', '/Xilinx/Vivado/2018.2/bin/vivado')

No dijo que estuviera mal, pero tampoco todo lo que el tutorial

  • Cambía al directorio de trabajo donde copiaste hdl_coder_lms
  • abrí lms.slx 
  • El mirar adentro es opcional
  • No pude hallar "HDL Code -> HDL workflow Advisor", pero si que yendo a Get Add-ons, buscar "hdl code", get trial  y un sales representative te contactará. 
Nuevamente se abre un nuevo mundo enorme y muy interesante de exploración que me alejan de mi propósito que es lograr un cierto dominio sobre Zynq y Vivado, lo siento Matlab, hasta aquí llegué.




Exercise 4C Creating IP in Vivado HLS

 

Este ejercicio al igual que el 3 me queda un poco grande
  • Abrir Vivado HLS
  • Create New Project
    • Add Files -> nco.cpp
    • Top Function ->nco
    • Add Test Files -> nco_tb.cpp
    • Part Selection -> usar part ya que no hay board
  • Ver *.cpp
  • Cambiar outfile a algo que te sirva
  • Run simulation
    • mirá el output
  • Seleccioná nco.cpp
  • Directive
    • Insertar todas las mencionadas
  • Run C Synthesis
  • Export RTL
Y en teoría esto sirve para el próximo

Exercise 5 Adventures with IP Integrator

Estos ejercicios integran lo anterior y dependen de generar un IP con Matlab que tal como relato arriba no pude lograr por motivos no técnicos.

Conclusiones


Pese a el problemita con Matlab, los ejercicios salvan al libro, si no sabés nada, tendrías que leer el libro, si sabés algo salteando los capítulos no ok y si sabés bastante quizás los ejercicios no te alcancen.

Los ejercicios en realidad son guías, si usas las versiones correctas y las placas consideradas sólo practicás recetas, quizás te cierre algún aprendizaje de la lectura del libro.



2019/12/22

VGA Rendering de simulación FPGA

Mientras estudiaba "Designing Video Game Hardware in Verilog" me hallé con que tenía que diagnosticar por que no funcionaban bien mis adaptaciones del código provisto a la Nexys 4 DDR que tengo con los ejemplos correspondientes a VGA (o mi doble adaptación a VGA por ser CRT).

Para no tener que pasar por todo el prolongado ciclo de modificar, sintetizar, implementar, generar el bitstream, burn it y tener que sacar el trasero de la silla para decirle al monitor que tome la entrada VGA en lugar del HDMI me hice un programita en TCL/TK que toma la salida de la simulación y me hace el render de las señales.

La verdad es que por lo valioso en términos educativos de este proyecto ni me molesté en ver si alguien ya lo había hecho, quizás por fin haya logrado aportar algo realmente útil. Mientras escribo esto veo que Xilinx tiene un repo de scripts para Vivado pero no llego a ver rápido si hay manera de ganarse una ventana dentro de la IDE, así que quedará para la Caja del Futuro.


En términos más formales:

El objetivo es hacer el render de una señal VGA generada probablemente por una simulación de un diseño Verilog o VHDL.

Los historias de usuario vienen a ser, "como usuario quiero que..."
  • Haga render de un frame
  • Haga render de varios frames consecutivos
  • Haga render de un frame  en "tiempo real", o sea, a medida que el simulador emita los datos
  • Haga render de varios frames consecutivos en "tiempo real"
  • Ajuste automático de resolución (640 x 480 la actual) 
  • Que entienda archivos standard tipo VCD
  • Que se pueda avanzar y retroceder
  • Que se pueda avanzar y retroceder usando el dispositivo ShuttleProV2


En verde lo que hice, no creo que avance con el resto pues esto es sólo un medio para lo que realmente quiero y no quiero que me distraiga.


Dado que hace muchos años trabajé con TCL/TK y me gustó y además Vivado usa TCL, más vale que empiece a recuperarlo, decidí usarlo para esta actividad.


En la carpeta "evolucion" dejé registrada la... evolución de mi acercamiento al problema, desde generar un patrón programáticamente en TCL/TK, pasando por mostrar las hsyncs y vsyncs, leer de un archivo, de STDIN y que finalmente funcione.

Los ejemplos 01_* a 04_* son los de "calibración", los restantes ya toman la salida de la simulación.





Entre las versiones 05_patternFromFile.tcl y 06_single_frame.tcl las diferencias significativas son:



  • Abstracción: en lugar de string index por todos lados, procs.
  • Lectura por STDIN
  • update para ver el rendering en tiempo real
  • y está bien alineado

La diferencia con la versión final, render.tcl es el multiframe


Con respecto a la salida de la simulación, primero investigué y no hay manera sencilla de acceder a lo generado pues está en una base de datos de formato desconocido para mi, así que opté por usar $strobe en el testbench con algo parecido a esto:



always @(negedge clock)
   $strobe("%b %b %b #%h%h%h", clock, hsync, sync, R, G, B);


Hay que generar el color tal que lo entienda TK o hacer una función adaptadora, opté por lo primero, mirá el código.


Podría quitar el clock ya que siempre es cero.

La simulación debe correr durante unos 8 ms para tener un frame completo entre vsyncs.




Me gustaría agregar colores distintos para las zonas no visibles que ahora está en negro y se confunde con la barra negra de la derecha, pero por ahora esto me sirve.


Es bastante lento, no me puse a optimizar, ni sé si se puede, de mis motivos originales sólo cumplo con no levantarme de la silla para cambiar la entrada del monitor.

Hay otra ventaja, la posibilidad de ver un sólo frame de una secuencia, que dependiendo del circuito real quizás no se pueda en la FPGA sin agregar lógica.




El video está fuertemente editado para que sólo se vea lo esencial de la interacción y el primer frame que no se muestra por no tener VSync está omitido, luego es tiempo real en una AMD A10-7700K Radeon R7.

Tambien corresponde a la versión de un solo frame, sin la simpática rayita blanca que muestra donde está dibujando, indispensable para multi frame.

El código en github

Esta es la captura de la última versión, con la simpática rayita y los límites de lo visible enmarcados en verde:




2019/11/30

Para estudiar Hardware Security


Estas son mis notas y actividades relacionadas con la atenta lectura y práctica parcial del libro Hardware Security: A Hands-on Learning Approach, que he leido en septiembre de 2019 y practico en la medida de lo posible ante cada oportunidad.




En el sitio hay un área docente y en mi calidad de autoinstruido, una condición simultánea de alumno/docente, quise acceder al material docente, recibiendo la respuesta:

Please use the student zone to access materials


Tambien pregunté cómo obtener un Ha-Ha board, que el libro dice hay proveedores pero en Internet no hay, sin respuesta.

Ya empezamos mal, a Stroustrup una vez le pregunté o señalé algo del libro Programming: Principles and Programming using C++ y si no él, al menos hubo alguien que se hizo pasar por él de modo extremadamente convincente y me contestó. Si esta gente con el libro recién editado no... bueno, como dijo Jonathan Swift:


Si una persona me mantiene a distancia, 
me consuela que también ella se mantiene.


Como este libro lo compré vía Amazon pude comentarlo, tomaré mi camino.


Crítica



Con respecto al libro, me ha resultado increiblemente bueno aunque objetivamente quizás no lo sea tanto, paso a explicar:


Cada tema generalmente se explica como si no hubieras leido los otros capítulos, lo cuál para mí está muy bueno, esa repetición genera un refuerzo y repaso. Hay una suerte de auto contención que de no estar, el libro tendría fácil la mitad de las páginas.


Tambien hay un cierta "desconexión", por ejemplo en la página XXX se menciona "como vimos en tal sección" remitiéndose a YYY, cuando era el tema de la sección anterior. Lamentablemente los valores de XXX e YYY los confié a mi memoria en el momento de leerlo, pero no funcionó.

Así que si sabés poco como yo, el libro es fantástico, si ya sabés algo, tiene mucho relleno, pero relleno útil, como que no tenés que estar buscando mucho las dependencias de un tema.



En síntesis, aunque es un muy buen libro, no cumple con "a hands-on learning approach" ya que no es posible hacer los ejercicios por falta de los enunciados.

A not so hands-on learning approach


A falta del Ha-Ha board y que no puedo acceder a los enunciados o guías de ejercicios, había considerado instructivo realizar una suerte de, más que ingeniería reversa, un acto de adivinación y me había propuesto hacer varios de los ejercicios en la medida que pudiera descubrir de qué se trata sin el enunciado.

Pero como tengo muchas otras cosas igual o más interesantes y urgentes que hacer, tuve que cambiar de enfoque y lo que he decidido es embeber en mis actividades el libro.

O sea, cada vez que haga algo que pueda relacionar con los ejercicios, lo registraré a continuación.




2019/11/25

Identificando versiones de programas

Supongamos que tengo que hallar versiones viejas de programas en una red y no puedo ejecutar:
 

$ programa --version

pues no puedo entrar a cada máquina, aunque si puedo ver su sistema de archivos. Tampoco hay un gestor de aplicaciones al cual consultar, incluso pueden haber programas instalados sin el uso de un usuario privilegiado, como puede ser un portable o compilado localmente.




Supongamos que tenemos el ejecutable identificado, como ejemplo usaré chrome.


En linux Mint y supongo Ubuntus está en:

/opt/google/chrome/chrome

En windows lo he hallado en lugares como:


C:\Program Files (x86)\Google\Chrome\Application\
C:\Users\XXXXX\AppData\Local\Google\Chrome\Application\


Primero hay que tener varias versiones identificadas:

chrome.lin.78.0.3904.97
chromium-browser.lin.65.0.3325.181
chrome.win32.24.0.1312.57
chrome.win.44.0.2403.155
 

chrome.win.51.0.2704.84
chrome.win.57.0.2987.133
chrome.win.62.0.3202.75 
chrome.win.78.0.3904.97

Las de linux se obtienen descomprimiento el deb que se consigue en  

http://security.ubuntu.com/ubuntu/pool/universe/c/chromium-browser/

¡Qué féo ese http sin la s!

Con grep vamos viendo si esos números están almacenados. 


$ grep 3904 chrome.*
Binary file chrome.lin.78.0.3904.97 matches
Binary file chrome.win.78.0.3904.97 matches

con -a le decimos a grep que los tome como archivos de texto pese a que son binarios. De pado limitamos el contexto de match con -o y con ".{32}".

$ grep -a -o '.\{32\}78\.0\.3904\.97.\{32\}' chrome.*

chrome.lin.78.0.3904.97:brtc/pc/peer_connection.cc:609778.0.3904.97id-smime-mod-ets-eSigPolicy-97
 
chrome.win.78.0.3904.97:test-child-processvvmodule78.0.3904.97GCM Store
 
chrome.win.78.0.3904.97:mblyIdentity type="win32" name="78.0.3904.97" version="78.0.3904.97" languag

Mmmm, ese último me gustó, probemos con algo más específico y sin -o



$ grep -a 'version="78.0.3904.97"' chrome.*
chrome.win.78.0.3904.97:<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"><dependency><dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity></dependentAssembly></dependency><dependency><dependentAssembly><assemblyIdentity type="win32" name="78.0.3904.97" version="78.0.3904.97" language="*"></assemblyIdentity></dependentAssembly></dependency><trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"><security><requestedPrivileges><requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel></requestedPrivileges></security></trustInfo><compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"><application><supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"></supportedOS><supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"></supportedOS><supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"></supportedOS><supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"></supportedOS><supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"></supportedOS></application></compatibility></assembly>( ;J�=I�=I�?L�@L�AM�BM�DP�AN�L]�DO�BO�CO�DP�EQ�FR�DR�GR�GS�OwdHT�IT�IU�Qo�IV�LW�Q\�Wb�[� [� >e�@e�]� ?f�[� \� >f�@g�]� ]�8]� Z�#^� _�[]� _� _� _� a�(`� `� a� b� b� c� ��Ie�!g�)��Jd�!��L��Mi�)Su�n�/��YZ�A��[��^P��J��O��<��?���ç�Ĩ�ĩ�Ū>��������D���Ѱ[��E��@���ձA��B��A��B��C��@��A��B��C��D��E��R��S��������������hhhhhhhhhhhhhhhhhhhhhh BQUhhhhhhhhhh FZYWhhhhhhh,&&#")TZY\hhhhh-**((>9E[ZYXhhhh//.@VJJRS[ZYhhh2113dC:7Af`[Z]hh455+L<::7Jc[Z]hh;60 L=<::Jb`[^hh;8 PD=<Cgaa_]hhh'
 
Me gusta cada vez más, quedémonos con la parte interesante de ese xml con identación para mejorar la lectura:

<assembly ...
   <assemblyIdentity
      type="win32"
      name="78.0.3904.97"
      version="78.0.3904.97"
      language="*"
   >
   </assemblyIdentity>
...
</assembly>

Y repitamos para las otras versiones con un nuevo grep ajustado:


$ grep -a -o "<assemblyIdentity type=\"win32\" name=\".\{16\}" chrom*
chrome.win.44.0.2403.155:<assemblyIdentity type="win32" name="44.0.2403.155" v
chrome.win.51.0.2704.84:<assemblyIdentity type="win32" name="51.0.2704.84" versio
chrome.win.57.0.2987.133:<assemblyIdentity type="win32" name="Microsoft.Window
chrome.win.57.0.2987.133:<assemblyIdentity type="win32" name="57.0.2987.133" v
chrome.win.62.0.3202.75:<assemblyIdentity type="win32" name="Microsoft.Window
chrome.win.62.0.3202.75:<assemblyIdentity type="win32" name="62.0.3202.75" ve
chrome.win.78.0.3904.97:<assemblyIdentity type="win32" name="Microsoft.Window
chrome.win.78.0.3904.97:<assemblyIdentity type="win32" name="78.0.3904.97" ve


Se me cayó linux, luego vemos. Para windows con esta regla ya estamos:

  • Si tiene información de versión
  • Y esa información no coincide con la versión que deseo

Dicho en yara:


rule ChromeWin
{
  strings:
    $version   = "<assemblyIdentity type=\"win32\" name=\""
    $version78 = "<assemblyIdentity type=\"win32\" name=\"78."
  condition:
    $version and not $version78
}

y su ejecución:

$ yara ruleChrome.yara .
ChromeNot78 ./chrome.win.51.0.2704.84
ChromeNot78 ./chrome.win.44.0.2403.155
ChromeNot78 ./chrome.win.57.0.2987.133
ChromeNot78 ./chrome.win.62.0.3202.75

Y así tenemos un modo que aunque dependiente del programa es independiente de las versiones menores y revisiones para identificarla estáticamente. Tambien pudimos usar un hash, pero hace falta identificar todos los casos.

Si sólo dejamos $version78, igual funciona, pero si hay otros programas los halla tambien.

Uh, uh, qué difícil, no? 

Quizás con linux suframos un poco más, veamos que tenemos:

$ grep -a -o ".\{16\}65.0.3325.181.\{16\}"chromium-browser.lin.65.0.3325.181
lurl_template65.0.3325.181BREAKPAD_DUMP_L

$ grep -a -o ".\{16\}78.0.3904.97.\{16\}" chrome.lin.78.0.3904.97

nection.cc:609778.0.3904.97id-smime-mod-e
 
Está en el medio de la nada, ni siquiera es un null terminated string, nos puede servir hallar en que section se encuentra, comenzando por el offset en el archivo:


$ hexdump -C chrome.lin.78.0.3904.97 | grep 3904
01039040  2f 76 69 64 65 6f 5f 62  69 74 72 61 74 65 5f 61  |/video_bitrate_a|
010db670  37 38 2e 30 2e 33 39 30  34 2e 39 37 00 69 64 2d  |78.0.3904.97.id-|
01139040  64 65 66 69 6e 65 64 2e  00 72 65 71 75 69 72 65  |defined..require|

Ahora hay que buscar donde cae el offset 010db670, tiene que estar en la zona amarilla, en realidad en la sección anterior a la valor inmediatamente mayor.
 
$ readelf -S --wide chrome.lin.78.0.3904.97
There are 38 section headers, starting at offset 0x91713c8:

Section Headers:
[Nr] Name              Type      Address    Off    Size   Flg
[ 0]                   NULL      00000000  000000  000000  
[ 1] .interp           PROGBITS  000002e0  0002e0  00001c   A
[ 2] .note.ABI-tag     NOTE      000002fc  0002fc  000020   A

[ 3] .note.gnu.build-id NOTE     0000031c  00031c  000024   A
[ 4] .dynsym           DYNSYM    00000340  000340  009ab0   A
[ 5] .gnu.version      VERSYM    00009df0  009df0  000ce4   A
[ 6] .gnu.version_r    VERNEED   0000aad4  00aad4  0003b0   A
[ 7] .gnu.hash         GNU_HASH  0000ae88  00ae88  0001dc   A
[ 8] .dynstr           STRTAB    0000b064  00b064  007ab9   A
[ 9] .rela.dyn         RELA      00012b20  012b20  e16a68   A
[10] .rela.plt         RELA      00e29588  e29588  009210   A
[11] .rodata           PROGBITS  00e32800  e32800  c047bf AMS
[12] protected_memory  PROGBITS  01a36fc0 1a36fc0  0001f8   A

[13] .gcc_except_table PROGBITS  01a371b8 1a371b8  001aac   A
[14] .eh_frame_hdr     PROGBITS  01a38c64 1a38c64  007c44   A
[15] .eh_frame         PROGBITS  01a408a8 1a408a8  01c464   A
[16] .text             PROGBITS  01a5d000 1a5d000 7028912  AX
[17] .init             PROGBITS  08a85914 8a85914  000017  AX
[18] .fini             PROGBITS  08a8592c 8a8592c  000009  AX
[19] malloc_hook       PROGBITS  08a85940 8a85940  000556  AX
...

Key to Flags:
 W (write), A (alloc), X (execute), M (merge), 

 S (strings), l (large),  I (info), L (link order),
 G (group), T (TLS), E (exclude), x (unknown),
 O (extra OS processing required),
 o (OS specific), p (processor specific)

Lo cual es razonable pues hasta donde entiendo los strings como este en .rodata deben estar.


$ objdump -s -j .rodata chrome.lin.78.0.3904.97 \
 | grep 3904 -A 2 -B 2 

10db650 62727463 2f70632f 70656572 5f636f6e  brtc/pc/peer_con
10db660 6e656374 696f6e2e 63633a36 30393700  nection.cc:6097.
10db670 37382e30 2e333930 342e3937 0069642d  78.0.3904.97.id-
10db680 736d696d 652d6d6f 642d6574 732d6553  smime-mod-ets-eS
10db690 6967506f 6c696379 2d393700 69642d73  igPolicy-97.id-s


más arriba cuando había dicho ni siquiera es un null terminated string me equivoqué, ahí está clarito el null.
Pero esto seguro cambia de versión en versión.

$ objdump -s -j .rodata chromium-browser.lin.65.0.3325.181 \
 | grep 65\.0\.3325 -A 2 -B 2

6d32960 00636872 6f6d6500 7469746c 65007465  .chrome.title.te
6d32970 78740075 726c0075 726c5f74 656d706c  xt.url.url_templ
6d32980 61746500 0036352e 302e3333 32352e31  ate..65.0.3325.1
6d32990 38310042 5245414b 5041445f 44554d50  81.BREAKPAD_DUMP
6d329a0 5f4c4f43 4154494f 4e005061 796d656e  _LOCATION.Paymen



Ok, quizás buscando un string de cuatro enteros separados por puntos entre dos nulos funcione... demasiado, trae toda dirección IP



$ grep -a -o -P \
 "\x00[1-9][0-9]*\.[0-9]+\.[0-9]+\.[0-9]+\x00" \
  chromium-browser.lin.65.0.3325.181  \
  chrome.lin.78.0.3904.97

chromium-browser.lin.65.0.3325.181:6.5.254.41
chromium-browser.lin.65.0.3325.181:65.0.3325.181
chromium-browser.lin.65.0.3325.181:239.255.255.250
chromium-browser.lin.65.0.3325.181:127.0.0.1
chrome.lin.78.0.3904.97:78.0.3904.97
chrome.lin.78.0.3904.97:7.8.279.23
chrome.lin.78.0.3904.97:4.10.1582.1
chrome.lin.78.0.3904.97:127.0.0.1
chrome.lin.78.0.3904.97:224.0.0.251
chrome.lin.78.0.3904.97:239.255.255.250
chrome.lin.78.0.3904.97:127.0.0.1

¡Qué problema! El orden no significa nada, sólo podríamso descartar algunas IPs muy evidentes como  127.0.0.1 y 239.255.255.250,pero nos empieza a obligar a tener una lista de versiones más estrictas.

No es tan terrible. para cada programa candidato, obtenemos la lista de strings potenciales y si alguna coincide con versiones correctas o incorrectas. 

Esta parte de linux ha sido para practicar lo aprendido en el libro Practical Binary Analysis, cuya reseña en pocas semanas publicaré.



2019/11/13

Rescatando un touchpad



Hallé tirado el cadáver vandalizado de una Toshiba Satellite a la que le quedaba la pantalla (b140xw0 v.8), el mother, el cooler, el chip wifi (Atheros AR5B95 Wireless Network Adapter con conector mini-pcie), los mini speakers, seguro que hay una flash por ahí que no pude encontrar y el touchpad, Synaptics 920-001019-02 rev A:



Foto tomada de algún foro ruso


Primero lamenté haber tirado el circuito que había entre el touchpad y el mother, pues me había parecido que sólo le agregaba los botones físicos. Luego, cuando ví esta foto me confundí, pensé... no sé qué pensé.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfJZXKpcWy30Ch1Z5iG0Vne-TB2ab055GqMhXTToXkhspy41NyEu18F5MZcOGOcwnOmNevQUxtvK3GbaLBb-Snmr6wC1f0G7paTMcaWldggPRSkiLoK7Oi7XyWBv5fBEMHNWqnO8NF5hOu/s1600/synaptic-apple-mag-g3-2_v1.PNG


Ahí me dí cuenta que esas letras amarillas estan asociadas los pines del chip y no a los test points o al conector,


Tambien me sobran cables con respecto al conector DIN, entonces reflexioné:

¿Y si 4 y 5, botón derecho e izquierdo no son salidas si no entradas al dispositivo? Eso sería razonable, en caso contrario la interfaz del lado de la computadora debería entender por un lado los mensajes del mouse y por otro los botones.

Lo que debe ocurrir es que el chip lee 4 y 5 los codifica en PS/2 data como corresponde.

Seguro que en la documentación está pero siendo un auténtico programador, cuanto más tarde en leerla ¡¡mejor!!



Ayuda que esté en Amazon como un componente aislado, pues entonces no hay dependencias intermedias.



En lo más parecido a una datasheet que hallé dice que puede ser PS/2, ADB o serial, apostaré a PS/2, respaldado por la mención en esta conversación.



Con el tester y comparando con esa datashit hice este mapeo, parece bastante compatible con esto:





pin mini din 6testpointpin chipcomentario
1 +5vT20 T2244
2 dataT103spoiler: clock
3 clkT112spoiler: data
4 switchT67
5 switchT76
6 groundT2345


Esto está respaldado por GIMP, usando pencil tool + shift. Intenté con Fuzzy Select pero la imagen no tiene la suficiente calidad.





Me ofende que con respecto al otro chip estén invertidos data y clk, igual no sé si son los mismos chips...



¿Cómo sigo? ¿Le adapto un conector mini DIN 6 y lo conecto a una PC vieja? ¿Tán fácil? Ni tanto, quizás tendría que cargarle el driver del synaptic, si no me sale nunca voy a estar seguro del motivo de la falla.

El problema es que si mirás el mapeo más arriba, Data y Clock están invertidos, no tengo documentación confiable, tengo que distinguir probando cuál es cada uno.  En las menciones a T10 y T11 en esta conversación todo parece confirmar que el pin chip 2 es data y el 3 clock, tambien en esta y esta, así que será el primer intento.


Le tendría que dar power, clock y mirar que aparece en data, que es el Camino Correcto Más Difícil Pero Más Cierto. Tengo que poner Cierto y no Seguro por que Seguro me transmite una seguridad en todo aspecto y lo más seguro es que queme algo, mejor Cierto como cercano a la Verdad.

Pero, en los programas que hay en esos links y recuerdo en el pdf, hay un protocolo a seguir, me parece improbable que por el simple hecho de darle corriente y clock aparezca algo en data, igual quizás pueda confirmar el pinout.


Los 5v me condenan a usar arduino en lugar de edu-ciaa-nxp. De paso puedo probar que funcione la conexión a PS/2 con algún dispositivo así no tengo dos incógnitas a la vez.


Arduino PS/2 a teclado o mouse


Como tengo un teensy, sigo los pasos para instalar teensyduino, que consiste en bajarse Arduino IDE e instalar, tomando nota de la ruta, bajar el instalador de teensyduino, aplicar udev rules, ejecutar el instalador de teensyduino para ver que versiones de Arduino IDE soporta. En este momento soporta 1.8.10 que es la última, ijuu!!


Next, next, los next que hagan falta y darle la ruta que recordaste antes.

Por las dudas un blinky primero: ejecutar la IDE, elegir teensy2.0++ como target, buscar el ejemplo de blinky, elegir pin 6 como led, si no baja el programa de una, configurar asi:

  • usb type: serial
  • cpu speed 16 Mhz
  • port: /dev/ttyACM0 serial (teensy 2++)
  • programmer: avr isp o avr isp mkii, tira un error pero funciona...



Luego hay que bajar y copiar las librerías de PS/2 en

~/bin/arduino-1.8.10/libraries


Conectarle un mouse y ver que anda con el ejemplo.


Por suerte tengo un cajón lleno de porquerías, por ejemplo este adaptador de un montón de cosas, incluido mini din 6 pines:


(1) Data, (3) Ground, (4) 5v, (5) Clock


Tuve que usar un teclado pues parece que tiré todos los mouses PS/2 que tenía.


Usé el ejemplo ./libraries/ps2/examples/ps2_kbd/ps2_kbd.pde con

// pin 3 data
// pin 5 clock
// kdbd(clock, data)
PS2 kbd(5,3)


Separé los pines para poder meter las puntas del osciloscopio, muy bonito, otro día exploraré el encoding.

No presté atención a qué tecla oprimí, sólo sé que 71 F0 71 vino por el serial monitor



Arduino PS/2 a touchpad


Como seguimos sin saber cual es clock y cual es data, le voy a poner una resistencia de 4k7 en serie a ver que pasa.


No pasa nada, ni al derecho ni al revés, pruebo sin resistencias:




Lo que cambié con respecto al ejemplo fue ajustar los pines en

./libraries/ps2/examples/ps2_mouse/

// pin 3 data
// pin 5 clock
// kdbd(clock, data)
PS2 mouse(5,3);


y este if para que el monitor no se llene de basura:

   // send the data back up
  if (mx != 0 || my != 0 ) {
    Serial.print(mstat, BIN);
    Serial.print("\tX=");
    Serial.print(mx, DEC);
    Serial.print("\tY=");
    Serial.print(my, DEC);
    Serial.println();
  }


Listo, anda, a otra cosa, algún día lo conectaré a algo. Dos fotitos más para quienes prefieren dibujitos a leer:



 El detalle de los cables y los puntos de soldado en los TP




El sensor pegado a la tapa de una caja de tarjetas


2019/11/05

Para estudiar Free Range VHDL

Estas son los recursos de los que me he servido para estudiar y practicar el fantástico libro Free Range VHDL, que se puede comprar, se puede bajar mediante un formulario que no me anduvo o se puede generar el pdf a partir del latex:

$ sudo apt get latex-full
$ git clone https://github.com/fabriziotappero/Free-Range-VHDL-book.git 
$ cd Free-Range-VHDL-book
$ chmod 755 clean compile
$ ./compile

latex-full es un poco drástico y son 3.5 GB, seguro que hay una opción más óptima o sudo apt remove latex-full al terminar.


El libro no explica como sintetizar ni simular ni generar el bitstream ni programar el dispositivo.

Sintetizar


Probé primero con gvhdl pues está en los repos de la distribución, pero no andaban bien y el Colo me señaló esta conversación y me recomendó ghdl:




$ sudo apt install gnat-5                    ;# 100 MB

$ git clone https://github.com/ghdl/ghdl.git ;# 110 MB
$ cd ghdl
$ git checkout -b v0.36

$ mkdir build
$ cd build
$ ../configure
$ make
$ sudo make install


<nota de color>

El tener que crear el directorio build es medio chancho y se debe a que no está versionado. Hay al menos dos maneras de versionar una carpeta "vacía" en git:


$ touch build/.gitkeep 
$ git add build

o esta un poco más retorcida pero indudablemente más completa, pues si te olvidás de hacer un clean lo que haya adentro no te aparece. Un .gitignore dentro de la carpeta con este contenido:

*
!.gitignore


</nota de color>



Luego es tan sencillo como


$ ghdl -a hello_world.vhdl
$ ghdl -e hello_world
$ ghdl -r hello_world


Que en nada se va a manifestar a menos que usés std.textio o generés waveforms.

Con respecto a los nombres, -e y -r usan el nombre de la entity que haya dentro del vhdl.


Las manifestaciones pueden ser por stdout o volcar las señales a un archivo que entienda gtkwave.

STDOUT

Hay que usar una libreria llamada textio. Luego, se escriben en una variable valores con formato y eventualmente se vuelcan en stdout:


Mensajes a stdout



Además de write() existen hwrite(), owrite() y brite() que imprimen en hexa, octal y binario pero no me los entiende mi ghdl, pese a que están en el código. Son los que hacen falta para imprimir los vectores.

Tambien se puede imprimir a archivos, pero ni lo probé, no sé si intentaré solucionarlo, lo veré cuando explore más a fondo el tema de simulación.

Lo mejor que hallé es https://lauri.võsandi.com/hdl/ghdl.html

Cuidado que --help no dá todas las opciones que si están en las migajas de más abajo.



Waveform


$ sudo apt install gtkwave

Luego, en teoría, si tomás el ejemplo del lauri:

$ ghdl -a full_adder.vhd full_adder_testbench.vhd

$ ghdl -e full_adder_testbench
$ ghdl -r full_adder_testbench \
               --vcd=out.vcd \
               --fst=out.fst \
               --wave=out.wave

deberías poder usar gtkwave, pero pese a lo que dice la documentación, gtkwave no entiende out.wave. Además, los otros dos archivos, aunque son válidos y proveen información de los pines, no hay datos. O eso pensé, luego miré http://enos.itcollege.ee/~vpesonen/lisa/lab_example.html
y aunque no lo dice, logré deducir que hay que pedirle:


  1. elegir un componente en la jerarquía
  2. elegir un pin o bus en las señales
  3. append/insert/replace



Había pensado subir mis resultados de los ejercicios del libro y mis propios ejercicios a github, pero me distraje con otro libro, asi que lo que está es algo muy incompleto.

Lamentablemente no sólo me distraje con ese libro si no con todo mi proyecto de Forzando Brutalmente MD5 y perdí contacto con VHDL, en algún  momento cuando necesite, retomaré.

Para poder hacer todo esto tuve que seguir las migajas:

https://ghdl.readthedocs.io/en/latest/
https://ghdl.readthedocs.io/en/latest/building/Building.html
https://ghdl.readthedocs.io/en/latest/building/mcode/GNULinux-GNAT.html
https://ghdl.readthedocs.io/en/latest/using/Simulation.html
https://vhdlguide.wordpress.com/2017/09/22/textio/

La conversación previamente mencionada me llevó a este interesante documento, http://qucs.sourceforge.net/docs/tutorial/digital.pdf