2010-03-16 28 views
12

Me preguntaba si había cualquier recurso disponible en línea que explica lo que sucede con algo, como printf de C, que explica lo que está pasando en el nivel muy bajo (BIOS/llamadas al kernel)Comprender el hardware de printf

Respuesta

23

Linux:

printf() ---> printf() en la biblioteca de C ---> write() en la biblioteca de C ---> escritura () llamada al sistema en kernel.

Para comprender la interfaz entre el espacio de usuario y el espacio del núcleo, necesitará tener algún conocimiento de cómo funciona system calls.

Para comprender lo que está sucediendo en los niveles más bajos, deberá analizar el código fuente en el kernel.

El Linux system call quick reference (enlace en pdf) puede ser útil ya que identifica en qué parte de la fuente del núcleo puede comenzar a buscar.

+2

+1, Gran respuesta. –

+1

Después de tropezar con [respuesta de Hostile Fork] (http://stackoverflow.com/questions/2442966/cc-function-definitions-without-assembly/2444508#2444508) a [C/C++ definiciones de funciones sin ensamblaje] (http://stackoverflow.com/questions/2442966/cc-function-definitions-without-assembly/2444508), creo que es mejor que el mío. – jschmier

0

Un buen ejercicio para hacer, aunque será algo difícil, sería rastrear la llamada a través del kernel de Linux. Puede dL en http://www.kernel.org/

1

Esto es muy específico de la plataforma. Desde la perspectiva del hardware, la implementación de servicios de fondo de printf() podría ser dirigido a un puerto serie, un LCD no de serie, etc. Realmente estás haciendo dos preguntas:

  1. ¿Cómo funciona printf() interpretar los argumentos y la cadena de formato para generar la salida correcta?

  2. ¿Cómo se obtiene la salida de printf() en su dispositivo de destino?

Debe recordar que no es necesario un SO, kernel y BIOS para que una aplicación funcione. Las aplicaciones incorporadas suelen tener printf() y otras rutinas IO para escribir en un búfer de anillo de caracteres. Una interrupción puede sondear ese búfer y manipular el hardware de salida (LCD, puerto serie, láser show, etc.) para enviar la salida almacenada en el buffer al destino correcto.

1

Por definición, las llamadas al BIOS y al kernel son específicas de la plataforma. ¿En qué plataforma estás interesado? Varios enlaces a información relacionada con Linux ya han sido publicados.

También tenga en cuenta que printf puede que no tenga como resultado ninguna llamada al BIOS o kernel, ya que su plataforma puede no tener un kernel o BIOS (los sistemas integrados son un buen ejemplo de esto).

3

Algo como printf, o printf específicamente? Eso es algo vago.

imprime salidas en el flujo de archivos predefinidos FILE *; con lo que eso está asociado depende el sistema y además se puede redirigir a cualquier otro dispositivo de transmisión para el cual el sistema operativo proporciona un controlador de dispositivo adecuado. Trabajo en sistemas integrados, y la mayoría de las veces stdout se dirige de forma predeterminada a un UART para E/S en serie; a menudo es el único dispositivo de E/S de transmisión compatible y no se puede redireccionar. En un sistema operativo GUI para aplicaciones en modo consola, la salida se 'dibuja' gráficamente en la fuente del terminal definida por el sistema en una ventana; en Windows, por ejemplo, esto puede involucrar llamadas GDI o DirectDraw, que a su vez acceden al controlador de dispositivo del hardware de video.En un sistema operativo de escritorio moderno, la salida de caracteres de la consola no involucra al BIOS en absoluto más que tal vez el arranque inicial.

En resumen, normalmente hay una gran cantidad de software entre una llamada printf() y el hardware en el que se emite.

0

El printf() toma múltiples argumentos (función de argumentos de longitud variable). El usuario proporciona una cadena y argumentos de entrada.

La función printf() crea un búfer interno para construir cadena de salida. Ahora, printf() repite a través de cada carácter de cadena de usuario y copia el carácter a la cadena de salida. Printf() solo se detiene en "%".

"%" significa que hay un argumento para convertir (los argumentos tienen la forma de char, int, long, float, double o string). Lo convierte en una cadena y lo agrega al búfer de salida. Si el argumento es una cadena, entonces hace una copia de cadena.

Finalmente, printf() puede llegar al final del pinchazo del usuario y copia todo el búfer en el archivo stdout.