Luis Angel Cofiño

Trucos Linux

Sección Once





Secciones

Índices

  1. 11/11/2006: Mi tarjeta PCMCIA USB 2.0 Conceptronic CSP480C2 no funciona con algunos dispositivos
  2. 12/01/2007: He actualizado mi kernel, y ahora mi Pinnacle PCTV solo mete ruido.
  3. 26/3/2007: ¿Puedo conectar el portátil a un móvil HTC p3600 con tecnología 3G?
  4. 28/10/2007: Cómo encriptar una partición de disco duro con dm-crypt
  5. 06/11/2007: Instalar dataplot en Gentoo

  * *

¿Puedo conectar el portátil a un móvil HTC p3600 con tecnología 3G?

Sí, claro que puedes.

A estas alturas ya tengo probados unos cuantos móviles de distintos tipos y compañías. Nunca me he preocupado de si estarían o no soportados por Linux. Y hasta el momento siempre he podido usarlos. El móvil HTC p3600, más conocido por sus fans como "Trinity", o como la "Trini", no es ninguna excepción en ese sentido, aunque es un teléfono muy particular porque en realidad es un híbrido entre PDA y móvil que usa Windows Mobile 5.0, con lo que se encuadraría en el terreno de las PocketPC.

Técnicamente, la Trinity es un dispositivo Windows Mobile 5 AKU3. Si has leído la sección sobre el Sharp 703SH, te diré que esto significa que no ofrece ningún perfil DUN, por lo que no puedes conectarte de la misma forma que con los móviles corrientes. En lugar de eso, la Trinity (y por extensión, se supone que cualquier dispositivo AKU3), ofrece un perfil PAN, lo que significa que se comporta como una especie de emulación de red Ethernet con NAT activo, es decir, que puede hacer navegar por Internet simultáneamente a la PDA y al Linux de tu portátil, y que se utiliza una asignación de IP para establecer el enlace entre ambas máquinas.

A decir verdad, poner esto en marcha es bastante fácil, pero hay que saber cómo hacerlo. Afortunadamente, nuestro amigo Moucha comentó como hacerlo en los foros de XDA-Developers. Muchas gracias, Moucha.

Asumo que tienes configurada una conexión a Internet en la Trinity. Es decir, asumo que con ella puedes navegar con el Explorer, por ejemplo. Si no es así, googlea un poco y configúralo, anda. Luego vuelve aquí y seguimos para que puedas navegar también con el portátil Linux.

¿Ya?. Bueno, pues al igual que con un teléfono móvil Bluetooth (que es como vamos a establecer en enlace con la Trini), tienes que tener capacidad Bluetooth en tu portátil (eso es de cajón), e instalar el paquete Bluez Utils.

 
[lacofi@lynette]$ su
password:
[root@lynette]# emerge bluez-utils gnome-bluetooth kdebluetooth

Ahora arranca el subsistema bluetooth y mételo en los scripts de arranque para lo haga siempre de forma automática.

 
[root@lynette]# /etc/init.d/bluetooth start
[root@lynette]# rc-update add bluetooth default

Ahora tienes que modificar tu kernel (2.6.x) para incluir soporte BNEP. Haz un "make menuconfig", vete a Networking, vete a Bluetooth subsystem support, y activa las casillas: BNEP protocol, Multicast filter, Protocol filter, y HIDP, además del Bluetooth device adecuado a tu caso (yo uso un lápiz USB Conceptronic Bluetooth, por lo que tengo activado el dispositivo HCI BCM203x). Ahora recompila y reinicia con el nuevo kernel. Si has activado BNEP dentro del kernel ya no tienes que hacer nada. Si lo has hecho como módulo tendrás que usar "modprobe bnep". ¿Vale?.

Ahora lógate en tu máquina Linux, a ser posible en KDE. Entra en el menú K, vete a Internet y ejecuta el demonio servidor "kbluetoothd". Con esto, debería aparecer en tu bandeja del sistema el logo de Bluetooth en tono gris, indicando que está escuchando pero no conectado.

Ahora entra en tu Trinity, vete a Inicio, vete a Configuración, vete a la pestaña Conexiones y abre el Administrador de Comunicación. Entra en Configuración y elige Bluetooth. Activa Bluetooth y la casilla "Permitir que sea visible". Vete a Dispositivos y pulsa en "Añadir nuevo dispositivo", con lo que debería detectar a tu portátil como Broadcom BCM2035 o similar. Mientras haces esto, te pedirá una contraseña. Mete una serie de números (8 cifras, por ejemplo). Ahora mira al portátil. En pantalla debería pedirte que metas la misma contraseña. Métela. Ahora vuelve a mirar al teléfono. Con esto la Trinity debería mostrar en la lista de Dispositivos al Broadcom BCM2035. Esto significa que ambos han quedado emparejados y se reconocen el uno al otro como dispositivos autorizados. Y nunca volverán a pedirte esa contraseña, simplemente bastará con que actives el Bluetooth de la Trini.

Una vez emparejados, coge la Trinity y cierra la configuración. Vete a la pantalla de Hoy. Vete a Inicio. Vete a Programas. Arranca "Conexión compartida". En "Conexión de PC" elige "PAN de Bluetooth". Luego pulsa en "Conectar".

Ahora abre una ventana Terminal en Linux y ejecuta una serie de comandos para arrancar el demonio de soporte de Bluez PAN, pídele al demonio que busque un dispositivo emparejado y se conecte a él, y luego crea una red Ethernet con él que te permita enganchar Internet. Esto es lo que nos contaba Moucha:

 
[root@lacofi]# pand -s -r PANU 
[root@lacofi]# pand -Q10
[root@lacofi]# pand -l
(esto debería mostrarte la MAC de la Trini. Ahora levantamos la red.)
[root@lacofi]# ifconfig bnep0 192.168.0.2
[root@lacofi]# route add default gw 192.168.1
[root@lacofi]# echo "nameserver 194.102.255.2" > /tmp/resolv.conf.bnep0

Y ya está. Si todo ha ido bien, ahora tienes ya tu Linux conectado a Internet a través de la Trini. Observa que el símbolo de Bluetooth de la bandeja del sistema de KDE, ha cambiado a color azul indicando que está conectado. Naturalmente, puedes crear un script con todos estos comandos para que con una sola orden te conectes a Internet. :-)

Pero eso no es todo. Si en la Configuración Bluetooth de la Trini activas la compartición FTP, puedes usar los menús del icono de Bluetoothd (en la bandeja del sistema de KDE) para intercambiar ficheros entre Linux y la Trinity, y alguna cosilla más que dejo que descubras por tí mismo. :-)

Para cerrar la conexión y deshacerlo todo, solo tienes que pulsar "Desconectar" en la Trini. Disfrútalo.

  * *

Mi tarjeta PCMCIA USB 2.0 Conceptronic CSP480C2 no funciona con algunos dispositivos

Googleando un poco se llega facilmente a la conclusión de que la tarjeta PCMCIA (o sea, PCCard) Conceptronic CSP480C2 funciona perfectamente en Linux. Así está recogido por ejemplo en la Web de TuxMobil, pero aparte de eso no te dicen mucho más. En otros foros, encuentras que sí, que se supone que funciona pero que da algunos problemas variados.

Todo lo que voy a contar, vale también para la tarjeta PCMCIA Inves USB 2.0 que proporciona dos puertos, y que es reconocida por lspci como una NEC Corporation (ENE Technology Inc CB1410 Cardbus Controller)

Yo me compré una tarjeta de esas y, efectivamente, funcionaba pero me encontré con unos cuantos problemillas que me costó un poco solucionar. Concretamente, solo conseguía hacerla pillar un lápiz USB LG de 1Gb que usaba USB 2.0, pero ningún dispositivo USB 1.1 era detectado (ni siquiera un lápiz USB MemoryBird de 64 Mb que se supone debería funcionar con todo). Curiosamente, tampoco conseguí hacer que vaya un disco duro externo LaCie Mobile de 80 Gb que es también USB 2.0. Una cosa muy rara, eso de que solo funcione uno de los aparatos y ninguno más.

Bien, lo primero de todo es usar un Kernel recientito. Yo estoy con un 2.6.17 bajo Gentoo, pero seguramente servirá cualquier kernel de la serie 2.6. Si usas gentoo, NO debes instalar pcmcia-cs. Ese paquete está creado kernels 2.4.x, así que no debería usarse con ningún kernel 2.6. En lugar de eso, asegúrate de que estás usando hotplug y udev.

Este era el punto de partida cuando compré la tarjeta. La salida de dmesg al enchufarla decía:

 
(blablabla y aquí insertamos la tarjeta pcmcia)
pccard: CardBus card inserted into slot 0
yenta EnE: chaning testregister 0xC9, 00 -> 00
PCI: Enabling device 0000:03:00.2 (0000 -> 0002)
ACPI: PCI Interrupt 0000:03:00.2[C] -> Link [LNKC] -> GSI 11 (level, low) -> IRQ 11
ehci_hcd 0000:03:00.2: EHCI Host Controller
ehci_hcd 0000:03:00.2: reset hcs_params 0x2395 dbg=0 cc=2 pcc=3 ports=5
ehci_hcd 0000:03:00.2: reset portroute 1 0 1 0 0 
ehci_hcd 0000:03:00.2: reset hcc_params e806 thresh 0 uframes 256/512/1024 park
ehci_hcd 0000:03:00.2: park 0
ehci_hcd 0000:03:00.2: MWI active
ehci_hcd 0000:03:00.2: ...powerdown ports...
drivers/usb/core/inode.c: creating file '005'
ehci_hcd 0000:03:00.2: new USB bus registered, assigned bus number 5
ehci_hcd 0000:03:00.2: irq 11, io mem 0xd2002000
ehci_hcd 0000:03:00.2: reset command 080b02 park=3 ithresh=8 period=1024 Reset HALT
ehci_hcd 0000:03:00.2: init command 010009 (park)=0 ithresh=1 period=256 RUN
ehci_hcd 0000:03:00.2: USB 2.0 started, EHCI 1.00, driver 10 Dec 2004
usb usb5: default language 0x0409
usb usb5: new device strings: Mfr=3, Product=2, SerialNumber=1
usb usb5: Product: EHCI Host Controller
usb usb5: Manufacturer: Linux 2.6.15-kal ehci_hcd
usb usb5: SerialNumber: 0000:03:00.2
usb usb5: hotplug
usb usb5: adding 5-0:1.0 (config #1, interface 0)
usb 5-0:1.0: hotplug
hub 5-0:1.0: usb_probe_interface
hub 5-0:1.0: usb_probe_interface - got id
hub 5-0:1.0: USB hub found
hub 5-0:1.0: 5 ports detected
hub 5-0:1.0: standalone hub
hub 5-0:1.0: individual port power switching
hub 5-0:1.0: individual port over-current protection
hub 5-0:1.0: Single TT
hub 5-0:1.0: TT requires at most 8 FS bit times (666 ns)
hub 5-0:1.0: power on to power good time: 20ms
hub 5-0:1.0: local power source is good
hub 5-0:1.0: enabling power on all ports
hub 5-0:1.0: state 5 ports 5 chg 0000 evt 0000
drivers/usb/core/inode.c: creating file '001'

Al enfhufar el MemoryBird que no funcionaba, la salida de dmesg era idéntica, era como si no hubiera enchufado nada.

Y la salida de lspci al meter la tarjeta decía:

 
00:00.0 Host bridge: Intel Corporation 82855PM Processor to I/O Controller (rev 03)
00:01.0 PCI bridge: Intel Corporation 82855PM Processor to AGP Controller (rev 03)
00:1d.0 USB Controller: Intel Corporation 82801DB/DBL/DBM USB UHCI Controller #1 (rev 03)
00:1d.1 USB Controller: Intel Corporation 82801DB/DBL/DBM USB UHCI Controller #2 (rev 03)
00:1d.2 USB Controller: Intel Corporation 82801DB/DBL/DBM USB UHCI Controller #3 (rev 03)
00:1d.7 USB Controller: Intel Corporation 82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (rev 03)
00:1e.0 PCI bridge: Intel Corporation 82801 Mobile PCI Bridge (rev 83)
00:1f.0 ISA bridge: Intel Corporation 82801DBM (ICH4-M) LPC Interface Bridge (rev 03)
00:1f.1 IDE interface: Intel Corporation 82801DBM (ICH4-M) IDE Controller (rev 03)
00:1f.3 SMBus: Intel Corporation 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller (rev 03)
00:1f.5 Multimedia audio: Intel Corporation 82801DB/DBL/DBM AC'97 Audio Controller (rev 03)
00:1f.6 Modem: Intel Corporation 82801DB/DBL/DBM AC'97 Modem Controller (rev 03)
01:00.0 VGA compatible controller: ATI Technologies Inc Radeon R250 Lf [FireGL 9000] (rev 01)
02:00.0 FireWire (IEEE 1394): VIA Technologies, Inc. IEEE 1394 Host Controller (rev 80)
02:01.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL-8139/8139C/8139C+ (rev 10)
02:02.0 Network controller: Intel Corporation PRO/Wireless LAN 2100 3B Mini PCI Adapter (rev 04)
02:03.0 CardBus bridge: ENE Technology Inc CB1410 Cardbus Controller
03:00.0 USB Controller: NEC Corporation USB (rev 43)
03:00.1 USB Controller: NEC Corporation USB (rev 43)
03:00.2 USB Controller: NEC Corporation USB 2.0 (rev 04)

Da la impresión de que la tarjeta pcmcia ha sido reconocida y que proporciona dos puertos USB 2.0, pero luego resulta que solo el lápiz USB 2.0 LG de 1Gb me funcionaba.

El problema es que si sigues las instrucciones habituales, tendrás activado el soporte EHCI y UHCI para USB, porque la mayoría de los USB actuales son UHCI, como ocurre por ejemplo en el portátil Highscreen CL50. Pero ahí es donde está el problema, porque resulta que la tarjeta PCMCIA usa el estándar OHCI, así que también tienes que activar el soporte de OHCI en tu kernel.

Vale, vamos a modificar tu kernel. ha de estar cofigurado para usar las Cardbus de 32 bits como ésta. Pero aparte de eso, tendrás que entrar en el apartado de USB y activar EHCI (para soporte de USB 2.0), UHCI (para soporte de los USB del portátil), y OHCI (para soporte de los USB de la tarjeta PCMCIA). Tal que así:

 
Haz un "make menuconfig" y elige:

Bus Options (PCI, PCMCIA, EISA, MCA, ISA) -->
  PCCARD (PCMCIA/CardBus) suport -->
	 <M> PCCard (PCMCIA/Cardbus) support
	 [ ]	Enable PCCARD debugging
	 <M>	16-bit PCMCIA support
	 [*]		Load CIS updates from userspace
	 [ ]		PCMCIA control ioctl
	 ---	32-bit Cardbus support
	 ---	PC-card bridges
	 <M>	CardBus yenta-compatible bridge support
	 <M>	Cirrus PD6729 compatible bridge support
	 <M>	i82092 compatible bridge support
	 <M>	i82365 compatible bridge support
	 <M>	Databook TCIC host bridge support
Device Drivers -->
  USB Support -->
	 <M>	Support for Host-side USB
	 [ ]		USB verbose debug messages
	 ---		Miscellaneous USB options
	 [*]		USB device filesystem
	 [*]		Enforce USB bandwidth allocation
	 [*]		Dynamic USB minor allocation
	 [ ]		USB selective suspend/resume and wakeup
	 ---		USB Host Controller Drivers
	 <*>		EHCI HCD (USB 2.0) support
	 [ ]			Full speed ISO transactions
	 [ ]			Root Hub Transaction Translators
	 < >		ISP116X HCD support
	 <M>		OHCI HCD support
	 <*>		UHCI HCD (most Intel and VIA) support
	 < >		SL811HS HCD support
	 ---		USB Device Class drivers
	 < >		USB Modem (CDC ACM) support
	 < >		USB Printer support
	 ---	NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
	 ---	may also be needed; see USB_STORAGE Help for more information
	 <*>	USB Mass Storage support
	 [ ]		USB Mass Storage verbose debug
	 [*]		Datafab Compact Flash Reader support
	 [ ]		Freecom USB/ATAPI Bridge support
	 [ ]		ISD-200 USB/ATA Bridge support
	 [ ]		Microtech/ZiO! CompactFlash/SmartMedia support
	 [ ]		USBAT/USBAT02-based storage support
	 [ ]		SanDisk SDDR-09 (and other SmartMedia) support
	 [ ]		SanDisk SDDR-55 SmartMedia support
	 [ ]		Lexar Jumpshot Compact Flash Reader
	 [*]		Olympus MAUSB-10/Fuji DPC-R1 support
	 [ ]	The shared table of common (or usual) storage devices
	 ---	USB Input Devices
	 <*>	USB Human Interface Device (full HID) support
	 [*]		HID input layer support
	 [ ]			Enable support for iBook/PowerBook special keys
	 [ ]			Force feedback support (EXPERIMENTAL)
	 [*]		/dev/hiddev raw HID device support 
 
(Y el resto según tu hardware, generalmente todo desactivado)
  

Ahora recompila y rebota la máquina para usar el nuevo kernel. Puede que tengas que compilar (o emerger) algunos módulos extra para dejar las cosas listas.

Ahora, al insertar la PCCard deberíamos ver la salida dmesg:

 
(blablabla y aquí metemos la tarjeta pcmcia)
pccard: CardBus card inserted into slot 0
yenta EnE: chaning testregister 0xC9, 00 -> 00
PCI: Enabling device 0000:03:00.0 (0000 -> 0002)
ACPI: PCI Interrupt 0000:03:00.0[A] -> Link [LNKC] -> GSI 11 (level, low) -> IRQ 11
PCI: Setting latency timer of device 0000:03:00.0 to 64
ohci_hcd 0000:03:00.0: OHCI Host Controller
drivers/usb/core/inode.c: creating file '005'
ohci_hcd 0000:03:00.0: new USB bus registered, assigned bus number 5
ohci_hcd 0000:03:00.0: created debug files
ohci_hcd 0000:03:00.0: irq 11, io mem 0xd2000000
ohci_hcd 0000:03:00.0: resetting from state 'reset', control = 0x0
ohci_hcd 0000:03:00.0: OHCI controller state
ohci_hcd 0000:03:00.0: OHCI 1.0, NO legacy support registers
ohci_hcd 0000:03:00.0: control 0x083 HCFS=operational CBSR=3
ohci_hcd 0000:03:00.0: cmdstatus 0x00000 SOC=0
ohci_hcd 0000:03:00.0: intrstatus 0x00000004 SF
ohci_hcd 0000:03:00.0: intrenable 0x8000001a MIE UE RD WDH
ohci_hcd 0000:03:00.0: hcca frame #0025
ohci_hcd 0000:03:00.0: roothub.a 0f000203 POTPGT=15 NPS NDP=3(3)
ohci_hcd 0000:03:00.0: roothub.b 00000000 PPCM=0000 DR=0000
ohci_hcd 0000:03:00.0: roothub.status 00008000 DRWE
ohci_hcd 0000:03:00.0: roothub.portstatus [0] 0x00000100 PPS
ohci_hcd 0000:03:00.0: roothub.portstatus [1] 0x00000100 PPS
ohci_hcd 0000:03:00.0: roothub.portstatus [2] 0x00000100 PPS
usb usb5: default language 0x0409
usb usb5: new device strings: Mfr=3, Product=2, SerialNumber=1
usb usb5: Product: OHCI Host Controller
usb usb5: Manufacturer: Linux 2.6.17-gentoo-r4 ohci_hcd
usb usb5: SerialNumber: 0000:03:00.0
usb usb5: uevent
usb usb5: configuration #1 chosen from 1 choice
usb usb5: adding 5-0:1.0 (config #1, interface 0)
usb 5-0:1.0: uevent
hub 5-0:1.0: usb_probe_interface
hub 5-0:1.0: usb_probe_interface - got id
hub 5-0:1.0: USB hub found
hub 5-0:1.0: 3 ports detected
hub 5-0:1.0: standalone hub
hub 5-0:1.0: no power switching (usb 1.0)
hub 5-0:1.0: global over-current protection
hub 5-0:1.0: power on to power good time: 30ms
hub 5-0:1.0: local power source is good
hub 5-0:1.0: no over-current condition exists
hub 5-0:1.0: state 7 ports 3 chg 0000 evt 0000
drivers/usb/core/inode.c: creating file '001'
PCI: Enabling device 0000:03:00.1 (0000 -> 0002)
ACPI: PCI Interrupt 0000:03:00.1[B] -> Link [LNKC] -> GSI 11 (level, low) -> IRQ 11
PCI: Setting latency timer of device 0000:03:00.1 to 64
ohci_hcd 0000:03:00.1: OHCI Host Controller
drivers/usb/core/inode.c: creating file '006'
ohci_hcd 0000:03:00.1: new USB bus registered, assigned bus number 6
ohci_hcd 0000:03:00.1: created debug files
ohci_hcd 0000:03:00.1: irq 11, io mem 0xd2001000
ohci_hcd 0000:03:00.1: resetting from state 'reset', control = 0x0
ohci_hcd 0000:03:00.1: OHCI controller state
ohci_hcd 0000:03:00.1: OHCI 1.0, NO legacy support registers
ohci_hcd 0000:03:00.1: control 0x083 HCFS=operational CBSR=3
ohci_hcd 0000:03:00.1: cmdstatus 0x00000 SOC=0
ohci_hcd 0000:03:00.1: intrstatus 0x00000004 SF
ohci_hcd 0000:03:00.1: intrenable 0x8000001a MIE UE RD WDH
ohci_hcd 0000:03:00.1: hcca frame #001e
ohci_hcd 0000:03:00.1: roothub.a 0f000202 POTPGT=15 NPS NDP=2(2)
ohci_hcd 0000:03:00.1: roothub.b 00000000 PPCM=0000 DR=0000
ohci_hcd 0000:03:00.1: roothub.status 00008000 DRWE
ohci_hcd 0000:03:00.1: roothub.portstatus [0] 0x00000100 PPS
ohci_hcd 0000:03:00.1: roothub.portstatus [1] 0x00000100 PPS
usb usb6: default language 0x0409
usb usb6: new device strings: Mfr=3, Product=2, SerialNumber=1
usb usb6: Product: OHCI Host Controller
usb usb6: Manufacturer: Linux 2.6.17-gentoo-r4 ohci_hcd
usb usb6: SerialNumber: 0000:03:00.1
usb usb6: uevent
usb usb6: configuration #1 chosen from 1 choice
usb usb6: adding 6-0:1.0 (config #1, interface 0)
usb 6-0:1.0: uevent
hub 6-0:1.0: usb_probe_interface
hub 6-0:1.0: usb_probe_interface - got id
hub 6-0:1.0: USB hub found
hub 6-0:1.0: 2 ports detected
hub 6-0:1.0: standalone hub
hub 6-0:1.0: no power switching (usb 1.0)
hub 6-0:1.0: global over-current protection
hub 6-0:1.0: power on to power good time: 30ms
hub 6-0:1.0: local power source is good
hub 6-0:1.0: no over-current condition exists
hub 6-0:1.0: state 7 ports 2 chg 0000 evt 0000
drivers/usb/core/inode.c: creating file '001'
PCI: Enabling device 0000:03:00.2 (0000 -> 0002)
ACPI: PCI Interrupt 0000:03:00.2[C] -> Link [LNKC] -> GSI 11 (level, low) -> IRQ 11
ehci_hcd 0000:03:00.2: EHCI Host Controller
drivers/usb/core/inode.c: creating file '007'
ehci_hcd 0000:03:00.2: new USB bus registered, assigned bus number 7
ehci_hcd 0000:03:00.2: reset hcs_params 0x2395 dbg=0 cc=2 pcc=3 ports=5
ehci_hcd 0000:03:00.2: reset portroute 1 0 1 0 0
ehci_hcd 0000:03:00.2: reset hcc_params e806 thresh 0 uframes 256/512/1024 park
ehci_hcd 0000:03:00.2: park 0
ehci_hcd 0000:03:00.2: MWI active
ehci_hcd 0000:03:00.2: ...powerdown ports...
ehci_hcd 0000:03:00.2: supports USB remote wakeup
ehci_hcd 0000:03:00.2: irq 11, io mem 0xd2002000
ehci_hcd 0000:03:00.2: reset command 080b02 park=3 ithresh=8 period=1024 Reset HALT
ehci_hcd 0000:03:00.2: init command 010009 (park)=0 ithresh=1 period=256 RUN
ehci_hcd 0000:03:00.2: USB 2.0 started, EHCI 1.00, driver 10 Dec 2004
usb usb7: default language 0x0409
usb usb7: new device strings: Mfr=3, Product=2, SerialNumber=1
usb usb7: Product: EHCI Host Controller
usb usb7: Manufacturer: Linux 2.6.17-gentoo-r4 ehci_hcd
usb usb7: SerialNumber: 0000:03:00.2
usb usb7: uevent
usb usb7: configuration #1 chosen from 1 choice
usb usb7: adding 7-0:1.0 (config #1, interface 0)
usb 7-0:1.0: uevent
hub 7-0:1.0: usb_probe_interface
hub 7-0:1.0: usb_probe_interface - got id
hub 7-0:1.0: USB hub found
hub 7-0:1.0: 5 ports detected
hub 7-0:1.0: standalone hub
hub 7-0:1.0: individual port power switching
hub 7-0:1.0: individual port over-current protection
hub 7-0:1.0: Single TT
hub 7-0:1.0: TT requires at most 8 FS bit times (666 ns)
hub 7-0:1.0: power on to power good time: 20ms
hub 7-0:1.0: local power source is good
hub 7-0:1.0: enabling power on all ports
ohci_hcd 0000:03:00.0: suspend root hub
hub 7-0:1.0: state 7 ports 5 chg 0000 evt 0000
drivers/usb/core/inode.c: creating file '001'
ohci_hcd 0000:03:00.1: suspend root hub

Wow!. Observa que la salida dmesg es muuucho más larga, y aparecen múltiples referencias a OHCI.

Y si ahora conectamos un MemoryBird aparece:

 
(lo de antes y ahora, además:)
hub 7-0:1.0: state 7 ports 5 chg 0000 evt 0002
ehci_hcd 0000:03:00.2: GetStatus port 1 status 001803 POWER sig=j CSC CONNECT
hub 7-0:1.0: port 1, status 0501, change 0001, 480 Mb/s
hub 7-0:1.0: debounce: port 1: total 100ms stable 100ms status 0x501
ehci_hcd 0000:03:00.2: port 1 full speed --> companion
ehci_hcd 0000:03:00.2: GetStatus port 1 status 003801 POWER OWNER sig=j CONNECT
hub 5-0:1.0: state 7 ports 3 chg 0000 evt 0000, resume root
ohci_hcd 0000:03:00.0: wakeup
hub 5-0:1.0: state 7 ports 3 chg 0000 evt 0000
ohci_hcd 0000:03:00.0: GetStatus roothub.portstatus [0] = 0x00010101 CSC PPS CCS
hub 5-0:1.0: port 1, status 0101, change 0001, 12 Mb/s
hub 5-0:1.0: debounce: port 1: total 100ms stable 100ms status 0x101
ohci_hcd 0000:03:00.0: GetStatus roothub.portstatus [0] = 0x00100103 PRSC PPS PES CCS
usb 5-1: new full speed USB device using ohci_hcd and address 2
ohci_hcd 0000:03:00.0: GetStatus roothub.portstatus [0] = 0x00100103 PRSC PPS PES CCS
usb 5-1: ep0 maxpacket = 8
usb 5-1: default language 0x0409
usb 5-1: new device strings: Mfr=1, Product=2, SerialNumber=3
usb 5-1: Product: Memorybird
usb 5-1: Manufacturer: Fujitsu
usb 5-1: SerialNumber: 171A1A0D0323
usb 5-1: uevent
usb 5-1: configuration #1 chosen from 1 choice
usb 5-1: adding 5-1:1.0 (config #1, interface 0)
usb 5-1:1.0: uevent
usb-storage 5-1:1.0: usb_probe_interface
usb-storage 5-1:1.0: usb_probe_interface - got id
scsi1 : SCSI emulation for USB Mass Storage devices
drivers/usb/core/inode.c: creating file '002'
hub 5-0:1.0: state 7 ports 3 chg 0000 evt 0002
usb-storage: device found at 2
usb-storage: waiting for device to settle before scanning
  Vendor: Fujitsu   Model: Memorybird        Rev: 1.05
  Type:   Direct-Access                      ANSI SCSI revision: 00
SCSI device sdb: 128000 512-byte hdwr sectors (66 MB)
ohci_hcd 0000:03:00.0: urb cf9700c0 path 1 ep1in 93120000 cc 9 --> status -121
sdb: Write Protect is off
sdb: Mode Sense: 43 00 00 00
sdb: assuming drive cache: write through
SCSI device sdb: 128000 512-byte hdwr sectors (66 MB)
ohci_hcd 0000:03:00.0: urb cf9700c0 path 1 ep1in 93120000 cc 9 --> status -121
sdb: Write Protect is off
sdb: Mode Sense: 43 00 00 00
sdb: assuming drive cache: write through
 sdb: sdb1
sd 1:0:0:0: Attached scsi removable disk sdb
sd 1:0:0:0: Attached scsi generic sg1 type 0
usb-storage: device scan complete

Evidentemente, lo reconoció. Si montas la unidad sdb1, verás que funciona y puedes acceder normalmente a los datos. Y por supuesto, puedes combinar lo que sabes de udev y de autofs para que todo esto se haga automáticamente, solo metiendo el MemoryBird (o lo que sea) en el puerto USB de la tarjeta Conceptronic.

Ahora deberían funcionar todos los dispositivos USB 2.0 y 1.1 en nuestra PCCard, o sea que la tarjeta funciona, tal y como dice TuxMobil. Pero algunos discos duros externos como el Lacie Mobile de 80 Gb no funcionarán porque necesitan una fuente de alimentación extra, cosa que no ocurre con el puerto USB propio del portátil. Enchufa el disco duro al USB del portátil y ya está, pero si necesitas conectarlo a la PCMCIA por narices, entonces necesitas usar un cable suplementario para alimentación eléctrica. Lo disfrutes :-).

  * *

He actualizado mi kernel, y ahora mi Pinnacle PCTV solo mete ruido.

Tienes un kernel 2.6.12, y un buen día decides actualizarlo a uno más nuevo, por ejemplo un 2.6.18, como me ocurrió a mí. Y entonces descubres que tu tarjeta capturadora de televisión, una Pinnacle PCTV que usa el módulo bttv, ha perdido el sonido, y solo se oye un horroroso ruido de estática.

Acabas de encontrar un bug en los kernels superiores a 2.6.12, que hace que el audio se vaya al carajo cuando se cargan los modulos automáticamente en el arranque o usando "modprobe bttv" y dejando que las dependencias lo resuelvan todo. Si te ocurre esto, prueba a cargar primero el módulo tuner y despues el módulo bttv.

 
[lacofi@jeanette ~]$ su
password:
[root@jeanette /home/lacofi]# rmmod bttv tuner
[root@jeanette /home/lacofi]# modprobe tuner
[root@jeanette /home/lacofi]# modprobe bttv

Si esto te funciona correctamente, puedes meter los comandos en algún fichero de autoarranque, para que siempre se carguen los módulos en el orden adecuado ya desde el boot. En el caso de Gentoo, puedes editar el fichero /etc/conf.d/local.start y poner los comandos:

 
# Fichero /etc/conf.d/local.start
rmmod bttv tuner
modprobe tuner
modprobe bttv

En mi caso, esto solucionó el problema.

  * *

Cómo encriptar una partición de disco duro con dm-crypt

A mi me surgió esta "necesidad" porque quería asegurarme de que nadie pueda leer mi disco duro externo portátil en caso de que me lo roben, pero hay muchos motivos para hacerlo. Unos ejemplos:

  1. Quieres encriptar un disco duro externo USB por si te lo roban. En ese caso, podrias encriptarlo con una contraseña que solo tú sabes, y debes teclear cada vez que lo enchufas. Es el ejemplo más sencillo.
  2. Quieres encriptar todos los datos privados que hay en tu ordenador (carpetas personales, fotos, documentos, etc): si se te estropea el ordenador, quieres estar seguro de que el servicio técnico no toqueteará en tus cosas. En ese caso podrías usar una contraseña tecleada cada vez que arrancas la máquina, pero es un poco peñazo, ¿no?. Es más práctico generar una contraseña aleatoria de, por ejemplo, 1024 bytes y meterla en un fichero en un lápiz USB, de tal forma que si el ordenador arranca con ese lápiz metido, puedes acceder a tus datos, pero si no, no.
  3. Quieres encriptar un disco duro externo USB por si te lo roban, pero manejas datos empresariales, o muy confidenciales (como datos médicos), o simplemente eres un paranoico del carajo. En ese caso puede que desconfies de una contraseña tan sencilla como para poder recordarla, y tampoco te fias de que no te roben el lápiz USB con la contraseña aleatoria. En ese caso, puedes encriptar el fichero con la clave con GNUpg, de tal forma que te pida una contraseña tecleada para poder usarlo. Parece un trabalenguas, pero en la práctica significa que para que alguien pueda leer el disco duro USB necesita tener el lápiz USB con la contraseña, y saber la frase de paso que hay que teclear (y que solo tu sabes). Tendrían que robarte, registrarte y torturarte a la vez, vamos. ;-)

Hay mucha documentación en la red para los que quieren encriptar una partición o un fichero loopback con dm-crypt. Por lo que tengo entendido, es el sistema recomendado, incluso por encima de loop-AES, que sería la alternativa más cercana. Si quieres probar con loop-AES, puedes echar un vistazo a la documentación. Yo lo he probado y te aseguro que funciona a la perfección.

Pero como parece que en los foros se recomienda más dm-crypt, al final me decidí por él.

Como está todo bien explicado en la red, lo que te pongo aquí es solo un resumen rápido de los pasos que seguí yo. Asumo que tienes Gentoo como yo, pero se puede hacer lo mismo en una Debian o un Ubuntu con muy pocas modificaciones. Si quieres más detalles o hacer algunas virguerías, échale un vistazo al HOWTO en castellano, al Tutorial resumido que usé yo, o al Gentoo Wiki más completo, que viene con un montón de detalles.

Lo primero que necesitas es un kernel adecuado. Muchas distribuciones ya incluyen el soporte a la encriptación dm-crypt de serie, como por ejemplo Fedora. Si no es así, entonces tendrás que compilar uno a medida.

Te animo a que compiles un kernel propio, incluso aunque el kernel de serie te funcione sin problemas. Un kernel propio te proporciona mucha flexibilidad a la hora de añadir cosas "finas" a tu sistema. Encriptar una partición de disco duro es un ejemplo, pero como esto hay muchas más, cosas que puedes ajustar o añadir, pero necesitas activar ciertas opciones del kernel. Modificar un kernel ya creado es muy facil, pero hacer uno nuevo desde cero puede ser un poco tortuoso, asi que piensa que tener un kernel propio es como tener mucho trabajo adelantado de cara al futuro.

Haz un "make menuconfig", entra en "Device Drivers" y luego en la opción que dice "RAID and LVM support". Activa las opciones "Multiple devices driver support (RAID and LVM)", "Device mapper support", y "Crypt target support". Ahora vuelve a la raiz y entra en "Cryptographic Options". Ahí yo lo activaría todo como módulos, pero tú tienes que activar al menos "AES cipher algorithims (i586)". Ahora vuelve a la raiz y entra en "Device Drivers" y luego en "Block Devices". Ahí, activa "Loopback device support". Vuelve al sistema y recompila.

Ojo, si quieres tener simultáneamente una unidad loop-AES, además de dm-crypt, has de saber que loop-AES te exige que desactives la opción "Loopback device support" del kernel, y que hagas un "emerge loop-aes" para compilar una versión modificada del módulo "loop" que está en Portage. Hazlo así, a dm-crypt no le importará, siempre y cuando te acuerdes de hacer un "modprobe loop" para que dm-crypt no se queje de que le falta el soporte de dispositivos loopback.

Bien, si vas a usar un fichero de contraseña, lo primero es crear el fichero, claro. Esto lo puedes hacer así, lo que crearía una contraseña fuerte de 1024 caracteres aleatorios (a que no hay narices a memorizarlos):

 
[root@jeanne ~]# head -c 1024 /dev/urandom > /mnt/usbdisk/.clave_discoduro.txt
[root@jeanne ~]# chown lacofi:users /mnt/usbdisk/.clave_discoduro.txt
[root@jeanne ~]# chmod go-rwx /mnt/usbdisk/.clave_discoduro.txt

Si quieres encriptar ese fichero con GnuPG, entonces será necesario teclear una passphrase cada vez que quieras usar el archivo de contraseña. Eso es algo así como usar una contraseña para desencriptar tu contraseña:

 
[root@jeanne ~]# head -c 3172 /dev/urandom | \
				uuencode -m - | grep -v ==== | tail -n 65 | \
				gpg --symmetric -a > /mnt/usbdisk/.clave_discoduro.txt
[root@jeanne ~]# chown lacofi:users /mnt/usbdisk/.clave_discoduro.txt
[root@jeanne ~]# chmod go-rwx /mnt/usbdisk/.clave_discoduro.txt

Y por supuesto, si no quieres complicarte la vida, puedes no especificar ningún fichero de contraseña. Te pedirá una sobre la marcha y tendrás que teclearla a mano todas las veces que montes la unidad.

Observa que me he asegurado de que el fichero que contiene la contraseña es accesible por mí y por nadie más, pero ahí puedes jugar un poco con los permisos según tus necesidades.

Ahora instala cryptsetup.

[root@jeanne ~]# emerge cryptsetup

Ahora MACHACA el contenido de la partición. ¡Cuidado, este comando que sigue destruirá permanentemente cualquier dato que esté en la partición!. ¡De eso se trata, así que no te confundas!.

[root@jeanne ~]# shred -n 1 -v /dev/lacie_backup1
shred: /dev/lacie_backup1: pass 1/1 (random)...
shred: /dev/lacie_backup1: pass 1/1 (random)...16MiB/120.0GiB 1%
shred: /dev/lacie_backup1: pass 1/1 (random)...87MiB/120.0GiB 2%
shred: /dev/lacie_backup1: pass 1/1 (random)...108MiB/120.0GiB 3%
(tómate un café, porque esto puede tardar un buen rato...)

Luego crea un dispositivo mapper (al final, lo que acabarás montando será este dispositivo mapper, y no el dispositivo real). Las instrucciones originales recomiendan también encriptar la partición swap, para que nadie pueda acceder a los datos temporales, pero como yo solo quiero proteger un disco duro portátil y ahí no habrá ninguna partición swap, puedo saltarme este paso. ¡Cuidado, este comando que sigue también destruirá permanentemente cualquier dato que esté en la partición, no te confundas de sitio!.

Si estás usando un fichero de contraseña:

 
[root@jeanne ~]# cryptsetup -v luksFormat /dev/lacie_backup1 /mnt/usbdisk/.clave_discoduro.txt

WARNING!
========
This will overwrite data on /dev/lacie_backup1 irrevocably.

Are you sure? (Type uppercase yes): <YES>
Command successful.

Si omites /mnt/usbdisk/.clave_discoduro.txt te pedirá una passphrase en la línea de comandos. En ese caso te recomiendo que uses la opción "-y", para que te la pida dos veces, y así no tendrás problemas en caso de que te equivoques al teclear.

Si prefieres encriptar el fichero de contraseña con GnuPG:

 
[root@jeanne ~]# gpg --quiet --decrypt /mnt/usbdisk/.clave_discoduro.txt | \
> cryptsetup -v luksFormat /dev/lacie_backup1
Introduce la passphrase: <aqui metes la passphrase>
gpg: ATENCIÓN: la intgridad del mensaje no está protegida
Command successful.

Observa que el dispositivo que uso es /dev/lacie_backup1 y no /dev/sdb1. Eso es porque tengo bien configurado UDEV. Te lo recomiendo sinceramente.

Ahora tienes que abrir el dispositivo mapper que acabas de crear.

Si usas un fichero de contraseña:

 
[root@jeanne ~]# cryptsetup --key-file /mnt/usbdisk/.clave_discoduro.txt \
> luksOpen /dev/lacie_backup1 encriptado
key slot 0 unlocked.
Command successful.

Si omites "--key-file /mnt/usbdisk/.clave_discoduro.txt" debería pedirte la contraseña en línea de comandos. Obviamente no serás capaz de recordarla, si la contraseña son 1024 caracteres aleatorios, pero sí si es solo una contraseña tecleada. En cualquier caso, con esto queda abierto y accesible el dispositivo mapper con nombre "encriptado".

Si usas un fichero de contraseña encriptado con GnuPG:

 
[root@jeanne ~]# gpg --decrypt /mnt/usbdisk/.clave_discoduro.txt 2>/dev/null | \
> cryptsetup luksOpen /dev/lacie_backup1 encriptado
key slot 0 unlocked.
Command successful.

Ahora ya tienes el dispositivo /dev/mapper/encriptado que es con lo que vas a trabajar. Para tí, /dev/lacie_backup1 ya no importa. Bien, pues ahora tienes que formatear el dispositivo. Algunos recomiendan no usar un sistema con journaling porque teoricamente puede producir corrupción de datos. Yo estoy usando ext3 hasta ahora sin problemas.

 
[root@jeanne ~]# mkfs.ext3 /dev/mapper/encriptado

Y ahora ya puedes crear el punto de montaje y montarlo:

 
[root@jeanne ~]# mkdir /mnt/lacie_backup
[root@jeanne ~]# mount /dev/mapper/encriptado /mnt/lacie_backup -t ext3 -o rw

El siguiente paso sería meter una entrada nueva en tu fstab:

 
/dev/mapper/encriptado  /mnt/lacie_backup  ext3  user,noauto,rw  0 0  

Con esto, la configuración ya está.

A partir de ahora, para acceder a tu partición metiendo la contraseña a mano (sin fichero de contraseñas) tendrás que ejecutar, también a mano:

 
[root@jeanne ~]# cryptsetup luksOpen /dev/lacie_backup1 encriptado
(aquí pedirá la contraseña)
[root@jeanne ~]# exit
[lacofi@jeanne ~]$ mount /mnt/lacie_backup

Aunque si estás usando un fichero de contraseña en un lápiz USB, puedes meter los comandos en los scripts de inicio del sistema, de tal forma que si está el lápiz enchufado, la máquina desencripte y monte los directorios seguros automáticamente.

Y para desmontar:

 
[lacofi@jeanne ~]$ umount /mnt/lacie_backup
[lacofi@jeanne ~]$ su
password:
[root@jeanne ~]# cryptsetup remove encriptado
(mientras no hagas esto último, la partición seguirá estando accesible sin
contraseña)

Si usas un fichero de contraseñas encriptado con GnuPG, tendrías que hacer más o menos lo mismo. Para montar:

 
[root@jeanne ~]# gpg --decrypt /mnt/usbdisk/.clave_discoduro.txt 2>/dev/null |\ 
> cryptsetup luksOpen /dev/lacie_backup1 encriptado
(aquí pedirá la passphrase)
[root@jeanne ~]# exit
[lacofi@jeanne ~]$ mount /mnt/lacie_backup

Y para desmontar, igual que antes.

Otra opción para automatizar el proceso sería por ejemplo, entrar en /etc/udev/rules.d/10-local.rules, ir a la entrada que identifica el disco duro lacie_backup1 y añadir en esa entrada una regla tal que así:

 
RUN+="cryptsetup --key-file /mnt/usbdisk/.clave_discoduro.txt luksOpen /dev/lacie_backup1 encriptado"

Con lo que cada vez que enchufes el disco duro portátil en ese ordenador, se abrirán todos los cerrojos y quedará listo para montarlo (siempre y cuando esté metido el lápiz USB con las claves):

 
[lacofi@jeanne ~]$ mount /mnt/lacie_backup

Observa que ya ni siquiera necesitamos ser root.

Que lo disfrutes.

  * *

Instalar dataplot en Gentoo

Vamos a instalar el paquete estadístico dataplot. No suele venir en las distribuciones estandard, así que tendremos que hacerlo a mano. Una pena, porque es algo lioso, pero afortunadamente es un programa bien documentado.

Lo primero es instalar ls dependencias gráficas: Tcl/Tk 8.0 o superior (se recomienda 8.3 o superior). Cualquier distribución linux más o menos moderna debería proporcionar eso de serie.

Te aconsejo que lo primero vayas a la página de Dataplot y eches un vistazo. Ahí tienes mucha documentación y muy buena.

Vete a la página con los downloads. Te interesan especialmente los binarios, así que entra en Dataplot executables, y bájate el "Linux Red Hat Fedora executable" con lo que obtendrás un fichero llamado dataplot.fedora.exe.gz. Luego entra en Dataplot auxillary files y bájatelos también, con lo que obtendrás un fichero llamado dplib.tar.gz.

Instalamos el ejecutable.

 
[lacofi@jeanne ~]$ su
password:
[root@jeanne lacofi]# mv dataplot.fedora.exe.gz /usr/local/bin/dataplot.gz
[root@jeanne bin]# cd /usr/local/bin
[root@jeanne bin]# gunzip dataplot.gz
[root@jeanne bin]# chmod 755 dataplot
[root@jeanne bin]# cd -

Ahora instalamos los ficheros auxiliares.

 
[root@jeanne lacofi]# mkdir /usr/local/lib
[root@jeanne lacofi]# mkdir /usr/local/lib/dataplot
[root@jeanne lacofi]# mv dplib.tar.gz /usr/local/lib/dataplot
[root@jeanne lacofi]# cd /usr/local/lib/dataplot
[root@jeanne dataplot]# tar -xzvf dplib.tar.gz
[root@jeanne dataplot]# rm dplib.tar.gz
[root@jeanne dataplot]# chown -R root:root *

Ahora ejecutamos un pequeño minitest que viene incluido entre los ficheros auxiliares. Este minitest ejecutará diferentes cálculos sobre el interfaz de texto. No importan los resultados, solo ver que funciona y que al final nos dice "THIS IS AN EXIT FROM DATAPLOT".

 
[root@jeanne dataplot]# exit
[lacofi@jeanne ~]$ cd ~
[lacofi@jeanne ~]$ dataplot

       ----------------------------------------------------
       |                    Dataplot                      |
       |  Interactive Graphics & Data Analysis Language   |
       |       James J. Filliben   and   Alan Heckert     |
       |    Information Technology Laboratory             |
       |   National Institute of Standards and Technology |
       |          301-975-2855  and  301-975-2899         |
       ----------------------------------------------------

          Number of Observations per Variable =  1000000
          Number of Variables                 =       10
          Total Internal Data Space Size      = 10000000
          Substitution/Replacement Character  =        ^

      1. Welcome to DATAPLOT (version 3/2006).  For assistance at
         any time during a run, enter HELP   .

      2. For a list of new commands/capabilities,
         enter NEWS  (updated 3/2006)

      3. The alternate Graphics output files (creatable
         via the DEVICE 2 and 3 commands) are
         dppl1f.tex and dppl2f.tex respectively.
      YOU HAVE JUST ACCESSED THE FILE DPMESF.
>

(y aquí metemos los siguientes comandos:)

device 1 x11 [Enter]
call minitest.dp [Enter]
exit

Ahora vamos a por el GUI. Para eso tenemos que volver a hacernos root.

 
[lacofi@jeanne ~]$ su
password
[root@jeanne lacofi]# cp /usr/local/lib/dataplot/frscript/xdataplot /usr/local/bin
[root@jeanne lacofi]# chmod a+rx /usr/local/bin/xdataplot
[root@jeanne lacofi]# whereis tcl
tcl: /usr/lib/tcl8.4 /usr/include/tcl.h
[root@jeanne lacofi]# whereis tk
tk: /usr/lib/tk8.4 /usr/include/tk.h /usr/man/mann/tk.n.bz2 /usr/share/man/mann/tk.n.bz2
[root@jeanne lacofi]# which wish
/usr/bin/wish

Obsérvese que hemos preguntado dónde está en nuestro sistema TCL, TK y Wish. Y obsérvese que he marcado en verde las respuestas válidas. Enseguida usaremos eso para modificar los scripts que arrancan el GUI.

Ahora hay que editar el fichero /usr/local/bin/xdataplot para cambiar unas cuantas cosas erróneas que está asumiendo.

 
Donde pone:
setenv TCL_LIBRARY /usr/local/lib/tcl
Debe poner:
setenv TCL_LIBRARY /usr/lib/tcl8.4

Donde pone:
setenv TK_LIBRARY /usr/local/lib/tk
Debe poner:
setenv TK_LIBRARY /usr/lib/tk8.4

Donde pone:
setenv XDP_FILE /usr/local/lib/frmenus/
Debe poner:
setenv XDP_FILE /usr/local/lib/dataplot/frmenus/

Donde pone:
setenv XDP_CODE /usr/local/lib/frscript/
Debe poner:
setenv XDP_CODE /usr/local/lib/dataplot/frscript/

Y hacemos lo mismo con el script /usr/local/lib/dataplot/frscript/xdp:

 
La primera línea debe ser:
#!/usr/bin/wish

Y con esto debería poderse arrancar ya toda la GUI usando solo el comando xdataplot. Pero eso sí, lo que queda es solo un pequeño detalle: estudiar mucha estadística. :-)


  • Sintaxis HTML 4.01 comprobada
  • Enlaces comprobados


Hecho con gvim * Hecho con CSS