Andrew s. Tanenbaum



Descargar 4,35 Mb.
Ver original pdf
Página9/134
Fecha de conversión12.11.2019
Tamaño4,35 Mb.
1   ...   5   6   7   8   9   10   11   12   ...   134

criptor de archivo para usarlo en las siguientes operaciones. Si el acceso está prohibido, se devuel-

ve un código de error. 

Otro concepto importante en UNIX es el sistema de archivos montado. Casi todas las compu-

tadoras personales tienen una o más unidades ópticas en las que se pueden insertar los CD-ROMs

y los DVDs. Casi siempre tienen puertos USB, a los que se pueden conectar memorias USB (en rea-

lidad son unidades de estado sólido), y algunas computadoras tienen discos flexibles o discos du-

ros externos. Para ofrecer una manera elegante de lidiar con estos medios removibles, UNIX

permite adjuntar el sistema de archivos en un CD-ROM o DVD al árbol principal. Considere la si-

tuación de la figura 1-15(a). Antes de la llamada 

mount


(montar), el sistema de archivos raíz en el

disco duro y un segundo sistema de archivos en un CD-ROM están separados y no tienen relación

alguna. 

Sin embargo, el sistema de archivo en el CD-ROM no se puede utilizar, debido a que no hay

forma de especificar los nombres de las rutas en él. UNIX no permite colocar prefijos a los nom-

bres de rutas basados en un nombre de unidad o un número; ese sería precisamente el tipo de de-

pendencia de dispositivos que los sistemas operativos deben eliminar. En vez de ello, la llamada al

sistema 


mount

permite adjuntar el sistema de archivos en CD-ROM al sistema de archivos raíz en

donde el programa desea que esté. En la figura 1-15(b) el sistema de archivos en el CD-ROM se ha

montado en el directorio b, con lo cual se permite el acceso a los archivos /b/x /b/y. Si el directo-

rio tuviera archivos, éstos no estarían accesibles mientras el CD-ROM estuviera montado, debi-

do a que /b haría referencia al directorio raíz del CD-ROM (el hecho de no poder acceder a estos

archivos no es tan grave como parece: los sistemas de archivos casi siempre se montan en directo-

rios vacíos). Si un sistema contiene varios discos duros, todos se pueden montar en un solo árbol

también. 

42

INTRODUCCIÓN

CAPÍTULO 1


SECCIÓN 1.5

CONCEPTOS DE LOS SISTEMAS OPERATIVOS



43

Otro concepto importante en UNIX es el archivo especial. Los archivos especiales se propor-

cionan para poder hacer que los dispositivos de E/S se vean como archivos. De esta forma se pue-

de leer y escribir en ellos utilizando las mismas llamadas al sistema que se utilizan para leer y

escribir en archivos. Existen dos tipos de archivos especiales: archivos especiales de bloque ar-

chivos especiales de carácter. Los archivos especiales de bloque se utilizan para modelar disposi-

tivos que consisten en una colección de bloques direccionables al azar, tales como los discos. Al

abrir un archivo especial de bloque y leer, por decir, el bloque 4, un programa puede acceder de ma-

nera directa al cuarto bloque en el dispositivo sin importar la estructura del sistema de archivos que

contenga. De manera similar, los archivos especiales de carácter se utilizan para modelar impreso-

ras, módems y otros dispositivos que aceptan o producen como salida un flujo de caracteres. Por

convención, los archivos especiales se mantienen en el directorio /dev. Por ejemplo/dev/lp podría

ser la impresora (a la que alguna vez se le llamó impresora de línea).

La última característica que veremos en esta descripción general está relacionada con los pro-

cesos y los archivos: los canales. Un canal (pipees un tipo de pseudoarchivo que puede utilizar-

se para conectar dos procesos, como se muestra en la figura 1-16. Si los procesos y  desean

comunicarse mediante el uso de un canal, deben establecerlo por adelantado. Cuando el proceso A

desea enviar datos al proceso B, escribe en el canal como si fuera un archivo de salida. De hecho,

la implementación de un canal es muy parecida a la de un archivo. El proceso puede leer los da-

tos a través del canal, como si fuera un archivo de entrada. Por ende, la comunicación entre proce-

sos en UNIX tiene una apariencia muy similar a las operaciones comunes de lectura y escritura en

los archivos. Y por si fuera poco, la única manera en que un proceso puede descubrir que el archi-

vo de salida en el que está escribiendo no es en realidad un archivo sino un canal, es mediante una

llamada al sistema especial. Los sistemas de archivos son muy importantes. En los capítulos 4, 10

y 11 hablaremos mucho más sobre ellos.



1.5.4  Entrada/salida

Todas las computadoras tienen dispositivos físicos para adquirir entrada y producir salida. Después

de todo, ¿qué tendría de bueno una computadora si los usuarios no pudieran indicarle qué debe ha-

cer y no pudieran obtener los resultados una vez que realizara el trabajo solicitado? Existen muchos

Raíz

CD-ROM


a

b

c



d

c

d



a

b

x



y

x

y



(a)

(b)


Figura 1.15. (a) Antes de montarse, los archivos en el CD-ROM no están accesibles.

(b) Después de montarse, forman parte de la jerarquía de archivos.



tipos de dispositivos de entrada y de salida, incluyendo teclados, monitores, impresoras, etcétera.

Es responsabilidad del sistema operativo administrar estos dispositivos.

En consecuencia, cada sistema operativo tiene un subsistema de E/S para administrar sus dis-

positivos de E/S. Parte del software de E/S es independiente de los dispositivos, es decir, se aplica

a muchos o a todos los dispositivos de E/S por igual. Otras partes del software, como los drivers de

dispositivos, son específicas para ciertos dispositivos de E/S. En el capítulo 5 analizaremos el soft-

ware de E/S.

1.5.5 Protección

Las computadoras contienen grandes cantidades de información que los usuarios comúnmente de-

sean proteger y mantener de manera confidencial. Esta información puede incluir mensajes de co-

rreo electrónico, planes de negocios, declaraciones fiscales y mucho más. Es responsabilidad del

sistema operativo administrar la seguridad del sistema de manera que los archivos, por ejemplo, só-

lo sean accesibles para los usuarios autorizados.

Como un ejemplo simple, sólo para tener una idea de cómo puede funcionar la seguridad, con-

sidere el sistema operativo UNIX. Los archivos en UNIX están protegidos debido a que cada uno

recibe un código de protección binario de 9 bits. El código de protección consiste en tres campos

de 3 bits, uno para el propietario, uno para los demás miembros del grupo del propietario (el admi-

nistrador del sistema divide a los usuarios en grupos) y uno para todos los demás. Cada campo tie-

ne un bit para el acceso de lectura, un bit para el acceso de escritura y un bit para el acceso de

ejecución. Estos 3 bits se conocen como los bits rwx. Por ejemplo, el código de protección rwxr-

x--x indica que el propietario puede leer (r), escribir (w) o ejecutar (x) el archivo, otros miembros

del grupo pueden leer o ejecutar (pero no escribir) el archivo y todos los demás pueden ejecutarlo

(pero no leer ni escribir). Para un directorio, indica el permiso de búsqueda. Un guión corto indi-

ca que no se tiene el permiso correspondiente. 

Además de la protección de archivos, existen muchas otras cuestiones de seguridad. Una de

ellas es proteger el sistema de los intrusos no deseados, tanto humanos como no humanos (por

ejemplo, virus). En el capítulo 9 analizaremos varias cuestiones de seguridad.

1.5.6 El shell

El sistema operativo es el código que lleva a cabo las llamadas al sistema. Los editores, compila-

dores, ensambladores, enlazadores e intérpretes de comandos en definitiva no forman parte del sis-

tema operativo, aun cuando son importantes y útiles. Con el riesgo de confundir un poco las cosas,

en esta sección describiremos brevemente el intérprete de comandos de UNIX, conocido como

44

INTRODUCCIÓN

CAPÍTULO 1

Proceso


Canal

Proceso


A

B

Figura 1-16. Dos procesos conectados mediante un canal.



SECCIÓN 1.5

CONCEPTOS DE LOS SISTEMAS OPERATIVOS



45

shell. Aunque no forma parte del sistema operativo, utiliza con frecuencia muchas características

del mismo y, por ende, sirve como un buen ejemplo de la forma en que se pueden utilizar las lla-

madas al sistema. También es la interfaz principal entre un usuario sentado en su terminal y el sis-

tema operativo, a menos que el usuario esté usando una interfaz gráfica de usuario. Existen muchos

shells, incluyendo shcshksh bash. Todos ellos soportan la funcionalidad antes descrita, que se

deriva del shell original (sh).

Cuando cualquier usuario inicia sesión, se inicia un shell. El shell tiene la terminal como en-

trada estándar y salida estándar. Empieza por escribir el indicador de comandos (prompt), un ca-

rácter tal como un signo de dólar, que indica al usuario que el shell está esperando aceptar un

comando. Por ejemplo, si el usuario escribe

date

el shell crea un proceso hijo y ejecuta el programa date como el hijo. Mientras se ejecuta el proce-



so hijo, el shell espera a que termine. Cuando el hijo termina, el shell escribe de nuevo el indicador

y trata de leer la siguiente línea de entrada.

El usuario puede especificar que la salida estándar sea redirigida a un archivo, por ejemplo:

date >archivo

De manera similar, la entrada estándar se puede redirigir, como en:

sort archivo2

con lo cual se invoca el programa sort con la entrada que se recibe del archivo1 y la salida se envía

al archivo2.

La salida de un programa se puede utilizar como entrada para otro, si se conectan mediante un

canal. Así:

cat archivo1 archivo2 archivo3 | sort >/dev/lp

invoca al programa cat para concatenar tres archivos y enviar la salida a sort para ordenar todas las

líneas en orden alfabético. La salida de sort se redirige al archivo /dev/lp, que por lo general es la

impresora. 

Si un usuario coloca el signo & después de un comando, el shell no espera a que se complete.

En vez de ello, proporciona un indicador de comandos de inmediato. En consecuencia:

cat archivo1  archivo2  archivo3  |  sort >/dev/lp &

inicia el comando sort como un trabajo en segundo plano y permite al usuario continuar su trabajo

de manera normal mientras el ordenamiento se lleva a cabo. El shell tiene otras características 

interesantes, que no describiremos aquí por falta de espacio. La mayoría de los libros en UNIX des-

criben el shell hasta cierto grado (por ejemplo, Kernighan y Pike, 1984; Kochan y Wood, 1990; Me-

dinets, 1999; Newham y Rosenblatt, 1998; y Robbins, 1999).

Actualmente, muchas computadoras personales utilizan una GUI. De hecho, la GUI es sólo un

programa que se ejecuta encima del sistema operativo, como un shell. En los sistemas Linux, este

hecho se hace obvio debido a que el usuario tiene una selección de (por lo menos) dos GUIs: Gno-

me y KDE o ninguna (se utiliza una ventana de terminal en X11). En Windows también es posible



reemplazar el escritorio estándar de la GUI (Windows Explorer) con un programa distinto, para lo

cual se modifican ciertos valores en el registro, aunque pocas personas hacen esto.



1.5.7 La ontogenia recapitula la filogenia

Después de que se publicó el libro de Charles Darwin titulado El origen de las especies, el zoó-

logo alemán Ernst Haeckel declaró que “la ontogenia recapitula la filogenia”. Lo que quiso decir

fue que el desarrollo de un embrión (ontogenia) repite (es decir, recapitula) la evolución de las es-

pecies (filogenia). En otras palabras, después de la fertilización un óvulo humano pasa a través de

las etapas de ser un pez, un cerdo y así en lo sucesivo, hasta convertirse en un bebé humano. Los

biólogos modernos consideran esto como una simplificación burda, pero aún así tiene cierto grado

de verdad.

Algo análogo ha ocurrido en la industria de las computadoras. Cada nueva especie (mainfra-

me, minicomputadora, computadora personal, computadora de bolsillo, computadora de sistema

integrado, tarjeta inteligente, etc.) parece pasar a través del desarrollo que hicieron sus ancestros,

tanto en hardware como en software. A menudo olvidamos que la mayor parte de lo que ocurre en

el negocio de las computadoras y en muchos otros campos está controlado por la tecnología. La

razón por la que los antiguos romanos no tenían autos no es que les gustara caminar mucho; se de-

bió a que no sabían construirlos. Las computadoras personales existen no debido a que millones

de personas tienen un deseo reprimido durante siglos de poseer una computadora, sino a que 

ahora es posible fabricarlas a un costo económico. A menudo olvidamos qué tanto afecta la 

tecnología a nuestra visión de los sistemas y vale la pena reflexionar sobre este punto de vez en

cuando.

En especial, con frecuencia ocurre que un cambio en la tecnología hace que una idea se vuel-



va obsoleta y desaparece con rapidez. Sin embargo, otro cambio en la tecnología podría revivirla de

nuevo. Esto es en especial verdadero cuando el cambio tiene que ver con el rendimiento relativo 

de distintas partes del sistema. Por ejemplo, cuando las CPUs se volvieron mucho más rápidas que

las memorias, las cachés tomaron importancia para agilizar la memoria “lenta”. Si algún día la nue-

va tecnología de memoria hace que las memorias sean mucho más rápidas que las CPUs, las cachés

desaparecerán. Y si una nueva tecnología de CPUs las hace más rápidas que las memorias de nue-

vo, las cachés volverán a aparecer. En biología, la extinción es para siempre, pero en la ciencia

computacional, algunas veces sólo es durante unos cuantos años.

Como consecuencia de esta transitoriedad, en este libro analizaremos de vez en cuando con-

ceptos “obsoletos”, es decir, ideas que no son óptimas con la tecnología actual. Sin embargo, los

cambios en la tecnología pueden traer de nuevo algunos de los denominados “conceptos obsoletos”.

Por esta razón, es importante comprender por qué un concepto es obsoleto y qué cambios en el en-

torno pueden hacer que vuelva de nuevo.

Para aclarar aún más este punto consideremos un ejemplo simple. Las primeras computadoras

tenían conjuntos de instrucciones cableados de forma fija. Las instrucciones se ejecutaban directa-

mente por el hardware y no se podían modificar. Después llegó la microprogramación (primero se

introdujo en gran escala con la IBM 360), en la que un intérprete subyacente ejecutaba las “instruc-

ciones de hardware” en el software. La ejecución de instrucciones fijas se volvió obsoleta. Pero es-

to no era lo bastante flexible. Después se inventaron las computadoras RISC y la microprogramación

46

INTRODUCCIÓN

CAPÍTULO 1


SECCIÓN 1.5

CONCEPTOS DE LOS SISTEMAS OPERATIVOS



47

(es decir, la ejecución interpretada) se volvió obsoleta, debido a que la ejecución directa era más ve-

loz. Ahora estamos viendo el resurgimiento de la interpretación en forma de applets de Java que se

envían a través de Internet y se interpretan al momento de su llegada. La velocidad de ejecución no

siempre es crucial, debido a que los retrasos en la red son tan grandes que tienden a dominar. Por en-

de, el péndulo ha oscilado varias veces entre la ejecución directa y la interpretación y puede volver

a oscilar de nuevo en el futuro.

Memorias extensas

Ahora vamos a examinar algunos desarrollos históricos en el hardware y la forma en que han afec-

tado al software repetidas veces. Las primeras mainframes tenían memoria limitada. Una IBM

7090 o 7094 completamente equipada, que fungió como rey de la montaña desde finales de 1959

hasta 1964, tenía cerca de 128 KB de memoria. En su mayor parte se programaba en lenguaje en-

samblador y su sistema operativo estaba escrito en lenguaje ensamblador también para ahorrar la

valiosa memoria.

A medida que pasaba el tiempo, los compiladores para lenguajes como FORTRAN y CO-

BOL se hicieron lo bastante buenos como para que el lenguaje ensamblador se hiciera obsoleto.

Pero cuando se liberó al mercado la primera minicomputadora comercial (PDP-1), sólo tenía

4096 palabras de 18 bits de memoria y el lenguaje ensamblador tuvo un regreso sorpresivo. Con

el tiempo, las microcomputadoras adquirieron más memoria y los lenguajes de alto nivel preva-

lecieron. 

Cuando las microcomputadoras llegaron a principios de 1980, las primeras tenían memorias 

de 4 KB y la programación en lenguaje ensamblador surgió de entre los muertos. A menudo, las

computadoras embebidas utilizaban los mismos chips de CPU que las microcomputadoras (8080,

Z80 y posteriormente 8086) y también se programaban en ensamblador al principio. Ahora sus des-

cendientes, las computadoras personales, tienen mucha memoria y se programan en C, C

 y Ja-

va, además de otros lenguajes de alto nivel. Las tarjetas inteligentes están pasando por un desarrollo

similar, aunque más allá de un cierto tamaño, a menudo tienen un intérprete de Java y ejecutan los

programas de Java en forma interpretativa, en vez de que se compile Java al lenguaje máquina de

la tarjeta inteligente.

Hardware de protección

Las primeras mainframes (como la IBM 7090/7094) no tenían hardware de protección, por lo que

sólo ejecutaban un programa a la vez. Un programa con muchos errores podía acabar con el siste-

ma operativo y hacer que la máquina fallara con facilidad. Con la introducción de la IBM 360, se

hizo disponible una forma primitiva de protección de hardware y estas máquinas podían de esta for-

ma contener varios programas en memoria al mismo tiempo, y  dejarlos que tomaran turnos para

ejecutarse (multiprogramación). La monoprogramación se declaró obsoleta.

Por lo menos hasta que apareció la primera minicomputadora (sin hardware de protección) la

multiprogramación no fue posible. Aunque la PDP-1 y la PDP-8 no tenían hardware de protección,

en cierto momento se agregó a la PDP-11 dando entrada a la multiprogramación y con el tiempo a

UNIX.


Cuando se construyeron las primeras microcomputadoras, utilizaban el chip de CPU 8080 de

Intel, que no tenía protección de hardware, por lo que regresamos de vuelta a la monoprograma-

ción. No fue sino hasta el Intel 80286 que se agregó hardware de protección y se hizo posible la

multiprogramación. Hasta la fecha, muchos sistemas integrados no tienen hardware de protección

y ejecutan un solo programa.

Ahora veamos los sistemas operativos. Al principio, las primeras mainframes no tenían hard-

ware de protección ni soporte para la multiprogramación, por lo que ejecutaban sistemas operativos

simples que se encargaban de un programa cargado en forma manual a la vez. Más adelante adqui-

rieron el soporte de hardware y del sistema operativo para manejar varios programas a la vez, des-

pués capacidades completas de tiempo compartido.

Cuando aparecieron las minicomputadoras por primera vez, tampoco tenían hardware de pro-

tección y ejecutaban un programa cargado en forma manual a la vez, aun cuando la multiprograma-

ción estaba bien establecida en el mundo de las mainframes para ese entonces. Gradualmente

adquirieron hardware de protección y la habilidad de ejecutar dos o más programas a la vez. Las

primeras microcomputadoras también fueron capaces de ejecutar sólo un programa a la vez, pero

más adelante adquirieron la habilidad de la multiprogramación. Las computadoras de bolsillo y las

tarjetas inteligentes se fueron por la misma ruta.

En todos los casos, el desarrollo de software se rigió en base a la tecnología. Por ejemplo, las

primeras microcomputadoras tenían cerca de 4 KB de memoria y no tenían hardware de protección.

Los lenguajes de alto nivel y la multiprogramación eran demasiado para que un sistema tan peque-

ño pudiera hacerse cargo. A medida que las microcomputadoras evolucionaron en las computado-

ras personales modernas, adquirieron el hardware necesario y después el software necesario para

manejar características más avanzadas. Es probable que este desarrollo continúe por varios años

más. Otros campos también pueden tener esta rueda de reencarnaciones, pero en la industria de las

computadoras parece girar con más velocidad.

Discos

Las primeras mainframes estaban en su mayor parte basadas en cinta magnética. Leían un progra-

ma de la cinta, lo compilaban, lo ejecutaban y escribían los resultados de vuelta en otra cinta. No

había discos ni un concepto sobre el sistema de archivos. Eso empezó a cambiar cuando IBM intro-

dujo el primer disco duro: el RAMAC (RAndoM Access, Acceso aleatorio) en 1956. Ocupaba cer-

ca de 4 metros cuadrados de espacio de piso y podía almacenar 5 millones de caracteres de 7 bits,

lo suficiente como para una fotografía digital de mediana resolución. Pero con una renta anual de

35,000 dólares, ensamblar suficientes discos como para poder almacenar el equivalente de un rollo

de película era en extremo costoso. Con el tiempo los precios disminuyeron y se desarrollaron los

sistemas de archivos primitivos.

Uno de los nuevos desarrollos típicos de esa época fue la CDC 6600, introducida en 1964 y

considerada durante años como la computadora más rápida del mundo. Los usuarios podían crear

“archivos permanentes” al darles un nombre y esperar que ningún otro usuario hubiera decidido

también que, por decir, “datos” fuera un nombre adecuado para un archivo. Éste era un directorio

de un solo nivel. Con el tiempo las mainframes desarrollaron sistemas de archivos jerárquicos com-

plejos, lo cual probablemente culminó con el sistema de archivos MULTICS.



48

INTRODUCCIÓN

CAPÍTULO 1


SECCIÓN 1.6

LLAMADAS AL SISTEMA



49

Cuando las minicomputadoras empezaron a usarse, con el tiempo también tuvieron discos du-

ros. El disco estándar en la PDP-11 cuando se introdujo en 1970 era el disco RK05, con una capaci-

dad de 2.5 MB, aproximadamente la mitad del RAMAC de IBM, pero sólo tenía cerca de 40 cm de

diámetro y 5 cm de altura. Pero también tenía al principio un directorio de un solo nivel. Cuando lle-

garon las microcomputadoras, CP/M fue al principio el sistema operativo dominante y también so-

portaba un solo directorio en el disco (flexible).

Memoria virtual

La memoria virtual (que se describe en el capítulo 3) proporciona la habilidad de ejecutar progra-

mas más extensos que la memoria física de la computadora, llevando y trayendo pedazos entre la

RAM y el disco. Pasó por un desarrollo similar, ya que apareció primero en las mainframes, des-

pués avanzó a las minis y a las micros. La memoria virtual también permitió la capacidad de ligar

dinámicamente un programa a una biblioteca en tiempo de ejecución, en vez de compilarlo. MUL-

TICS fue el primer sistema operativo en tener esta capacidad. Con el tiempo, la idea se propagó des-

cendiendo por toda la línea y ahora se utiliza ampliamente en la mayoría de los sistemas UNIX y

Windows.

En todos estos desarrollos vemos ideas que se inventaron en un contexto y más adelante se des-

cartaron cuando cambió el contexto (la programación en lenguaje ensamblador, la monoprograma-

ción, los directorios de un solo nivel, etc.) sólo para reaparecer en un contexto distinto, a menudo

una década más tarde. Por esta razón, en este libro algunas veces vemos ideas y algoritmos que pue-

den parecer atrasados en comparación con las PC de hoy en día con capacidades de gigabytes, pe-

ro que pronto pueden volver en las computadoras incrustadas y las tarjetas inteligentes.

1.6 LLAMADAS AL SISTEMA

Hemos visto que los sistemas operativos tienen dos funciones principales: proveer abstracciones a

los programas de usuario y administrar los recursos de la computadora. En su mayor parte, la inte-

racción entre los programas de usuario y el sistema operativo se relaciona con la primera función:

por ejemplo, crear, escribir, leer y eliminar archivos. La parte de la administración de los recursos

es en gran parte transparente para los usuarios y se realiza de manera automática. Por ende, la in-

terfaz entre los programas de usuario y el sistema operativo trata principalmente acerca de cómo li-

diar con las abstracciones. Para comprender realmente qué hacen los sistemas operativos, debemos

examinar esta interfaz con detalle. Las llamadas al sistema disponibles en la interfaz varían de un

sistema operativo a otro (aunque los conceptos subyacentes tienden a ser similares).

Por lo tanto, nos vemos obligados a elegir una opción entre 1) generalidades imprecisas (“los

sistemas operativos tienen llamadas al sistema para leer archivos”) y 2) cierto sistema específico

(“UNIX tiene una llamada al sistema conocida como 

read


con tres parámetros: uno para especifi-

car el archivo, uno para decir en dónde se van a colocar los datos y uno para indicar cuantos bytes

se deben leer”).

Hemos optado por la última opción; implica más trabajo, pero proporciona una visión más de-

tallada en cuanto a lo que realmente hacen los sistemas operativos. Aunque este análisis se refiere


en forma específica a POSIX (Estándar internacional 9945-1) y por ende también a UNIX, System

V, BSD, Linux, MINIX 3, etc., la mayoría de los demás sistemas operativos modernos tienen llama-

das al sistema que realizan las mismas funciones, incluso si difieren los detalles. Como la verdadera

mecánica relacionada con la acción de emitir una llamada al sistema es altamente dependiente de 

la máquina y a menudo debe expresarse en código ensamblador, se proporciona una biblioteca 

de procedimientos para hacer que sea posible realizar llamadas al sistema desde programas en C y

por lo general desde otros lenguajes también.

Es conveniente tener en cuenta lo siguiente. Cualquier computadora con una sola CPU puede

ejecutar sólo una instrucción a la vez. Si un proceso está ejecutando un programa de usuario en mo-

do usuario y necesita un servicio del sistema, como leer datos de un archivo, tiene que ejecutar una

instrucción de trap para transferir el control al sistema operativo. Después, el sistema operativo ave-

rigua qué es lo que quiere el proceso llamador, para lo cual inspecciona los parámetros. Luego lle-

va a cabo la llamada al sistema y devuelve el control a la instrucción que va después de la llamada

al sistema. En cierto sentido, realizar una llamada al sistema es como realizar un tipo especial de

llamada a un procedimiento, sólo que las llamadas al sistema entran al kernel y las llamadas a pro-

cedimientos no.

Para hacer más entendible el mecanismo de llamadas al sistema, vamos a dar un vistazo rápi-

do a la llamada al sistema 

read

. Como dijimos antes, tiene tres parámetros: el primero especifica el



archivo, el segundo apunta al búfer y el tercero proporciona el número de bytes a leer. Al igual que

casi todas las llamadas al sistema, se invoca desde programas en C mediante una llamada a un pro-

cedimiento de la biblioteca con el mismo nombre que la llamada al sistema: read. Una llamada des-

de un programa en C podría tener la siguiente apariencia:

cuenta=read(fd, bufer, nbytes);

La llamada al sistema (y el procedimiento de biblioteca) devuelve el número de bytes que se leen

en  cuenta. Por lo general este valor es el mismo que nbytes pero puede ser más pequeño si, por

ejemplo, se encuentra el fin de archivo al estar leyendo.

Si la llamada al sistema no se puede llevar a cabo, ya sea debido a un parámetro inválido o a

un error del disco, cuenta se establece a 

1 y el número de error se coloca en una variable global

llamada errno. Los programas siempre deben comprobar los resultados de una llamada al sistema

para ver si ocurrió un error.

Las llamadas al sistema se llevan a cabo en una serie de pasos. Para que este concepto quede

más claro, vamos a examinar la llamada 

read


antes descrita. En su preparación para llamar al proce-

dimiento de biblioteca read, que es quien realmente hace la llamada al sistema 

read

, el programa lla-



mador primero mete los parámetros en la pila, como se muestra en los pasos 1 a 3 de la figura 1-17.

Los compiladores de C y C

 meten los parámetros en la pila en orden inverso por razones

históricas (esto tiene que ver con hacer que el primer parámetro para printf, la cadena del formato,

aparezca en la parte superior de la pila). Los parámetros primero y tercero se pasan por valor, pero

el segundo parámetro se pasa por referencia, lo cual significa que se pasa la dirección del búfer (lo

cual se indica mediante &), no el contenido del mismo. Después viene la llamada al procedimien-

to de biblioteca (paso 4). Esta instrucción es la instrucción de llamada a procedimiento normal uti-

lizada para llamar a todos los procedimientos.

50

INTRODUCCIÓN

CAPÍTULO 1


SECCIÓN 1.6

LLAMADAS AL SISTEMA



51

El procedimiento de biblioteca (probablemente escrito en lenguaje ensamblador) coloca por lo

general el número de la llamada al sistema en un lugar en el que el sistema operativo lo espera, como

en un registro (paso 5). Después ejecuta una instrucción 

TRAP

para cambiar del modo usuario al 



modo kernel y empezar la ejecución en una dirección fija dentro del núcleo (paso 6). La instrucción

TRAP


en realidad es muy similar a la instrucción de llamada a procedimiento en el sentido en que la

instrucción que le sigue se toma de una ubicación distante y la dirección de retorno se guarda en 

la pila para un uso posterior.

Sin embargo, la instrucción 

TRAP

también difiere de la instrucción de llamada a un procedi-



miento en dos formas básicas. En primer lugar, como efecto secundario, cambia a modo kernel. La

instrucción de llamada al procedimiento no cambia el modo. En segundo lugar, en vez de dar una

dirección relativa o absoluta en donde se encuentra el procedimiento, la instrucción 

TRAP


no puede

saltar a una dirección arbitraria. Dependiendo de la arquitectura, salta a una ubicación fija, hay un

campo de 8 bits en la instrucción que proporciona el índice a una tabla en memoria que contiene di-

recciones de salto, o su equivalente.

El código de kernel que empieza después de la instrucción 

TRAP


examina el número de llama-

da al sistema y después la pasa al manejador correspondiente de llamadas al sistema, por lo gene-

ral a través de una tabla de apuntadores a manejadores de llamadas al sistema, indexados en base al

Regresa al procedimiento 

llamador

4

10



6

0

9



7

8

3



2

1

11



Despa-

chador


Manejador

de llamadas

al sistema

Dirección

0xFFFFFFFF

Espacio de usuario

Espacio de kernel

(sistema operativo)

Procedimiento 

de biblioteca

read

Programa  



de usuario 

llamando  

a read

Trap al kernel



Coloca el código para 

lectura en el registro

Incrementa SP

Llama a read

Mete fd en la pila

Mete &bufer en la pila

Mete nbytes en la i\pila

5

Figura 1-17. Los 11 pasos para realizar la llamada al sistema 

read

(

fd

,



bufer

,

nbytes



).

número de llamada al sistema (paso 7). En ese momento se ejecuta el manejador de llamadas al

sistema (paso 8). Una vez que el manejador ha terminado su trabajo, el control se puede regresar

al procedimiento de biblioteca que está en espacio de usuario, en la instrucción que va después de

la instrucción 

TRAP

(paso 9). Luego este procedimiento regresa al programa de usuario en la forma



usual en que regresan las llamadas a procedimientos (paso 10).

Para terminar el trabajo, el programa de usuario tiene que limpiar la pila, como lo hace después

de cualquier llamada a un procedimiento (paso 11). Suponiendo que la pila crece hacia abajo, co-

mo es comúnmente el caso, el código compilado incrementa el apuntador de la pila lo suficiente 

como para eliminar los parámetros que se metieron antes de la llamada a read. Ahora el programa

es libre de hacer lo que quiera a continuación.

En el paso 9 anterior, dijimos que “se puede regresar al procedimiento de biblioteca que está

en espacio de usuario …” por una buena razón. La llamada al sistema puede bloquear al procedi-

miento llamador, evitando que continúe. Por ejemplo, si trata de leer del teclado y no se ha escrito

nada aún, el procedimiento llamador tiene que ser bloqueado. En este caso, el sistema operativo

buscará a su alrededor para ver si se puede ejecutar algún otro proceso a continuación. Más adelan-

te, cuando esté disponible la entrada deseada, este proceso recibirá la atención del sistema y se lle-

varán a cabo los pasos 9 a 11. 

En las siguientes secciones examinaremos algunas de las llamadas al sistema POSIX de uso

más frecuente, o dicho en forma más específica, los procedimientos de biblioteca que realizan esas

llamadas al sistema. POSIX tiene aproximadamente 100 llamadas a procedimientos. Algunas de

las más importantes se listan en la figura 1-18, agrupadas por conveniencia en cuatro categorías.

En el texto examinaremos brevemente cada llamada para ver cuál es su función.

En mayor grado, los servicios ofrecidos por estas llamadas determinan la mayor parte de la la-

bor del sistema operativo, ya que la administración de recursos en las computadoras personales es

una actividad mínima (por lo menos si se le compara con los equipos grandes que tienen muchos

usuarios). Los servicios incluyen acciones tales como crear y terminar procesos, crear, eliminar, leer

y escribir en archivos, administrar directorios y realizar operaciones de entrada y salida.

Al margen, vale la pena mencionar que la asignación de las llamadas a procedimientos POSIX

a llamadas al sistema no es de uno a uno. El estándar POSIX especifica varios procedimientos que

debe suministrar un sistema que se conforme a este estándar, pero no especifica si deben ser llama-

das al sistema, llamadas a una biblioteca, o algo más. Si un procedimiento puede llevarse a cabo sin

necesidad de invocar una llamada al sistema (es decir, sin atrapar en el kernel), por lo general se

realizará en espacio de usuario por cuestión de rendimiento. Sin embargo, la mayoría de los proce-

dimientos POSIX invocan llamadas al sistema, en donde por lo general un procedimiento se asig-

na directamente a una llamada al sistema. En unos cuantos casos, en especial en donde los

procedimientos requeridos son sólo pequeñas variaciones de algún otro procedimiento, una llama-

da al sistema maneja más de una llamada a la biblioteca.

1.6.1 Llamadas al sistema para la administración de procesos

El primer grupo de llamadas en la figura 1-18 se encarga de la administración de los procesos. 

fork

es un buen lugar para empezar este análisis. 



fork

es la única manera de crear un nuevo proceso en

POSIX. Crea un duplicado exacto del proceso original, incluyendo todos los descriptores de archivos,

52

INTRODUCCIÓN

CAPÍTULO 1


SECCIÓN 1.6

LLAMADAS AL SISTEMA



53

Administración de procesos

Descripción

Llamada

a

e



r

Crea un proceso hijo, idéntico al padre

Abre un archivo para lectura, escritura o ambas

Crea un nuevo directorio

Elimina un directorio vacío

Crea una nueva entrada llamada nombre2, que apunta 

a nombre1

Elimina una entrada de directorio

Monta un sistema de archivos

Desmonta un sistema de archivos

Cambia el directorio de trabajo

Cambia los bits de protección de un archivo

Envía una señal a un proceso

Obtiene el tiempo transcurrido desde Ene 1, 1970

Cierra un archivo abierto

Lee datos de un archivo y los coloca en un búfer

Escribe datos de un búfer a un archivo

Desplaza el apuntador del archivo

Obtiene la información de estado de un archivo

Espera a que un hijo termine

Termina la ejecución de un proceso y devuelve el estado

Reemplaza la imagen del núcleo de un proceso

pid = fork()

pid = waitpid(pid, &statloc, opciones)          

s = execve(nombre, argv, entornp)

exit(estado)



Administración de archivos

Descripción

Llamada

fd = open(archivo, como, …)

s = close(fd)

n = read(fd, bufer, nbytes)

n = write(fd, bufer, nbytes)

posicion = lseek(fd, desplazamiento, dedonde)

s = stat(nombre, &buf)

Administración del sistema de directorios y archivos

Descripción

Llamada 

s = mkdir(nombre, modo)

s = rmdir(nombre)

s = link(nombre1, nombre2)

s = unlink(nombre)

s = mount(especial, nombre, bandera)

s = umount(especial)

Llamadas varias

Descripción

Llamada

s = chdir(nombredir)

s = chmod(nombre, modo)

s = kill(pid, senial)

segundos = tiempo(&segundos)

Figura 1-18. Algunas de las principales llamadas al sistema POSIX. El código de re-

torno es 

1 si ocurrió un error. Los códigos de retorno son: pid es un id de proceso,

fd es un descriptor de archivo, es una cuenta de bytes, posicion es un desplazamien-

to dentro del archivo y segundos es el tiempo transcurrido. Los parámetros se explican

en el texto.


registros y todo lo demás. Después de 

fork


, el proceso original y la copia (el padre y el hijo) se van

por caminos separados. Todas las variables tienen valores idénticos al momento de la llamada a

fork, pero como los datos del padre se copian para crear al hijo, los posteriores cambios 

en uno de ellos no afectarán al otro (el texto del programa, que no se puede modificar, se compar-

te entre el padre y el hijo). La llamada a 

fork


devuelve un valor, que es cero en el hijo e igual al

identificador del proceso (

PID

) hijo en el padre. Mediante el uso del PID devuelto, los dos procesos



pueden ver cuál es el proceso padre y cuál es el proceso hijo.

En la mayoría de los casos, después de una llamada a 

fork

el hijo tendrá que ejecutar código



distinto al del padre. Considere el caso del shell: lee un comando de la terminal, llama a fork para

crear un proceso hijo, espera a que el hijo ejecute el comando y después lee el siguiente comando

cuando el hijo termina. Para esperar a que el hijo termine, el padre ejecuta una llamada al sistema

waitpid


, la cual sólo espera hasta que el hijo termine (cualquier hijo, si existe más de uno). 

Wait-


pid

puede esperar a un hijo específico o a cualquier hijo anterior si establece el primer parámetro a

1. Cuando 

waitpid


se completa, la dirección a la que apunta el segundo parámetro (statloc) se es-

tablece al estado de salida del hijo (terminación normal o anormal, con el valor de 

exit

). También



se proporcionan varias opciones, especificadas por el tercer parámetro.

Ahora considere la forma en que el shell utiliza a 

fork

. Cuando se escribe un comando, el shell



crea un nuevo proceso usando 

fork


. Este proceso hijo debe ejecutar el comando de usuario. Para

ello utiliza la llamada al sistema 

execve

, la cual hace que toda su imagen de núcleo completa se sus-



tituya por el archivo nombrado en su primer parámetro. (En realidad, la llamada al sistema en sí es

exec


, pero varios procedimientos de biblioteca lo llaman con distintos parámetros y nombres lige-

ramente diferentes. Aquí trataremos a estas llamadas como si fueran llamadas al sistema.) En la fi-

gura 1-19 se muestra un shell muy simplificado que ilustra el uso de 

fork


,

waitpid


y

execve


.

#define TRUE 1

while (TRUE) {

/* se repite en forma indefinida */

type_prompt();

/* muestra el indicador de comando en la pantalla */

read_command(command, parameters);

/* lee la entrada de la terminal */

if (fork() !=0) {

/* usa fork para el proceso hijo */

/* Codigo del padre. */

waitpid(-1, &status, 0);

/* espera a que el hijo termine */

} else {


/* Codigo del hijo. */

execve(command, parameters, 0);

/* ejecuta el comando */

}

}



Figura 1-19.  Una versión simplificada del shell. En este libro supondremos que TRUE

se defi


ne como 1.

En el caso más general, 

execve

tiene tres parámetros: el nombre del archivo que se va a ejecu-



tar, un apuntador al arreglo de argumentos y un apuntador al arreglo del entorno. En breve descri-

biremos estos parámetros. Se proporcionan varias rutinas de biblioteca incluyendo a execlexecv,



54

INTRODUCCIÓN

CAPÍTULO 1


SECCIÓN 1.6

LLAMADAS AL SISTEMA



55

execle execve, para permitir la omisión de los parámetros o para especificarlos de varias formas.

En este libro utilizaremos el nombre 

exec

para representar la llamada al sistema que se invoca me-



diante cada una de estas rutinas.

Consideremos el caso de un comando tal como

cp archivo1 archivo2

que se utiliza para copiar archivo1 archivo2. Una vez que el shell se ha bifurcado mediante 

fork

,

el proceso hijo localiza y ejecuta el archivo cp y le pasa los nombres de los archivos de origen y



destino.

El programa principal de cp (y el programa principal de la mayoría de los otros programas en

C) contienen la siguiente declaración:

main(argc, argv, envp)

en donde argc es una cuenta del número de elementos en la línea de comandos, incluyendo el nom-

bre del programa. Para el ejemplo anterior, argc es 3.

El segundo parámetro, argv, es un apuntador a un arreglo. El elemento de ese arreglo es un

apuntador a la i-ésima cadena en la línea de comandos. En nuestro ejemplo, argv[0] apuntaría a la

cadena “cp”, argv[1] apuntaría a la cadena “archivo1” y argv[2] apuntaría a la cadena “archivo2”.

El tercer parámetro de mainenvp, es un apuntador al entorno, un arreglo de cadenas que con-

tiene asignaciones de la forma nombre valor que se utilizan para pasar información, tal como el

tipo de terminal y el nombre del directorio de inicio, a los programas. Hay procedimientos de bi-

blioteca que los programas pueden llamar para obtener las variables de entorno, que a menudo se

utilizan para personalizar la forma en que un usuario desea realizar ciertas tareas (por ejemplo, la

impresora predeterminada que desea utilizar). En la figura 1-19 no se pasa un entorno al hijo, por

lo que el tercer parámetro de execve es un cero.

Si 

exec


parece complicado, no se desanime; es (en sentido semántico) la más compleja de to-

das las llamadas al sistema POSIX. Todas las demás son mucho más simples. Como ejemplo de una

llamada simple considere a 

exit


, que los procesos deben utilizar cuando terminan su ejecución. Tie-

ne un parámetro, el estado de 

exit

(0 a 255), que se devuelve al padre mediante statloc en la lla-



mada al sistema 

waitpid


.

En UNIX los procesos tienen su memoria dividida en tres segmentos: el segmento de texto (es

decir, el código del programa), el segmento de datos (es decir, las variables) y el segmento de pila.

El segmento de datos crece hacia arriba y la pila crece hacia abajo, como se muestra en la figura 

1-20. Entre ellos hay un espacio libre de direcciones sin utilizar. La pila crece hacia ese espacio de

manera automática, según sea necesario, pero la expansión del segmento de datos se realiza de ma-

nera explícita mediante una llamada al sistema (

brk


), la cual especifica la nueva dirección en donde

debe terminar el segmento de datos. Sin embargo, esta llamada no está definida en el estándar de PO-

SIX, ya que se recomienda a los programadores utilizar el procedimiento de biblioteca malloc para

asignar espacio de almacenamiento en forma dinámica y la implementación subyacente de malloc no

se consideró como un tema adecuado para su estandarización, ya que pocos programadores lo utili-

zan directamente y es improbable que alguien se dé cuenta siquiera que brk no está en POSIX.



1.6.2 Llamadas al sistema para la 

administración de archivos

Muchas llamadas al sistema se relacionan con el sistema de archivos. En esta sección analizaremos

las llamadas que operan con archivos individuales; en la siguiente sección examinaremos las llama-

das que implican el uso de directorios o el sistema de archivos como un todo.

Para leer o escribir en un archivo, éste debe primero abrirse mediante open. Esta llamada es-

pecifica el nombre del archivo que se va a abrir, ya sea como un nombre de ruta absoluto o relati-

vo al directorio de trabajo, y un código de O_RDONLY,  O_WRONLY o  O_RDWR, que significa

abrir para lectura, escritura o ambos. Para crear un nuevo archivo se utiliza el parámetro O_CREAT.

Después se puede utilizar el descriptor de archivo devuelto para leer o escribir. Al terminar, el ar-

chivo se puede cerrar mediante 

close

, que hace que el descriptor de archivo esté disponible para



reutilizarlo en una llamada a 

open


posterior.

Las llamadas de uso más frecuente son sin duda 

read



write



. Anteriormente vimos a 

read


.

Write


tiene los mismos parámetros.

Aunque la mayoría de los programas leen y escriben archivos en forma secuencial, para cier-

tas aplicaciones los programas necesitan la capacidad de acceder a cualquier parte del archivo en

forma aleatoria. Con cada archivo hay un apuntador asociado, el cual indica la posición actual 

en el archivo. Al leer (escribir) en forma secuencial, por lo general apunta al siguiente byte que se

va a leer (escribir). La llamada a 

lseek

cambia el valor del apuntador de posición, de manera que



las siguientes llamadas a 

read


write


puedan empezar en cualquier parte del archivo.

Lseek


tiene tres parámetros: el primero es el descriptor del archivo, el segundo es una posición

en el archivo y el tercero indica si la posición en el archivo es relativa al inicio del mismo, a la po-

sición actual o al final del archivo. El valor devuelto por 

lseek


es la posición absoluta en el archi-

vo (en bytes) después de modificar el apuntador.

Para cada archivo, UNIX lleva el registro del modo del archivo (archivo regular, especial, direc-

torio, etcétera), su tamaño, la hora de la última modificación y demás información. Para ver esta in-

formación, los programas pueden utilizar la llamada al sistema 

stat


. El primer parámetro especifica

el archivo que se va a inspeccionar; el segundo es un apuntador a una estructura en donde se va a co-

locar la información. Las llamadas al sistema fstat hacen lo mismo para un archivo abierto.

56

INTRODUCCIÓN

CAPÍTULO 1

Dirección (hex)

FFFF

0000


Pila

Datos


Texto

Espacio libre



Figura 1-20. Los procesos tienen tres segmentos: de texto, de datos y de pila.

SECCIÓN 1.6

LLAMADAS AL SISTEMA



57

1.6.3 Llamadas al sistema para la administración de directorios

En esta sección analizaremos algunas llamadas al sistema que se relacionan más con los directorios o

con el sistema de archivos como un todo, en vez de relacionarse sólo con un archivo específico, co-

mo en la sección anterior. Las primeras dos llamadas, 

mkdir



rmdir



, crean y eliminan directorios va-

cíos, respectivamente. La siguiente llamada es 

link

. Su propósito es permitir que aparezca el mismo



archivo bajo dos o más nombres, a menudo en distintos directorios. Un uso común es para permitir

que varios miembros del mismo equipo de programación compartan un archivo común, en donde ca-

da uno de ellos puede ver el archivo en su propio directorio, posiblemente bajo distintos nombres. No

es lo mismo compartir un archivo que proporcionar a cada miembro del equipo una copia privada; te-

ner un archivo compartido significa que los cambios que realice cualquier miembro del equipo serán

visibles de manera instantánea para los otros miembros; sólo hay un archivo. Cuando se realizan co-

pias de un archivo, los cambios subsiguientes que se realizan en una copia no afectan a las demás. 

Para ver cómo funciona 

link

, considere la situación de la figura 1-21(a). Aquí hay dos usua-



rios, ast jim, y cada uno tiene su propio directorio con algunos archivos. Si ast ejecuta ahora un

programa que contenga la llamada al sistema

link(“/usr/jim/memo”, “/usr/ast/nota”);

el archivo memo en el directorio de jim se introduce en el directorio de ast bajo el nombre nota. De

aquí en adelante, /usr/jim/memo /usr/ast/nota harán referencia al mismo archivo. Para comple-

mentar, hay que tener en cuenta que el lugar en el que se mantengan los directorios de los usuarios,

ya sea en /usr/user/home o en alguna otra parte es simplemente una decisión que realiza el admi-

nistrador del sistema local.

/usr/ast

/usr/jim


16

81

40



correo

juegos


prueba

(a)


31

70

59



38

bin


memo

f.c.


prog1

/usr/ast


/usr/jim

16

81



40

70

correo



juegos

prueba


nota

(b)


31

70

59



38

bin


memo

f.c.


prog1

Figura 1-21. a) Dos directorios antes de enlazar /usr/jim/memo al directorio de ast

b) Los mismos directorios después del enlace.

Entendiendo cómo funciona 

link


probablemente nos aclare lo que hace. Todo archivo en UNIX

tiene un número único, su número-i, que lo identifica. Este número-i es un índice en una tabla de no-



dos-i, uno por archivo, que indican quién es propietario del archivo, en dónde están sus bloques de

disco, etcétera. Un directorio es simplemente un archivo que contiene un conjunto de pares (núme-

ro-i, nombre ASCII). En las primeras versiones de UNIX, cada entrada de directorio era de 16 bytes:

2 bytes para el número-i y 14 bytes para el nombre. Ahora se necesita una estructura más complica-

da para soportar los nombres de archivo extensos, pero en concepto un directorio sigue siendo un

conjunto de pares (número-i, nombre ASCII). En la figura 1-21, correo tiene el número-i 16, y así

sucesivamente. Lo que 

link


hace es tan sólo crear una nueva entrada de directorio con un nombre

(posiblemente nuevo), usando el número-i de un archivo existente. En la figura 1-21(b), dos entra-

das tienen el mismo número-i (70) y por ende se refieren al mismo archivo. Si más adelante se eli-

mina una de las dos mediante la llamada al sistema 

unlink


, la otra sigue vigente. Si se eliminan

ambas, UNIX ve que no existen entradas para el archivo (un campo en el nodo-i lleva la cuenta del

número de entradas de directorio que apuntan al archivo), por lo que el archivo se elimina del disco.

Como dijimos antes, la llamada al sistema 

mount

permite combinar dos sistemas de archivos en



uno. Una situación común es hacer que el sistema de archivos raíz contenga las versiones binarias (eje-

cutables) de los comandos comunes y otros archivos de uso frecuente, en un disco duro. Así, el usua-

rio puede insertar un disco de CD-ROM con los archivos que se van a leer en la unidad de CD-ROM.

Al ejecutar la llamada al sistema 

mount

, el sistema de archivos de CD-ROM se puede adjuntar



al sistema de archivos raíz, como se muestra en la figura 1-22. Una instrucción común en C para

realizar el montaje es

mount(“/dev/fd0”, “/mnt”, 0);

donde el primer parámetro es el nombre de un archivo especial de bloque para la unidad 0, el se-

gundo parámetro es la posición en el árbol en donde se va a montar y el tercer parámetro indica que

el sistema de archivo se va a montar en modo de lectura-escritura o de sólo escritura.



58

INTRODUCCIÓN

CAPÍTULO 1

(a)


(b)

bin


dev

lib


mnt

usr


bin

dev


usr

lib


Figura 1-22. (a) Sistema de archivos antes del montaje.  (b) Sistema de archivos des-

pués del montaje.

Después de la llamada a 

mount


, se puede tener acceso a un archivo en la unidad 0 con sólo uti-

lizar su ruta del directorio raíz o del directorio de trabajo, sin importar en cuál unidad se encuentre.

De hecho, las unidades segunda, tercera y cuarta también se pueden montar en cualquier parte del

árbol. La llamada a 

mount

hace posible integrar los medios removibles en una sola jerarquía de ar-



chivos integrada, sin importar en qué dispositivo se encuentra un archivo. Aunque este ejemplo in-

volucra el uso de CD-ROMs, también se pueden montar porciones de los discos duros (que a

menudo se les conoce como 



Compartir con tus amigos:
1   ...   5   6   7   8   9   10   11   12   ...   134


La base de datos está protegida por derechos de autor ©absta.info 2019
enviar mensaje

    Página principal