Hola, estoy untentando hacer un programa en el que necesito acceder a ciertos sectores del disket. Para ello utilizo la función 0x02 de la interrupción 0x13 de la bios. Y por supuesto para ello hay q utilizar el ensamblador.
Lo estoy haciendo de la siguiente manera. Pero al llegar a la intrrupción me da error de segmento.
void lee(int sector,int pista)
{
__asm__ ("movb $2, %ah"); // pone ah <- 2 (FUNCION 2 DE LA BIOS)
__asm__ ("movb $1, %al"); // pone al <- 1 (Num Sectores a leer)
__asm__ ("movb $0, %dl"); // pone dl <- 0 (DISKETERA 0)
__asm__ ("movb $0, %dh"); // pone dh <- 0 (CABEZAL 0,1)
__asm__ ("movb %0, %%ch" : : "g" (pista)); // pone ch <- pista (CILINDRO 0..79)
__asm__ ("movb %0, %%cl" : : "g" (sector)); // pone cl <- sector (SECTOR 1..18)
__asm__ ("int $0x13"); // INTERRUPCION 0x13
}
No se si lo que estoy haciendo mal son los valores de los registros (que serian los parametros de entrada para la función de la interrupción de la bios) o si estoy usando mal las llamadas a ensamblador dentro del codigo de c.
Bueno si alguien ha hecho algo parecido o intuye cual puede ser la causa de mi fallo que por favor me diga algo
1 saludo
Buf, ya ni me acuerdo.
Si estás en Windows, no deja hacer nada de eso (llamar a interrupciones). Nunca he intentado hacer cosas a este nivel en Windows, pero debe ser un coñazo.
no. es en linux. creo que en windows habia una funcion de la libreria bios.h que lo hacia. biosdisk() creo.
Pero vamos lo estoy haciendo en linux y con el gcc.
Empiezo a pensar que haya que activar el uso de interrupciones mediante alguna función o algo así.
Si alguien sabe algo... :P
Debido a mi desconocimiento profundo de Linux-ASM-Bajo nivel... no te puedo asegurar nada al 100%, pero con lo que se, por logica y demas... creo que los tiros podrian ir por aqui.
Sobre MSDOS y Windows, ASM y bajo nivel si estoy puesto... en windows(a partir del NT) olvidate de llamar a esas interrupciones porque nop, te contestaran pero es como una capa de emulacion del sistema operativo por compatibilidad.. pero no afectan realmente a nada. El nucleo de los NT y superiores corre en el anillo 0 del procesador y solo los procesos que corran a ese nivel de privilegios pueden hacer llamadas reales, el resto..seran emuladas.
En MSDOS ok, todo iba de lujo y en los Windos 95,98 y 98SE. En ellos no habia proteccion ni leches jeje
Y se me ocurre que en Linux...todo sea mas parecido al modo de trabajar de un NT que un viejo y monolitico MSDOS.. por lo que, si no tienes derechos sobre ello, no estaras llamando a las interrupciones "verdaderas" y si te esta contestando alguien..es una capa de emulacion del Linux por temas de compatibilidad... o incluso mira, error de segmento porque seguramente estas intentando ejecutar esa llamada y no tienes permisos para ello.
Si no fuera asi.... seria muy inseguro, inestable y demas..imagina que cada usuario puede acceder a esos entresijos...
Pero vamos, seguro al 100% no estoy... pero usando el sentido comun tiene toda la logica del mundo que impidan, asi, a voz de pronto, utilizar las interrupciones de la bios de bajo nivel... quizas con permisos de root..o quizas aun mas...
Saludos
He desempolvado un viejo libro que tenía por ahí, y lo hace igual que tu, pero dice que para los datos hay que especificar no se qué de un segmento.....
Citar
Ya que los datos no se transfieren automáticamente en una zona de memoria fija, se ha de especificar la dirección del buffer en la pareja de registros ES:BX. Como siempre, ES acoge la dirección de segmento del buffer y BX la dirección de offset.
sí..., si va a ser eso B)
Estoooo... no, así a pelo no vas a poder hacerlo, y te explico porque:
Las llamadas a la bios suponen que el procesador está en modo real, usease, tal y como funcionaba el 8086, es decir, direccionando la memoria en cachitos de 64k's, debido a que usaba registros de direccionamiento de 16 bits. Las direcciones de memoria se formaban mediante dos registros:
1) registro base
2) registro de segmento
formando una dirección de 32 bits, que al final se quedaba en una de 24 en base a un calculillo que ahora mismo no recuerdo (hace ya muuucho tiempo de eso). Estas direcciones eran direcciones REALES, es decir, cuando tu accedias a la direccion 0x1000:0x0000, lo que recuperabas estaba realmente en esa dirección física de la memoria.
Por otra parte, tanto linux como win tienen el procesador corriendo en modo protegido, lo que quiere decir:
1) Direccionan con registros de 32 bits (con los registros extendidos)
2) Los registros de segmento realmente apuntan a un "descriptor de segmento", que indica entre otras cosas a que dirección física están mapeados, por lo que una dirección 0x01000:0, puede estar apuntando realmente a cualquier sitio en la memoria física.
Cuando tu haces un int 0x13, lo que está intentando hacer el procesador es coger una dirección de memoria física guardada en el vector de interrupción 0x13. Este vector está en la dirección 0x0: 0x26 (dirección física, que no tiene ningun sentido cuando el procesador está en modo protegido). Resultado: PUMBA!... violación de acceso a memoria, violación anal de segmento o cosas similares.
Solución... pasar por las funciones del sistema operativo.
Nota: he tenido que rebuscar muuucho en el fondo de mi memoria, por lo que alguna cosa puede no ser correcta.. sois libres de corregirme, castigarme o mandarme a tomar por segmento :P
jajaja
Pero Hgh aqui no se accede a ningún punto de la memoria solo se llama a una interrupcion de la bios, y en esta, llamamos a una función de ella, la 0x02 que es la de leer. Me da igual como este formada la memoria.
Pero bueno te veo bastante puesto así que confiaré en ti :P
Según tu, la solucion es pasar por las funciones del so. Pero cuales!??
Qué función te da la posibilidad de acceder a un sector y una pista del disket??
y no me vale la función biosdisk() de la libreria bios.h :P que estamos en las mismas
si alguien sabe algo...
y gracias a todos por contestar
Fer eres un loco, ¿en qué asignatura te han mandado hacer eso? :P
Cita de: "dj_spin0"Pero Hgh aqui no se accede a ningún punto de la memoria solo se llama a una interrupcion de la bios, y en esta, llamamos a una función de ella, la 0x02 que es la de leer. Me da igual como este formada la memoria.
Si que se accede. Ten en cuenta que la ejecutarse la instrucción "int 13h", se está intentando acceder a la dirección de memoria 0x0:0x026
Citar
Según tu, la solucion es pasar por las funciones del so. Pero cuales!??
Qué función te da la posibilidad de acceder a un sector y una pista del disket??
Ahí me pillas... te tendrá que contestar algun linux-gurú.
Curioseando se me ha ocurrido que, tal vez, usando ioctl's puedas acceder a la disquetera, pero ya te digo que no soy ni mucho menos experto en linux (de hecho soy mucho menos que eso)
jajajaja
julio cabron ni en viena te dejas de visitar estos foros!!!
espero q estes follando mucho por alli :P
esto es pa un trabajo de el de periféricos pa diciembre. solo me falta esa y la carrera es mia jejej
gracias hgh. de todas formas me da igual en linux o windors :P
[OFFTOPIC]
mirale, ke viene aqui para que le hagan las prácticas de la uni!!, jaja, serás perraco!!
la solución mas obvia es que le preguntes al profesor y punto pelota :P
tenemos una cuenta pendiente :ph34r:
[/OFFTOPIC]
aver si contesto alguna burrada y luego me linchais..... :lol:
creo que basicamente el problema es el que han comentado: la imposibilidad de acceder a la memoria directamente (como podiamos hacer desde el bendito DOS) desde Linux puesto que las direcciones de memoria fisicamente no estan accesibles :(
sino que estan "virtualizadas"
por lo que, soluciones: que pases de todo y compiles en un linux en tiempo real (
MaRTEOS-este te aseguro que programar para el es muy divertido (grrr) ), rTLinux, etc) para que puedas acceder a la memoria sin problemas
que te hagas un "driver" para Linux y asi acceder a la memoria de forma "real", mirate funciones como
ioremapte leas el libro "device driver para linux" o algo asin que esta muy bien.
pero creo que lo mejor es que te pases al DOS y jodas la disquetera o el disco duro sin problemas (genial)
Citartrabajo de el de periféricos pa diciembre
no me habia fijado, pero ya veo, lo mejor es que hagas un "driver" para poder direccionar la memoria y acceder al dispositivo directamente (outw, inw, outb, inb.....)
aqui tienes la segunda edición del libro que te decía antes:
linux device driver, 2º edicion (pero la tercera existe B) y esta muy muy actualizada)
pero te aviso, yo me le he empollado y tiene mucha tela que cortar <_<
ah, y para leer al disquete seguro que con llamadas directas a puertos con ciertos valores te vale, no creo que tengas que crearte un driver completo, mirate los capitulos 8 y 9
Aparte de lo del registro de segmento ES que te has dejado, como muy bien te han comentado, no puedes acceder en modo protegido a la BIOS (modo real) sin apaños (nunca lo he intentado pero hay programas que lo hacen).
Mi pregunta es: ¿ Porque no abres a pelo /dev/hda o /dev/fd0 con fopen()/open() y similares ? ¿ o es que necesariamente vas a jugar con formatos muy raros de sector (como protecciones anticopia saltandose sectores y tal) ?
Lo digo porque los devices de linux soportan formatos extendidos de disquete de 1.7MB y cosas asi de serie.
EDIT: Con esos archivos abres el disco como si fuera un simple fichero enorme, los primeros 512 bytes son el primer sector, los 512 siguientes el segundo, etc...
Hay formas de saltarse eso... pero entras mas bien en el mundo del "hacking"... recuerdo que en mi universidad teniamos el NT SP3 y con ayuda del SoftIce... encontre un fallito en una funcion del so que me permitia hacer un overflow y ejecutar instrucciones en el anillo 0. Estuvo muy bien porque con eso, resetee la CMOS, entre en la bios, cambie su password y puse arranque de diskete, con el ntfsdos capture el fichero sam y ale...l0pht rulez! en unos dias tenia todas las password de user y admin jeje y me sirvio para almacenar cosas sin que se borraran... pero con el SP4 ya solucionaron ese bug y pase de buscar otro....
Menuda chapa eh? moraleja: intenta hacer lo que dice senior wapo... ya que si intentas saltarte esas protecciones usando algun bug del SO puede que te funcione solo en tu maquina.. y mas en Linux...que hay mil versiones del kernel...