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