Cosas mías

May 30, 2007

Javier Lorenzo : El último soldurio

Filed under: Lecturas

Esta novela pretende ser una reivindicación de la España pre-romana y una narración de la conquista del norte por los romanos, todo ello desde el punto de vista de Linto, alias Corocotta, que narra en primera persona su historia. Primero como aliado de los romanos y que, como es hijo de un jefe hispano, rehén de César. Asiste a la conquista de las Galias mientras es instruido por un maestro romano con el que hace amistad. Después, ya liberado de su penitencia, viaja de acá a allá y se establece en el sur de España, como guardaespaldas o vigilante de un rico romano. Pero ciertos percances (la hija del romano envenena a su mujer por despecho y Linto la mata), tiene que huir de allí, volviendo de nuevo a su Cantabria natal. Conforme va pasando el tiempo va sobresaliendo y termina siendo jefe del mayor grupo homogéneo de hispanos de la época, tanto que es capaz de hacer frente a las tropas romanas, que vuelven a estar de conquista gracias al nuevo emperador, Augusto. Al final se entrega y es perdonado, pero tiene que intentar pacificar a sus congéneres. Al principio todo va bien, pero conforme va pasando el tiempo la mala gestión romana y el inconformismo español se enfrentarán en varias batallas, en una de las cuales muere nuestro personaje. El autor finaliza el libro contándonos de boca de historiadores romanos lo que siguió a la muerte de Corocotta.

Es un buen intento de reivindicación hacia los cultos del norte de España de la época, una alabanza a la fiera independencia de cántabros y vascos, a su determinación a no ser dominados por nadie. Pero lo que el autor embellece en estas páginas no es cierto del todo. Antes de la llegada de Roma, esas zonas no eran otra cosa que un hervidero de salvajes que se mataban unos a otros por un pedazo de carne o de territorio, tribus grupales apenas contenidas en los castros y que si hoy se aliaban contigo, mañana te atacaban.

Otra cosa que no me ha gustado mucho es ese didactismo un tanto trasnochado y creo que erróneo, ya que no hace falta que Linto nos comente esto o aquello sobre sus costumbres: el que esté leyendo la novela lo verá por el mismo desarrollo de la misma, aparte de que si en algunos aspectos éste sobra, en otros falta por completo y a veces si no es por las notas finales (poco hubiera costado dejarlas a pie de página) nos quedamos a dos velas, e independientemente está el hecho de que al tener que buscarlas al final se rompe la continuidad de la novela.
Por otro lado, entretenida y amena, aunque un poco larga para mi gusto.

May 21, 2007

Peter S. Beagle: Two Hearts

Filed under: Lecturas

Un grifo (mitad león mitad águila) asola una alejada zona del reino, y cada vez que han pedido ayuda al rey éste ha enviado caballeros que no han podido acabar con el bicho. Cuando desaparece la mejor amiga de una niña de unos 10 años, ésta decide ir a ver al rey en persona, por lo que se escapa y en el camino se encuentra con un mago y una bella y misteriosa mujer que la acompañan a ver al rey, que se encuentra apático y vencido por su mujer, al parecer una bruja. Pero estos sus antiguos amigos consiguen vencer los hechizos y el rey despierta y decide ir a matar al grifo, cosa que consigue con la ayuda de la mujer (que es un unicornio –recordemos que sólo un unicornio es capaz de vencer a un grifo) y del mago, pero muere en la acción.

Un cuento insulso y poco logrado, a mi parecer, carente casi de atractivo.

Parece ser que este cuento se ha llevado el Nebula como relato largo… En mi opinión, o los demás han debido de ser pésimos, o hay gato encerrado, porque el cuento no aporta nada nuevo.

May 20, 2007

Doherty, Paul: Los Verdugos de Set

Filed under: Lecturas

Estamos en el Antiguo Egipto y el juez Amerotke se enfrenta a un nuevo caso de homicidio. Han pasado 30 años desde la reconquista de Egipto sobre los hicsos, y existe una guardia de élite del faraón (más bien faraona) que en su momento ayudó en la batalla final infiltrándose en las líneas enemigas y matando a la principal hechicera. Dicha guardia ahora tiene una edad y son personas ricas y respetables.

Pero la muerte de un escriba fanfarrón y venido de nadie sabe dónde, más otros misteriosos asesinatos, intentan recrear una supuesta venganza perpetrada por el espíritu de la hechicera; el escriba es el hijo de ella, pero el asesino central es uno de los esclavos (ahora hombre libre) de uno de los guardias y que también participó en la escaramuza.

Todo viene porque la hija de otro de ellos está enamorada del esclavo, tienen un hijo pero la hacen abortar (sin saber de quién es) y ya no podrá tener más a causa del mismo. Asimismo dicha hija estuvo prometida al amo del criado, que al final decide vengarse.

Como novela policíaca no está nada mal, y casi tenemos todos los datos para conocer al culpable, sobre todo al final del libro, cuando el juez los enfrenta a todos delante del faraón.

Ejecutar un programa antes de que se inicie Windows (y II)

Filed under: Programación

En la entrada anterior hablaba sobre cómo lanzar un programa para que se ejecute antes del inicio de Windows basado en mis propias investigaciones. Tras un comentario de Peni, decidí probar un programa cualquiera… para descubrir que no funciona.

Un sesudo destripe de los dos programas que sé lo hacen, a saber, PDBoot.exe y autochk.exe comenzó a darme una ligera idea de qué es necesario. Para ello el que suscribe abrió una consola de comandos del Visual Studio, se fue a C:\Windows\System32 y ejecutó el conocido dumpbin sobre dichos programas, a saber:

dumpbin /exports <fichero>

El autochk.exe no exporta nada, pero el otro sí, en general funciones relacionadas con la desfragmentación. Luego hizo lo mismo con las importaciones, y ahí sí que obtuvo algo interesante. Lo siguiente es la importación de funciones de autochk.exe:

ntdll.dll
77F497AB 716 _wcsicmp
77F20011 76A wcsstr
77F3F354 CD NtClose
77F40014 1A1 NtQueryValueKey
77F3FC24 150 NtOpenKey
77F22F50 3B3 RtlInitUnicodeString
77F3FFA4 19A NtQuerySymbolicLinkObject
77F3FCD4 15D NtOpenSymbolicLinkObject
77F1764A 42E RtlPrefixUnicodeString
77F42EF7 33F RtlEqualUnicodeString
77F3FE04 179 NtQueryDirectoryObject
77F3FBC4 149 NtOpenDirectoryObject
77F78664 85 LdrSetMUICacheType
77F40574 20A NtTerminateProcess
77F89B82 4BC RtlUnhandledExceptionFilter
77F02B68 4D0 RtlUnwind

Y sigue así hasta algo más de cien exportaciones. Está claro que el programa está utilizando el API nativo de Windows, no el subsistema Win32 como hacen todos los programas comunes. Además, si lanzamos el programa citado nos dice que no se puede ejecutar bajo Win32.

Así que una en la frente: no se trata de un ejecutable normal y corriente, sino de algo especial. La primera pregunta es: ¿quizás sea el formato ejecutable de un driver, o sólo la obligatoriedad de no realizar llamadas a Win32?

Y aquí es donde el autor de esto decide hacer lo que debió haber hecho desde un primer momento: consultar en Google.

¿Y qué encontró? Pues esto: http://www.microsoft.com/technet/sysinternals/information/NativeApplications.mspx. Entre otras cosas, le dice que necesita el DDK de Windows, y que debe usar funciones como NtDisplayString y no printf. En fin, que como el autor ya tiene suficiente con su trabajo diario como para meterse en camisa de once varas, pues decide detenerse aquí en cuanto al tema de ejecutar programas propios antes del inicio de Windows, de modo que lo publicado hasta ahora solo sirve para lanzar un chequeo de disco, que no es poco.

También ha añadido una nueva función que ha llamado RemoveBootExecuteEntry, y a la de la entrada anterior le ha cambiado el nombre por AddBootExecuteEntry. Un ejemplo completo se puede bajar de aquí. Y eso es todo.

Addenda
Como no quiero que este comentario de Ramón Sola se pierda, lo añado aquí:

Eso se puede observar en la cabecera PE. El valor de subsistema no es 3 (interfaz de consola) ni 2 (interfaz gráfica), sino 1 (nativo, no requiere subsistema). Csrss.exe es el programa nativo responsable del subsistema Windows en modo usuario, siendo Win32k.sys la parte kernel.

Las API nativas de Windows apenas están documentadas. El propósito de esta ocultación de información, según veo yo, es el de evitar el desarrollo de programas que dependan excesivamente de la implementación interna del sistema operativo, ya que puede variar mucho de una versión del sistema operativo a otra (o incluso de un service pack a otro). Esto ha generado acusaciones más o menos fundadas contra Microsoft de no proporcionar igualdad de oportunidades; de aprovecharse del conocimiento del subsistema nativo para provecho de sus propios productos en detrimento de la competencia, que tiene que acogerse forzosamente al subsistema Win32. Si algunas empresas como Raxco o Diskeeper son capaces de desarrollar productos que se apoyan directamente en los servicios nativos, debe de ser porque Microsoft comparte la información con ellas de algún modo, mediante algún acuerdo.

Los módulos nativos en modo usuario enlazan directa o indirectamente a Ntdll.dll y no pueden o no deberían depender de bibliotecas Win32. Los módulos nativos en modo kernel son los drivers, que enlazan a Ntoskrnl.exe, Hal.dll u otros drivers (controladores de minipuerto, por ejemplo).

Por el contrario, el subsistema Win32 depende considerablemente de los servicios nativos y otras rutinas de apoyo que ofrece Ntdll.dll. No tienes más que fijarte en las tablas de importación de Kernel32, User32, Gdi32, Advapi32 y otras DLLs de Windows. Además, en las tablas de exportación de Kernel32 podrás observar incluso "forwards" (no sé cómo traducirlo), entradas que remiten a otras DLLs. Por ejemplo, la llamada a HeapAlloc desde un programa Win32 se resuelve en tiempo de carga a la rutina RtlAllocateHeap en Ntdll.dll.

Versiones de Windows NT anteriores a Windows XP incluyeron otros subsistemas aparte de Win32. Por ejemplo, Windows 2000 incluía un subsistema POSIX, y Windows NT 4 también un subsistema OS/2 que emulaba OS/2 1.x (aplicaciones en modo texto). Parece que no llegaron a ser muy populares.

Ejecutar un programa antes de que se inicie Windows

Filed under: Programación

Seguro que cualquier usuario de Windows ha visto cómo justo en medio del arranque de su PC, se modifica la pantalla de inicio de forma un tanto extraña y se inicia un chequeo del disco duro. O si utiliza herramientas como el Acronis Disk Director, tras el pertinente reinicio se lanzan en dicho lugar las herramientas, o también con los desfragmentadores comerciales como el Perfect Disk o el Diskeeper.

¿Cómo puede hacer uno eso mediante código para, por ejemplo, forzar un chequeo del disco de sistema sin intervención del usuario? Es decir, si uno intenta lanzar un chkdsk con la opción /f desde una ventana sobre el disco de sistema (aunque sea por programa), chkdsk le dirá que no puede verificar ahora, que si quiere hacerlo en el siguiente reinicio, requiriendo la intervención del usuario.

O quizás estemos haciendo una aplicación de sistemas que requiera acceso a disco antes de que el propio Windows lo bloquee…

La teoría
Justo es que si Windows puede hacerlo, nosotros también. Todo el meollo del asunto está en una clave del registro, situada en

"HKLM\SYSTEM\CurrentControlSet\Control\Session Manager"

llamada

"BootExecute"

y que suele contener un array de cadenas con el texto (en mi caso, que tengo instalado el Perfect Disk)

"PDBoot.exe","autocheck autochk *"

Una inspección a dicha clave tras haber lanzado un chequeo de disco y haber aceptado la opción de reinicio devuelve

"autocheck autochk /p \\??\\C:","PDBoot.exe","autocheck autochk *"

Podemos observar que a lo existente se le ha añadido una nueva línea, justo al principio de todo. Con esto ya tenemos claro cómo funciona todo el asunto: una línea por comando, con la observación de que los programas de aplicación pueden, también, trastear con la clave sin peligro, ya que el software del Perfect Disk así lo hace.

El algoritmo
Para evitar eliminar entradas existentes, se hace necesario en primer lugar leer el contenido de dicha clave, añadir al principio nuestra nueva línea, y después volver a escribir la clave. Opcionalmente nos queda reiniciar, cosa que explicaré cómo hacer en una próxima entrada.

El ejemplo (en C++/CLI)
Esta vez he optado por un ejemplo completo de consola de comandos. Quien quiera probarlo sólo tiene que crearse un proyecto nuevo y sustituir el texto de su fichero principal por el que pongo aquí.

// BootExecute.cpp : main project file.
#include

"stdafx.h"
using namespace System;
using namespace Microsoft::Win32;

void BootExecute(String ^nuevoValor)
{
 

//Abrimos la clave con permisos de escritura
  RegistryKey ^key=Registry::LocalMachine->OpenSubKey("SYSTEM\\CurrentControlSet\\Control\\Session Manager",true);

  //Leemos el valor

  array<String ^> ^values=(array<String ^> ^)key->GetValue("BootExecute",gcnew array<String ^> {"ERROR"});
  array<String ^> ^newValues;

  //Aquí no deberíamos entrar, pero por si acaso…
  if(values->Length==1 && values[0]=="ERROR")
    newValues=gcnew array<String ^>(1) {nuevoValor};
  else
  {
    //Creamos un nuevo array y copiamos los valores antiguos más el nuevo
    newValues=gcnew array<String ^>(values->Length+1);
    newValues[0]=nuevoValor;
    Array::Copy(values,0,newValues,1,values->Length);
  }

  //Escribimos y nos vamos
  key->SetValue("BootExecute",newValues);
  key->Close();
}

int main(array

<System::String ^> ^args)
{

  //Lo que vamos a añadir

  String ^nuevoValor="autocheck autochk /p \\??\\C:";

  BootExecute(nuevoValor);

  return 0;
}

El funcionamiento es evidente por sí mismo, aparte de los profusos comentarios que ayudan a entender el programa. Básicamente abrimos la clave del registro, leemos los valores actuales, creamos un nuevo array con el nuevo valor y copiamos el de los valores actuales. Luego escribimos y ya está hecho.

El paso siguiente es explicar cómo reiniciar el sistema operativo, forzando incluso el mismo cierre, lo que requiere hacerlo con código nativo. Todo eso lo explicaré en una próxima entrada.

May 15, 2007

Atributos y reflexión (Cosas curiosas de C#, último post)

Filed under: Programación

Atributos
Con esta largamente proyectada y nunca escrita (hasta ahora) entrada pretendo finalizar la serie de temas curiosos o novedosos (o más bien el hecho de que me hayan resultado curiosos a mí personalmente) sobre el lenguaje C#, para pasar a otras cosas. En algún lugar –hace ya bastante tiempo- dije que no me gustaban los atributos, al menos para realizar Interop con código nativo, pensando que la única finalidad de ellos era la citada, pero no es así, una parte de los atributos es el Interop, pero tiene muchas otras más, todas ellas interesantes, y como rectificar es de sabios –y no es que yo lo sea-, los atributos es una de las cosas que más me están gustando del .NET, ahora que empiezo a conocerlos en todo su esplendor.

Pero, ¿qué son los atributos? Son la forma de indicar dentro del código fuente que ciertos métodos o clases tienen un comportamiento especial definido mediante dichos atributos, amén de poder incluir toda una serie de metadatos dentro del código ejecutable para que sirva a nuestros propósitos o a los del entorno de ejecución. En pocas palabras, es mediante el uso de atributos como el .NET (y el Visual Studio) sabe la mayoría de cosas sobre el código que está ejecutando, así como su comportamiento.

Dicho esto, y tomando un ejemplo un tanto trivial, la construcción

[Serializable]
class Dato
{
    int d1,d2;
}

está indicando al compilador y al entorno de ejecución que la clase asociada es serializable, es decir, que puede ser guardada automáticamente en un flujo de datos, por lo que su implementación final dentro del código será algo diferente si no hubiera indicado dicho atributo.

Existen infinidad de atributos predefinidos que nos permiten desde hacer lo de arriba hasta indicar de qué forma se van a distribuir los datos en una estructura, pasando por indicar que una enumeración está compuesta de flags, potenciar la compilación condicional de forma que ciertos métodos se ejecuten como si estuvieran vacíos, marcar algo como obsoleto y que podría ser eliminado en siguientes versiones, utilizar código nativo y hacer llamadas a bibliotecas de terceros realizadas en otros lenguajes, y un larguísimo etcétera. La MSDN contiene una referencia completa sobre los atributos existentes si se busca la clase System.Attribute y se miran todas las clases que heredan de ella, lo que nos mete de lleno en el siguiente párrafo.

Y es que aparte de utilizar los existentes, también podemos crear nuestros propios atributos de forma sencilla, o más bien de la misma forma en que creamos nuestras propias clases: heredando de Attribute o de alguna de sus hijas. La utilidad de todo esto no es evidente a simple vista, pero lo cierto es que podría ser de mucha utilidad en la metaprogramación y en la creación de herramientas y extensiones al lenguaje. Imaginemos que estamos haciendo una herramienta para medir el código que cada programador realiza mediante la obligación de que cada programador marque su código con una propiedad que signifique su nombre y la fecha en que empezó el código. Es solo un ejemplo que no voy a detallar (más que nada porque ando algo falto de tiempo y porque es el ejemplo típico de la MSDN y de algún libro), pero su implementación mediante atributos es muy sencilla.

Claro está, si tenemos atributos personalizados debemos ser capaces de obtenerlos en tiempo de ejecución, si no de poco nos iban a servir. Y ello es completamente posible mediante el uso de typeof aplicado al elemento del que queremos obtenerlos. De nuevo en la MSDN tenemos varios ejemplos, que se entenderán mejor si antes seguimos el punto sobre la reflexión de esta entrada, ya que los citados se obtienen gracias a la misma.

Lo importante de todo esto está en que podemos cualificar y calificar nuestro propio código asociando metainformación que en determinadas situaciones podrían hacer que el código funcione de diferente forma a la deseada, o simplemente a incluir información extendida sobre lo que estamos haciendo, como tener un sistema de ayuda no sólo integrado en el código fuente, sino también disponible en tiempo de ejecución, que es la forma en la que está documentado en mayor parte el .NET y que las herramientas de desarrollo son capaces de obtener.

Reflexión
Una de las cosas que permiten los atributos, o más bien una de las cosas en las que los atributos forman parte directa e importante es la reflexión. No, no es cuestión de pensar, si no de, sin saber qué código vamos a cargar, poder ejecutarlo sin más o incluso lanzar métodos y acceder a elementos que teóricamente no están a nuestro alcance, como puede ser entrar y conocer el nivel de acceso privado de un objeto. Con la reflexión también podemos acceder a los atributos arriba citados.

Para entendernos diremos que es un paso más allá del OLE, ActiveX y COM, mucho más potente y seguro. Para un programador de C++, tanto los atributos como la reflexión son un RTTI a lo grande (realmente demasiado grande y con demasiado código oculto para que nos guste, pero eso no evita que esté ahí y que se pueda utilizar).

El primer paso consiste en obtener una referencia a un objeto de la clase Type mediante el método miembro GetType() que toda clase .NET y C# posee, incluso los tipos por valor (aquí es donde podemos ver una aplicación práctica a la dualidad clase-tipo de la que en su momento hablé y que, siendo sincero, sigue sin gustarme). También podemos utilizar la expresión typeof().

Luego podemos hacer muchas cosas con ello, desde la obtención de los atributos de un objeto como ya hemos dicho, o la ejecución de métodos que en principio no están accesibles, como el ejemplo de esta entrada mía, en la que explico cómo activar el doble buffer en un panel.

Lo cierto es que estas dos características dan al .NET Framework y a sus familiares cercanos una potencia nada desdeñable y a la que los programadores de sistemas no estamos acostumbrados.

May 3, 2007

¿Alguien recuerda qué es la línea A20?

Estábamos el otro día charlando amigablemente en el servidor de noticias de Tella y de repente surgió el tema del MS-DOS… Más bien alguien preguntó qué era el DR-DOS. Los habituales del grupo informamos que era un sistema operativo clon del MS-DOS que hizo en su momento Digital Research. También se contó la historia de por qué Windows 3.1 no era compatible con él y cómo se descubrió que todo fue una triquiñuela de Microsoft para chafar lo que en aquellos momentos era un sistema operativo mejor, más robusto, más rápido y con más opciones (por ejemplo, tenía un editor a pantalla completa, cosa que hasta el MS-DOS 5 Microsoft no se negó a incluir), y encima costaba cerca de la mitad.

Luego el que suscribe mencionó si alguien recordaba qué era la línea A20, para qué servía, cómo se usaba y qué es lo que dio origen a ella. Personalmente recordaba para qué servía, pero no la respuesta a las otras cuestiones. Pero llegó Ramón Sola, MVP, y dio una explicación magistral que considero no debe perderse en los vericuetos de un servidor de noticias, así que decidí publicarla aquí. El texto que sigue pertenece a dicho MVP, y es fiel transcripción del mismo. Simplemente para los nostálgicos.

Ahí va (firma incluída):

 

Je, resulta que es un error en el 80286 que se convirtió en "feature" después del artificio de la A20. ¿Recordáis el direccionamiento en modo real? La memoria se organiza en 65535 (2^16) segmentos de 65536 bytes cada uno que se solapan cada 16 bytes. Para obtener una dirección física a partir de una dirección de segmento y un desplazamiento, ambos de 16 bits, se realiza esta operación: dirección efectiva = (segmento * 16) + desplazamiento.

(En adelante, segmentos, desplazamientos y direcciones efectivas se expresan en hexadecimal.)

El bus de direcciones de los procesadores 8086 y 8088 sólo disponía de 20 líneas (de A19 a A0), por tanto tenían acceso únicamente a un megabyte de memoria (20 líneas => 2^20 bytes = 1.048.576 bytes = 1.024 MB = 1 MB). Si la combinación segmento:desplazamiento superaba el valor máximo de 20 bits, FFFFF, el hecho de tener un bus de tan sólo 20 líneas causaba que el procesador accediera realmente a memoria baja (este comportamiento se denominaba "wrap-around", algo así como "vuelta al principio"). Los programas debían considerar esta circunstancia y comprobar cuidadosamente los punteros que pudiesen superar la dirección efectiva FFFFF.

Ejemplo (se ve mejor con letra de ancho fijo):

FFF0:0100

FFF0 <— desplazado 4 bits a la izquierda (*16)

+ 0100

——-

1 00000

| ^^^^^ <– 20 bits (5 dígitos hexa) de dirección efectiva en 8086/88

+——– Ignorado en 8086/88

1 0 0 0 0 0 Hexadecimal

—- —- —- —- —- —-

0001 0000 0000 0000 0000 0000 Binario

—– —– —– —- —- —-

23-20 19-16 15-12 11-8 7-4 3-0 <— Bits

Obsérvese que el 1 es el bit 20 del resultado.

Más tarde llegó el 80286 con su bus de direcciones de 24 bits (de A23 a A0), con el que podía direccionar hasta 16 MB de memoria (2^24 = 2^[4+20] = 2^4 * 2^20 = 2^4 MB = 16 MB). Este procesador incorporaba otro modo de funcionamiento, el modo protegido. Salvo que algún programa solicitara este modo, el 80286 debía comportarse de la misma forma que un 8086/88, por tanto se inicializaba siempre en modo real. Sin embargo, debido a un error de diseño, el 80286 no truncaba en modo real las direcciones que sí se truncaban en los 8086/88. Por ejemplo, la combinación FFF0:0100 generaba la dirección 100000 (1 MB), no la 00000 como habría ocurrido en los 8086/88. Esto podía ocasionar problemas de compatibilidad con programas concebidos para los 8086/88.

La solución, o más bien el apaño, debía consistir en manipular la línea A20 de algún modo. Para emular el "wrap-around" de los 8086/88, hay que forzar la línea A20 a valor cero. Esto supone un problema en modo protegido: se alternarían secciones accesibles (0-1MB, 2MB-3MB…) con otras inaccesibles (1 MB-2 MB, 3 MB-4 MB…).

El control sobre la línea A20 se llevaba a cabo mediante una puerta lógica AND. Recordemos que una puerta AND da un 1 a su salida si y sólo si todas sus entradas son 1; análogamente, basta con que una entrada sea cero para que la salida también sea cero. La salida y una de las entradas de la puerta AND se conectaban a la línea A20. La otra entrada estaba comunicada con un pin libre del controlador de teclado. Al arrancar la máquina, el controlador de teclado forzaba un cero en su entrada de la puerta AND, lo que forzaba a su vez un cero en la línea A20. Teníamos un modo real idéntico al del 8086. Si un programa necesitaba entrar en modo protegido, debía habilitar la puerta AND enviando la orden correspondiente al controlador de teclado (poner un 1 en su entrada) para evitar el problema de las regiones inaccesibles descrito anteriormente.

¿Qué pasaba si se habilitaba la línea A20 en modo real? Pues que se tenía acceso a un área adicional por encima del primer megabyte, con un tamaño de 64 KB menos 16 bytes (direcciones físicas 100000 a 10FFEF). Se trata del área de memoria alta (HMA).

Por supuesto, todas estas ideas se mantienen prácticamente intactas en la actualidad aunque las implementaciones hardware hayan evolucionado. La palabra clave es *compatibilidad*.

Referencia en español:

Wikipedia - Área de memoria alta

http://es.wikipedia.org/wiki/%C3%81rea_de_memoria_alta

(Traducción de la Wikipedia en inglés.)

Más referencias, en inglés:

Real Adress Mode

http://esteve.tizos.net/archives/real-address-mode

A20 - a pain from the past

http://www.win.tue.nl/~aeb/linux/kbd/A20.html

Wikipedia - High Memory Area

http://en.wikipedia.org/wiki/High_Memory_Area

Ramón Sola (*Asterixco*) desde Málaga (España)

Lo que le pido es un poquito de barriga, señor Paciencia.

No todos repiten los chismes que oyen. Algunos los mejoran.

— Anónimo.

May 1, 2007

Henning Mankell: Cortafuegos

Filed under: Lecturas

715 páginas (mas dos de epilogo del autor) de intenso estrés y emoción, intriga y misterio. ¡Puf! Mankel no escribe nada mal, y sabe cómo mantener al lector en vilo desde el principio al final; hace tiempo que no leía nada tan intenso y tan absorbente que no fuera alguna que otra POMM de ciencia ficción.

Nos enfrentamos a una novela policíaca de corte moderno, ambientada en 1997 en Suecia, y parece ser que Mankell ha sacado a la palestra más veces a Wallander (el detective protagonista) y a su equipo de investigadores en otras obras.

Alguien aparece muerto en un cajero, un par de crías matan a un taxista a golpes. Así comienza todo. Y la trama termina descubriendo una organización de orden mundial para arrasar la sociedad actual (o al menos una parte importante de ella). La novela es bastante original, y no es del tipo "descubre tu mismo al culpable", ya que el autor nos lo va contando todo conforme ocurre, más bien es del tipo "¿cómo es posible que Wallander no se dé cuenta de esto?

Por otro lado aparece el tema informático, pero en un tono comedido y comprensible; tenemos a un crío que es un hacker y a otro hacker que no es tan crío. Y en medio la policía. Y las extrañas muertes. Y los todavía más extraños acontecimientos…

No deja de ser una mera obra de entretenimiento, pero lo que sí es cierto es que consigue hacerlo de principio a fin.

Get free blog up and running in minutes with Blogsome
Theme designed by Gary Rogers