Вы находитесь на странице: 1из 511

Programacion Linux 2.

0

API de sistema

y funcionamiento de ntscteo

, ,

Remy CARD Eric DUMAS

,

Franck MEVEL

"Ouvrage publie avec I'aide du Ministere charge de la Culture I Obra public ada con la ayuda del Ministerio frances responsable de la Cultura"

~EYROLLES

IZI EDiCIONES GEsnON ZOOO; S.A.

Prefacio

J

Hi dear Reader,

l

The book you hold in your hand will hopefully help you understand the Linux operating system kernel better, and you can delve into the strange and wonderful world of systems programming. Because it really is a strange and wonderful world, full of subtle details ranging from how to control the physical hardware to how to manage multiple different users at the same time with limited resources.

I certainly still, after more than five years, enjoy working on the Linux kernel, and hope that others will find it as fascinating as I have.

Linus Torvalds University of Helsinki

I

Indice

PR6LOGO 1

CAPITULO 1: LINUX: INTRODUCCI6N .5

1 Hlstoria 5

2 Descripci6n de Unux y sus funclonaHdades 7

3 iGradas, Internet! 8

4 Refer-endas 9

I



!

I

CAPITULO 2: PRESENTACI6N GENERAL 13

1 Los diler-entes tipos de sistemas operativos 1 3

2 Funci6n del sistema operativo 14

2.1 Maquina virtual 14

2.2 Compartir el procesador 15

2.3 Gesti6n de la memoria 16

2.4 Gesti6n de recursos 16

2.5 Centro de comunicaci6n de la maquina .16

3 Estructura general del sistema 17

4 Modo mideo, modo usuario 18

4.1 Principio 18

4.2 Llamadas al sistema .19

1 j

r

CAPITULO J: DESARROLLO BAJO LINUX 21

1 Los productos GNU 21

1.1 Presentaci6n 21

1.2 Herramientas GNU 22

1.2.1 Presentacion 22

1.2.2 gee 22

2 Las herramientas del desarroUador 23

2.1 Las diferentes Cases de la compilaci6n 23

iv Programaci6n Linux 2.0

2.2 gee 25

2.3 Depurador 27

2.4 straee 27

2.5 make 28

2.5.1 Presentacion 28

3 Formato de los ejecutables 28

3.1 a.out: el ancestro 29

3.2 ELF 29

3.2.1 Bienvenida al Mundo ELF 29

3.2.2 ELF Y su formato 30

4 Presentaci6n de las bibliotecas .32

4.1 Utilidad .32

4.2 Utilizaci6n de bibliotecas 33

5 Organizacl6n del c6digo fuente del nueleo 33

5.1 Ndcleo 33

5.2 Archives de cabecera 34

6 Funcionamlento del nueleo 36

6.1 L1amadas al sistema 36

6.1.1 lmplementacion de una llamada at sistema 36

6.1.2 Creacion de una llamada al sistema .37

6.1.3 C6digos de retorno .39

6.2 Func iones de utilidad .40

6.2.1 Manipulacion de espacio de direccionamiento .41

6.2.2 Asignaciones y liberaciones 41

CAPITULO 4: PROCESOS 43

1 Conceptos bBsicos 43

1.1 Noci6n de proceso 43

1.2 Estado de un proceso 44

1.3 Atributos de un proceso 45

1.4 Identificadores de un proceso .45

1.5 Filiaci6n 46

1.6 Grupos de procesos 46

1.7 Sesiones 48

1.8 Multiprogramaci6n .48

2 Llamadas aI sistema de base 49

2.1 Creaci6n de procesos .49

2.2 Finalizaci6n del proceso actual .50

2.3 Espera de la finalizaci6n de un proceso hijo 50

2.4 Lectura de los atributos del proceso actual .53

2.5 Modificaci6n de atributos 54

2.6 Informaci6n de contabilidad 56

t

,I j

I I

indice

v

2.7 Lfmites 57

2.8 Grupos de procesos 58

2.9 Sesiones 59

2.10 Ejecuci6n de programa .59

3 Conceptos avanzados 61

3.1 Coordinador 61

3.2 Personalidades 62

3.3 Clonado 63

4 Llamadas 81 sistema complementarias 64

4.1 Cambio de personalidad 64

4.2 Modificaci6n de la coordinaci6n 65

4.3 Prioridades de los procesos 67

4.4 Control de la ejecuci6n de un proceso 68

4.5 Clonado 70

5 Presentaci6n general de la implementaci6n 74

5.1 La tabla de procesos 74

5.1.1 Descriptor de proceso 74

5.1.2 Organizacion de La tabla de procesos 78

5.1.3 Manipulacion de La tabla de procesos 79

5.2 Registros del procesador 79

5.3 Sincronizaci6n de procesos 81

5.3.1 Principio 81

5.3.2 Colas de espera 81

5.3.3 Semdforos 81

5.4 Los timers 83

5.5 Ambitos de ejecuci6n 83

5.6 Forrnatos de los archivos ejecutables 84

6 Presentaci6n detallada de la implementaci6n 85

6.1 Funciones internas 85

6.1.1 Sincronizacion de procesos 85

6.1.2 Coordinacion 86

6.1.3 Los timers 88

6.1.4 Espera con demora 88

6.2 Implementaci6n de las lIamadas at sistema 89

6.2.1 Creaci6n de procesos 89

6.2.2 Terminacion de proceso 90

6.2.3 Obtenci6n de los atributos 92

6.2.4 Modijicaci6n de atributos 92

6.2.5 Grupos de procesos y sesiones 93

6.2.6 Control de procesos 93

,

vi

Programaci6n Linux 2.0

CAPiTULO 5: SEN-ALES 97

1 Conceptos basicos 97

1.1 Introducci6n 97

1.2 Definici6n de sefiales 97

1.3 Lista de sen ales 99

1.4 Visualizaci6n de las sefiales .1 00

2 Llamadas aI sistema de base .1 01

2.1 Emisi6n de una sefial .1 02

2.2 Desviaci6n de una seiial 103

2.3 Espera de una sena 105

3 Conceptos avanzados 106

3.1 Las Ilamadas al sistema interrumpibles .106

3.2 Las funciones reentrantes .106

3.3 Los grupos de senates 107

4 Llamadas al sistema complementarias 108

4.1 La gesti6n avanzada de las sen ales 108

4. I. I La interrupcion de las llamadas al sistema 108

4. J.2 El bloqueo de las seiiales 108

4.1.3 El desvio de senales 111

4.1.4 La espera de senaJes 112

4.2 La gesti6n de las alarmas .113

4.2.1 La llamada al sistema alarm .113

4.2.2 Una gestion mas precisa del tiempo 114

4.3 La sefial SIGCHLD 117

5 Presentaci6n general de la implementaci6n 119

5.1 Las estructuras de datos 119

5.1.1 La creacion y la terminacion de procesos .119

5.1.2 La emision de senaLes 120

5.1.3 La recepcion de las seiiales 120

6 Presentaci6n detallacla de la implementaci6n .121

6. t Funciones de biblioteca 121

6.1.1 La gestion de los grupos de seiiales 121

6.1.2 La funcion raise 122

6.2 Las Ilamadas at sistema 122

6.2.1 El bloqueo de las seiiales .122

6.2.2 El desvio de seiiales 123

6.2.3 Las seiiales en espera .124

6.2.4 La suspension del proceso en espera de seiiales 124

6.2.5 EL envio de seiiales .124

6.2.6 La gestion de las alarmas .125

lndice

vii

CAPiTULO 6: SISTEMAS DE ARCHIVOS 127

1 Conceptos buieos 127

1.1 Organizaci6n de los archivos .127

1.2 Tipos de archivos 128

1.3 Enlaces con los archivos 129

1.4 Atributos de archivos 130

1.5 Primitivas de entrada/salida 131

1.6 Descriptores de entradas/salidas 132

2 Llamadas bBsicas al sistema 132

2.1 Entradaslsalidas sobre archivos .132

2.1.1 Aperture y cierre de archives 132

2.1.2 Lectura y escritura de datos 134

2.1.3 Posicionamiento en un archive 136

2.1.4 Guardar los datos modificados 13 8

2.2 Manipulaci6n de archivos 139

2.2.1 Creacion de enlaces 139

2.2.2 Supresion de archivos 139

2.2.3 Cambia de nombre de un archivo 140

2.2.4 Cambia de tamaiio de un archive .141

2.2.5 Derechas de acceso sobre un archivo 142

2.2.6 Modijicacion del usuario propietario 143

2.3 Gesti6n de directorios 144

2.3. J Creacion de directorios 144

2.3.2 Supresion de directorios 145

2.3.3 Directorio actual .145

2.3.4 Directorio raiz local .146

2.3.5 Exploracion de los directories 147

2.4 Enlaces simb6licos 151

3 Conceptos avanzados 152

3.1 i-nodos 152

3.2 Descriptores de entrada/salida 153

3.3 Compartir descriptores 154

3.4 Bloqueo de archivos .156

3.5 Montaje de sistemas de archivos 157

3.6 Cuotas de disco 157

4 Llamadas al sistema complementarlas .159

4.1 Lectura y escritura de varias memorias intermedias 159

4.2 Duplicaci6n de descriptor de entrada/salida 160

4.3 Atributos de archivos 161

4.4 Fechas asociadas a los archivos 164

4.5 Propiedades de los archivos abiertos 165

viii

Programaci6n Linux 2.0

4.6 Control del proceso bdflush 166

4.7 Bloqueo 168

4.7.1 Bloqueo de un archivo 168

4.7.2 Bloqueo de una seccion de un archivo 168

4.8 Montaje de sistemas de archives 169

4.9 Informaciones sobre un sistema de archives 171

4.10 Informaci6n sabre los tipos de sistemas de archivos soportados 172

4.11 Manipulaci6n de cuotas de disco 173

5 Presentad6n general de la Implementaci6n .175

5.1 EI sistema virtual de archives 175

5./.1 Principia 175

5.1.2 Operaciones aseguradas por el SVA 176

5.2 Estructuras del SVA 177

5.2.1 Tipos de sistemas de archivos 177

5.2.2 Sistemas de archivos mont ados 178

5.2.3 l-nodos en curso de utilizacion .179

5.2.4 Archivos abiertos 181

5.2.5 Archivos abiertos por un proceso 181

5.2.6 Descriptores de bloqueos 182

5.2.7 Descriptores de cuotas de disco 183

5.2.8 Memorias intermedias del bujer cache 184

5.2.9 Cache de nombres 186

5.3 Operaciones genericas 187

5.3.1 Operaciones sobre superbloques 187

5.3.2 Operaciones sobre i-nodos .189

5.3.3 Operaciones sobre archivos abiertos 192

5.3.4 Operaciones sobre cuotas de disco 194

6 Presentacl6n detallada de la implementaci6n 195

6.1 Funciones intemas del SVA 195

6.1.1 Gestion de descriptores de sistemas de archivos montados 195

6.1.2 Gestion de los i-nodos 197

6.1.3 Gestion de descriptores de archivos abiertos 201

6.1.4 Gestui« de descriptores de cuotas de disco 202

6.1.5 El cacM de nombres 207

6.1.6 Funciones de soporte de gestion de i-nodos 209

6.1.7 Gestion de los nombres de archives .210

6.1.8 Gestion de bloqueos 211

6.2 EI bUfer cache 213

6.2.1 Presentacion 213

6.2.2 Gestion de las listas de memorias intermedias 213

6.2.3 Entradas/salidas 216

lndice

ix

I < j

6.2.4 Modificad6n del tamaho del bufer cadre 217

6,2,5 Funciones de gestion de dispositivos "., .. , , 219

6.2.6 Funciones de acceso a las memorias intermedias . , 219

6.2.7 Reescritura de las memorias intermedias modificadas 220

6.2.8 Gestion de clusters , , , , , , , . , , , , , , , 222

6.2,9 lnicializacion del bufer cache ,""" 223

6.3 Implementaci6n de las llamadas al sistema, . , , , , , . , 224

6.3. } Organizacion de los archives fuente . .. , , . , , , 224

6.3.2 ManipuJaci6n de archivos ,"", ", ,"" .224

6.3.3 Gesti6n de los atributos de archivos , , , , , , , , , , , ,225

6.3.4 Entrada/salida sobre archivos ,""",.,',', , ,226

6.3.5 Lectura de directorio ,""""'" . , , , , , , , , .228

6.3.6 Gesti6n de bloqueos , , , , , , , , , , , , , , , , ,228

6.3,7 Gesti6n del bufer cache ", , , . , , , , 230

6.3,8 Gestion de los sistemas de archivos , , , , . , , , , , , , , .230

6.3.9 ManipuJaci6n de descriptores de entrada/salida ".,.,." ,232

6.3,/0 Herencia de descriptores ,.,", ,." .... ,"" .233

6.3,11 Cambia de directorio , , , , , , , , , , , , , , , , 234

6.3.12 Gesti6n de las cuotas de disco, , , , , . , , , , , , , .. , , , , , ,234

6.4 Sistemas de archives soportados , , , , , , , , , , .. , , , , ,236

6.5 Implementaci6n del sistema de archives Ext2 , , , , , , , , , 237

6.5, } Caracteristicas de Ext2 .,." ,"", ,237

6.5,2 Estructura fisica de un sistema de archivos Ext2 ' .. """ ,238

6,5.3 El superbloque , , , , , , .... , , , , , , ... , , , , , , , , , , , .239

6,5.4 Los descriptores de grupo de bloques " ,', .. ", ,240

6.5,5 Estructura de un i-nodo , , , , , , , , , , , , ,241

6.5,6 Entrada de directorio , , , , , , , 242

6.5.7 Operaciones vinculadas al sistema de archivos " .. 243

6.5.8 Asignaci6n y liberacion de bloques e i-nodos , 244

6.5.9 Gestion de los i-nodos en disco ,"', ,' ,246

6.5,/0 Gesti6n de directorios ,', 248

6.5. / / Entradas/salidas sobre archivos , 249

6.6 Implementaci6n del sistema de archives /proc , . , , .250

6.6.1 Presentaci6n " ,., .. 250

6.6.2 Entradas de /proc " 252

6.6.3 Operaciones sabre sistema de archivos ,." 253

6.6.4 Gestion de directorios ,"" ,254

6.6.5 Operaciones sobre i-nodos y sobre archivos , , 255

CAPiTULO 7: ENTRADAS/SALIDAS , .. , 257

1 Conceptos , , .. ,'" .257

2 Llamadas al sistema " .. , , , .258

,

x

Programaci6n Linux 2.0

2.1 Creaci6n de un archivo especial 258

2.2. Entradaslsalidas sobre dispositivos 259

2.3 Multiplexado de entradaslsaiidas 260

2.4 Operaci6n de control sobre un dispositivo 262

3 Presentaci6n general de la implementacl6n 262

3.1 Dispositivos soportados por el nucleo 262

3.2 Entradaslsalidas en disco 263

4 Presentaci6n detalJada de 18 implementaci6n 264

4.1 Gesti6n de los dispositivos efectuados 264

4.2 Entradaslsalidas de disco 265

4.3 Entradaslsalidas sobre dispositivos en modo bloque 266

4.4 Multiplexado de entradas/saiidas 266

4.4.1 Principio 266

4.4.2 Funciones de utilidad 267

4.4.3 La operacion sobre archive select 268

4.4.4 Implementacion de La primitiva select 269

4.5 Gesti6n de las interrupciones 269

4.6 Gesti6n de los canales DMA 270

4.7 Acceso a los puertos de entrada/salida 271

4.8 Ejemplo de dispositivo en modo bloque: el disco en memoria 272

4.8.1 Presentacion 272

4.8.2 Acceso al contenido del disco en memoria 272

4.8.3 Operaciones sobre archivos 273

4.8.4 Inicializacion 273

4.8.5 Cargo de disco de memoria 274

4.9 Ejempio de dispositive en modo caracter: la impresora 275

4.9.1 Funcionamiento 275

4.9.2 Descripci6n de los puertos , 275

4.9.3 Funciones de gesti6n de fa impresora con exploracion .. ". ,276

4.9.4 Funciones de gesti6n de La impresora con interrupciones 276

4.9.5 Operaciones de entrada/salida sobre archivo 277

4.9.6 Funciones de inicializacion .278

CAPiTULO 8: GESTI6N DE LA MEMORIA 279

1 Conceptos basicos 279

1.1 Espacio de direccionamiento de un proceso 279

1.2 Asignaci6n de memoria 281

2 Llamadas al sistema de base 281

2.1 Cambio del tamano del segmento de datos 281

2.2 Funciones de asignaci6n y liberaci6n de memoria , 282

3 Conceptos avanzados 283

3.1 Regiones de memoria ,' 283

lndice

xi

3.2 Protecci6n de la memoria 284

3.3 Bloqueo de zonas de memoria 285

3.4 Proyecci6n de archives en memoria 286

3.5 Dispositivos de swap 287

4 Llamadas aI sistema complementarias 287

4.1 Protecci6n de paginas de memoria 287

4.2 Bloqueo de paginas de memoria 288

4.3 Proyecci6n en memoria 289

4.4 Sincronizaci6n de paginas en memoria 292

4.5 Gesti6n de los dispositivos de swap 293

5 Presentad6n general de la Implementacl6n 294

5.1 Gesti6n de las tablas de pagina 294

5.1.1 Segmentaci6n 294

5.1 .2 Paginaci6n .296

5.1.3 Tablas de paginas gestionadas por Linux 298

5.1.4 Compartir pdginas 298

5.1.5 Tipos 299

5.2 Gesti6n de las pliginas de memoria 299

5.2.1 Descriptores de pagina 299

5.3 Asignaci6n de memoria para el nacleo .301

5.3.1 Asignaci6n de paginas de memoria .301

5.3.2 Asignaci6n de zonas de memoria 302

5.4 Espacios de direccionamiento de los procesos 304

5.4.1 Descriptores de regiones de memoria 304

5.4.2 Descriptores de espacio de direccionamiento 305

5.4.3 Organizaci6n de los descriptores de regiones .306

5.5 Asignaci6n de memoria no contigua aI m1cleo 309

5.6 Gesti6n del swap .309

5.6.1 Formato de los dispositivos de swap 309

5.6.2 Descriptores de dispositivos de swap 310

5.6.3 Direcciones de entradas del swap 311

5.6.4 Seleccion de pdginas a descartar 311

5.7 Operaciones de memoria , 312

6 Presentacl6n detallada de la implementacl6n 314

6.1 Asignaci6n de memoria para el m1cleo 314

6.1.1 Asignaci6n de pdglnas de memoria 314

6.1.2 Asignaci6n de regiones de memoria .315

6.2 Gesti6n de las tablas de paginas .315

6.3 Gesti6n de las regiones de memoria 3 t 9

6.4 Tratamiento de las excepciones 320

6.5 Acceso aI espacio de direccionamiento de los procesos 322

xii Programaci6n Linux 2.0

6.6 Modificaci6n de regiones de memoria .323

6.6.1 Creacion y supresion de regiones de memoria 323

6.6.2 Bloqueo de regiones de memoria .. , 324

6.6.3 Modificaciones de protecciones de memoria 326

6.6.4 Reasignar regiones de memoria 327

6.7 Creaci6n y supresi6n de espacio de direccionarniento 328

6.8 Proyecci6n de archivos en memoria .329

6.9 Gesti6n del swap .332

6.9.1 Gestion de los dispositivos de swap .332

6.9.2 Entrada/salida de pdginas de swap " .. ,333

6.9.3 Eliminacion de pdginas de memoria 334

CAP1TUW 9: TERMINALES POSIX .337

1 Conceptos bulcH .337

1.1 Presentaci6n general .337

1.2 Configuraci6n de un terminal .339

1.2.1 Modo canonico - modo no canonico .339

1.2.2 La estructura termios .340

1.2.3 Funcionamiento de una comunicaci6n 341

1.2.4 Configuracion de los modos de entrada , 341

1.2.5 Conftguracion de los modos de salida 342

1.2.6 Conftguracion de los modos de control 343

1.2.7 Configuraci6n de los modos locales 344

1.3 Los caracteres especiales y la tabla c_cc .345

1.4 EI mandato stty 346

1 .5 EI mandato setserial .347

1.6 Gmpos de tenninales _ sesi6n .347

1,7 Pseudotenninales .348

2 Las funciones POSIX - . - .349

2.1 Acceder y modificar los atributos de un terminal 349

2.2 Un ejemplo de configuraci6n de linea .351

2.3 La velocidad de transmisi6n 352

2.4 Control de lfnea .355

2.5 Identificaci6n del terminal .357

2.6 Grupos de procesos .359

2.7 Pseudotenninales .360

3 Organizaci6n en el nucleo - estructuras de datos ' 363

3.1 Organizaci6n 363

3.2 Estructuras de datos intemas .364

3.3 La estructura tty_struct .364

3.4 La estructura tty_driver 366

3.5 La estructura tty_ldisc 369

lndice

xiii

3.6 La estructura win size .371

3.7 La estructura tty_flip_buffer 371

4 Implementaci6n .372

4.1 La inicializaci6n .372

4.2 Las entradaslsalidas en los terminales 373

4.3 Otras funciones generales , 374

4,4 Gesti6n de la desconexi6n 375

4.5 La gesti6n de la disciplina de la lfnea 376

4.6 Los pseudotenninales .378

CAPiTULO lO:COMUNICACI6N POR TUBEIUAS " 381

1 Conceptos bAslcos .3 81

1.1 Presentaci6n 381

1.2 Tuberfas an6nimas y tuberfas con nombre 382

2 Llamadas al sistema .383

2.1 Thberfas an6nimas 383

2.1.1 Creacion de una tuberia 383

2.1.2 Un ejemplo de usa 385

2.1.3 Creacion de una tuberia y ejecucion de un programa 388

2.2 Las tuberfas con nombre 388

3 Presentaci6n general de Ia implementaci6n 390

3.1 Las tuberfas con nombre .390

3.2 Las tuberfas an6nimas , 391

4 Presentaci6n detallada de la implementaci6n 391

4.1 Creaci6n del i-nodo de una tuberfa 391

4.2 Creaci6n de una tuberfa con nombre 391

4.3 Creaci6n de una tuberia an6nima 392

4.4 Operaciones de entradaslsalidas .392

CAPITULO 11: IPC SYSTEM V .395

1 Conceptos basicos 395

1.1 Introducci6n .395

I .2 La gestion de claves .396

1.3 Los derechos de acceso .398

2 Llamadas al sistema 398

2.1 Colas de mensajes .399

2. J .J Las estructuras bdsicas 399

2.1.2 Creacion y busqueda de colas de mensajes 0400

2.1.3 Control de las colas de mensajes 401

2.1.4 Emisi6n de mensajes 0402

2.1.5 Recepcion de mensajes .403

2.1.6 Un ejemplo de usa .404

XIV

Programaci6n Linux 2.0

2.2 Semaforos 411

2.2.1 Las estructuras basicas 412

2.2.2 Creacion y bUsqueoo de grupos de semdforos .413

2.2.3 Operaciones sabre los semdforos 414

2.2.4 El control de los semdforos 415

2.3 Memorias compartidas .417

2.3.1 Las estructuras basicas .417

2.3.2 Creaci6n y bwqueoo de una zona de memoria compartida . .418

2.3.3 Vinculaci6n de una zona de memoria .419

2.3.4 Desvincular una zona de memoria .420

2.3.5 Control de las zonas de memoria compartidas 420

2.3.6 Interacci6n can otras llamadas al sistema .421

2.3.7 Ejemplo de usa 421

3 Concept os avanzados .428

3.1 Opci6n de compilaci6n del nucleo 428

3.2 Los programas ipcs e ipcnn 429

3.2.1 ipcs 429

3.2.2 ipcrm .430

4 Presentad6n general de la implementacl6n 431

4.1 Funciones comunes 431

4.2 Algoritmos .432

4.3 Gesti6n de las claves .433

5 Presentad6n deta1Jada de la implementad6n 433

5.1 Colas de mensajes .433

5.1.1 Representacion intema de las colas de mensajes .434

5.1.2 La inicializacion 435

5.1.3 Creacion de una cola de mensajes .435

5.1.4 El envio de un mensaje .435

5.1.5 La recepcion de un mensaje .435

5.1.6 El control de una cola de mensajes 435

5.2 Semaforos .436

5.2.1 Representacion intema de los semdforos .436

5.2.2 La inicializacion 436

5.2.3 Creacion de semdforos .437

5.2.4 Control de los semdforos .437

5.2.5 Modificacion de los valores de semdforos 438

5.2.6 La finalizacion .438

5.3 Memorias compartidas .439

5.3.1 Representacion intema de las memorias compartidas .439

5.3.2 La inicializacion .440

5.3.3 Creacion de una zona de memoria compartida .440

lndice xv

5.3.4 Vinculacio" de una zona de memoria 441

5.3.5 Desvinculacion de una zona de memoria compartida 441

5.3.6 Control de las zonas de memoria compartidas 441

5.3.7 Herencia de las zonas de memoria compartidas 442

CAPiTULO 12: LOS M6DULOS CARGABLES 443

1 Conceptos b4sicos 443

1.1 Presentaci6n 443

1.2 Compilaci6n 444

1.3 Operaciones en lfnea de mandates: la carga manual 445

1.4 Carga dinamica 446

2 Conceptos avanzados 448

2.1 La realizaci6n de un m6dulo cargable , .448

2.1.1 Presentacion , , " 448

2.1.2 Ejemplo , ", 448

2.1.3 Compilacion yejecucion ,."., ," .450

2.2 Las lIamadas al sistema especfficas de los m6dulos ,' ,451

2.2.1 get_kemelflms " .. 451

2.2.2 create module , , . .452

2.2.3 init_module , .. " , , .452

2.2.4 delete_module ,', ,454

3 Impiementad6D de los m6dulos cargables , , , , , , 454

3.1 Presentaci6n 454

3.2 Implementaci6n de las lIamadas a1 sistema .455

3.2.1 create_nwdule 455

3.2.2 init_module 455

3.2.3 delete module .455

3.2.4 get_kernel_syms .456

3.3 Gesti6n de los archives virtuales 456

3.4 Funciones anexas 457

4 Carga automatica de m6dulos (kerneld) 457

4.1 Presentaci6n 457

4.2 Detalle de la implementaci6n 458

CAPITUL013:ADMINISTRACION DEL SISTEMA .461

1 Conceptos bBsicos 461

1.1 Infonnaciones destinadas a los procesos 461

1.2 Infonnaciones que controlan la ejecuci6n .462

1.3 Cambia de estado del nucleo 463

1.4 Configuraci6n dinamica del sistema .463

1.4.1 Presentacion 463

1.4.2 Otro metoda: /proc/sys .463

XVI

Programaci6n Linux 2.0

2 Llamadas aI sistema de atbninistracion 464

2.1 Informaciones respecto a la estaci6n 464

2.2 Control de la ejecuci6n 467

2.2.1 El tiempo 467

2.2.2 Modo de visualizacion de los mensajes del nucleo 469

2.2.3 Estado de la mdquina 471

2.2.4 Sincronizacion de relojes 473

2.3 Cambio de estado del m1cleo 474

2.4 Configuraci6n dimimica del sistema 474

3 Implementaci6n 477

3.1 sethostname, gethostname, setdomainname y uname .477

3.2 reboot 478

3.3 syslog 478

3.4 gettimeofday, settimeofday, time y stime .479

3.4. J time 479

3.4.2 slime 479

3.4.3 gettimeofday 479

3.4.4 settimeofday 480

3.5 sysctl 480

3.6 adjtimex 481

APENDICE A: FASES DE UNA COMPILACI6N C 483

1 Preprocesador 483

2 Compilador 484

3 Ensamblador 485

4 Enlazador 485

APENDICE B: UTILIZACI6N DE GDB .487

APENDICE C: UTILIZACI6N DE MAKE .491

1 Funcionamiento de make .491

2 Escritura de un archivo makefile 491

APENDICE D: GESTI6N DE LAS BmLIOTECAS .493

1 Herramientas de creaci6n y de manipuJacion 493

2 Bibliotecas est8ticas .494

3 Bibliotecas dioBmicas a.out .495

4 Bibliotecas dinamicas ELF 495

5 La carga dimimica de bibliotecas .496

BIBLIOGRAFfA 499

Pr61ogo

Desde hace algunos afios, el sistema operativo Linux se implanta cada vez mas en los medios universitarios e industriales. Este cl6nico de Unix cuya estabilidad y potencia Ie permiten rivalizar sin complejos con los otros sistemas operativos comerciales, posee ciertas especificidades que 10 hacen muy interesante. La libre difusi6n de su c6digo fuente en Internet ha contribuido ampliamente a popularizar Linux, que se ha convertido as! en un tema de estudio ideal.

Organizaci6n dellibro

Esta obra, cuya redacci6n ha ocupado alrededor de un afio, tiene como objetivo presentar los diferentes aspectos de Linux 2.0 desde el punto de vista de un desarrollador, y asimismo analizar su micleo, que constituye el centro del sistema operativo Linux. Este libra no es solamente un libra de programaci6n de sistemas para Unix (y para Linux en particular): es tambien un media para comprender el funcionamiento interno del nucleo,

.,

Ellibro se divide en 13 capftulos que detallan la mayor parte de aspectos de este sistema, excepto la gestion de los protocolos de red, que necesitarlan un libro completo.

Los tres primeros capftulos son introductorios:

J

• EI primer capitulo presenta el origen y las funcionalidades del sistema Linux.

Tambien proporciona una lista de referencias.

• EI segundo capitulo es una presentaci6n rapida de los distintos componentes de un sistema operativo y de Linux en particular. En el se explica la noci6n de modo micleo y modo usuario y se detalla el mecanismo de las lIamadas aI sistema .

. ~

Contiene una descripci6n de la organizaci6n de las fuentes del nticleo y algunas referencias sobre la instalaci6n y 1a manipulaci6n de las herrarnientas basicas de Linux .

. /

,..--

2

Programaci6n Linux 2.0

• EI tercer capftulo describe las herramientas de desarrollo disponibles bajo Linux, e introduce las nociones de programaci6n del sistema.

Los capftulos siguientes describen en detalle el sistema Linux, Cada uno de elias presenta primero la interfaz de sistema relacionada can el concepto que describe seguida de la implementaci6n de dicho concepto en el micleo Linux:

• Los capftulos 4 y 5 tratan la gesti6n de los procesos y las sefiales,

• El capttulo 6 presenta la gesti6n de archivos. La implementaci6n describe el sistema virtual de archivos y dos ejemplos de sistemas de archives, Ext2 y Iproc.

• El capitulo 7 ahorda las entradaslsalidas sobre dispositivos y analiza particularmente el controlador de impresora y el gestor de disco en memoria.

• EI capitulo 8 presenta un concepto importante de los sistemas actuales, la gesti6n de la memoria virtual.

• EI capftulo 9 se interesa por la gesti6n de los terminales.

• Los capftulos 10 y 11 describen las comunicaeiones interprocesos, el pipeline y los !PC System V.

• Los dos ultimos capftulos tratan sobre la earga dinarnica de m6dulos en el nucleo y sobre funciones utiles para la administraci6n del sistema.

Para terminar, cuatro apendices detallan la utilizaci6n de las herramientas de desarrollo bajo Linux (compilador de C. depurador, make y herramientas de gesti6n de bibliotecas) .

Cada capftulo se compone de varias partes: las primeras presentan los eonceptos expuestos, asf como las lIamadas de sistema tratadas, mientras que las siguientes deta- 11an el funeionamiento del micleo, describiendo las estructuras de datos utilizadas y las funciones internas de Linux.

Esta estructuraci6n permite allector recorrer un capitulo yendo de los coneeptos generales hasta los detaJles de la implementaci6n. La lectura puede Ilevarse a cabo, pues, de manera secuenciaJ par capftulos, pero tambien de manera aleatoria, en funci6n de las necesidades, del tiempo, la curiosidad ...

Diversos ejemplos (en lenguaje C). figuras y tablas completan el contenido de esta obra que pretende ser clara, completa e ilustrada. Ellector encontrara al final una bibJiograffa relativa a los sistemas operatives y a la documentaci6n tecnica existentes sobre Linux,

Pr6logo

3

Publico y prerrequisitos

Este libro va destinado a los desarrolladores de sistemas. ya sean esrudiantes, profesionales 0 investigadores en informatica, Puede utilizarse como apoyo de cursos sobre sistemas, como ayuda en el desarrollo de programas, 0 en el desarrollo en el micleo. La propia estructura de los capftulos 10 hace accesible a un publico muy variado: el principiante podI'li limitarse aJ principio a leer las primeras partes de un capitulo, mientras que el hacker (programador del sistema) se centran\ mas bien en el funcionamiento interne del nucleo.

, , '11

Sin embargo. es necesario precisar que se requiere el conocimiento dellenguaje C y de su biblioteca est4ndar. Ademas, el lector debe estar familiarizado can los conceptos generales relacionados con los sistemas operativos en general. y con Unix en particular. para comprender los ejemplos y la descripci6n del funcionamiento interno del nncleo.

La lectura de estas panes es mas ardua, por 10 que se aconseja estudiar el c6digo fuente del ndcleo de fonna paralela.

Convenciones utilizadas

., .



I

Todas las lIamadas al sistema presentadas en un capftulo se agrupan en un cuadro al principio de cada capitulo:

-Primitillas detalladas .

_ liamadal 1m ~ ... 1

Se utilizan tablas para aclarar la descripci6n de las estructuras y uniones presentadas. Tambien se usan para las listas de errores correspondientes a las lIamadas al sistema, las listas de constantes y las listas de macroinstrucciones.

Los prototipos de las funciones de la biblioteca estandar del C y las diferentes lIamadas al sistema presentadas se escriben en forma de teletipo.

Los nombres de lIamadas aJ sistema. de funciones de biblioteca y de mandatos se representan en cursiva. Se utiJiza un tipo de tetra teletipo para los nombres de tipos, de estructuras, de variables y de funciones.

r

4

Programacion Linux 2.0

Agradecimientos

La redacci6n de este libro no habrfa side posible sin la colaboraci6n de numerosas personas.

Agradecemos a todos los desarrolladores de Linux. y especialmente al primero de ellos, Linus Torvalds. Sin ellos, este sistema operativo no habrfa nacido.

Nuestro agradecimiento a Benjamin Bayart por su valiosa ayuda sobre el uso y la programaci6n de LaTeX.

Queremos agradecer a las personas que han aceptado hacer el trabajo ingrato de relectura de esta obra y han participado en gran medida a mejorar su contenido gracias a sus numerosas crfticas constructivas y sugerencias: Eric Commelin. Pierre David, Pierre Ficheux, Thomas Quinot, Pierre-Guillaume Raverdy, y Stephan Voisin.

Finalmente, nuestro agradecimiento a Julien Simon, que ha contribuido ampliamente a la definicion y a la estructuraci6n de este libro.

Evidentemente, un libro asf contiene necesariamente errores 0 imprecisiones, Invitamos a los lectores a transmitimos sus comentarios, sugerencias y correcciones de errores por correo electr6nico, a la direcci6n in f o@ges t i on2 000 . com.

Rimy Card (Remy.Card@linux.org) Eric Dumas (dumas@freenix.fr) Franck Mivei (mevel@Linux.EU.Org)

I ,

,

Capitulo 1

, ,

Linux: Introduccion

Linux, Linux, Linux ... pero, i.por que el nombre Linux? Antes de adentrarnos en los vericuetos de este sistema operativo y de su micleo, se impone una breve presentaci6n de su historia y de su concepci6n, pues su historia es particularmente original en el mundo de los sistemas operativos. A continuaci6n de esta presentaci6n se exponen las funcionalidades del rnicleo y se proporciona una lista de referencias.

1 Historia

t

La historia de Linux empieza en Finlandia en 1991, cuando un tal Linus B. Torvalds (Linus.Torvalds@cs.helsinki.ji), estudiante de la universidad de Helsinki, compra un PC con un procesador 386 pant estudiar su funcionamiento. MS/DOS no aprovechaba las caracterfsticas del procesador 386 (por ejemplo el modo llamado protegido), por 10 que Linus utilize otro sistema operativo comercializado: Minix, desarrollado principalmente por Andrew Tanenbaum. EI sistema Minix era un pequefio sistema Unix.

Sin embargo, debido a las limitaciones de este sistema, Linus empez6 a reescribir algunas partes, a afiadir funcionalidades, etc. Posteriormente, difundi6 el c6digo fuente de su trabajo por Internet, de manera gratuita, con el nombre de Linux, contracci6n de Linus y Unix. j Habia nacido Linux! La primera difusi6n de Linu x tu vo lugar el mes de agosto de 1991. Se trataba de la versi6n 0.01.

Esta primera versi6n era 10 que se podrfa denominar un embri6n. Ni siquiera hubo anuncio oficial. La primera versi6n «oficial» se hizo publica el 5 de octubre de 1991 (versi6n 0.02). Esta versi6n permitfa el funcionamiento de algunos programas GNU como bash, gee, ... pero poca cosa mas,

, I

.r"

6

Programacion Linux 2.0

Estas primeras versiones eran muy limitadas (jLinux 0.01 s610 podfa funeionar bajo Minix!). Sin embargo, el hecho que el e6digo fuente se difundiera penniti6 una rapida evoluci6n del sistema. Con el paso de los ailos, el mimero de desarrolladores no ha dejado de aumentar. AI principio, s610 algunos apasionados se enteraron de la aparici6n de este sistema y se interesaron en ~1. Actualmente, Linux 10 desarrollan decenas de personas situadas en todos los rincones del mundo, que en su mayor parte no se han visto j8J114s: unas 80 personas contribuyeron a la versi6n 1.0, y hay mas de 190 desarrolladores referenciados para la versi6n 2.0.

EI papel de la red mundial Internet es importante porque ha penni lido una rapida evoluci6n del sistema. Es f4cil imaginar a un desarrollador instalando Linux en su maquina, eneontrando un error, corrigiendolo y enviando el archivo fuente corregido a Linus. Unos dfas m4s tarde (en ocasiones tan s610 unos minutos), el nucleo corregido puede difundirse de nuevo.

Si las primeras versiones de Linux eran relativamente inestables (jcuantas reinstalaciones habta que lIevar a cabo!), la primera version considerada estable (1.0) se hizo publica a1rededor de marzo de 1994. EI rnimero de versi6n asociado al micleo tiene un sentido muy particular porque esta relacionado con su desarrollo, ya que la evoluci6n de Linux se efecn1a en una sucesi6n de dos fases:

• Una fase de desarrollo: el ndcleo cuya estabilidad no esta asegurada y cuyo objetivo es aiiadirle funcionalidades, optimizaciones y nuevas conceptos. Esta fase se caracteriza por un mlmero de versi6n impar: 1.1, 1.3. En este momenta es cuando 'se efecnia la mayor parte del trabajo sobre el micleo.

• Una fase de estabilizaci6n cuyo objetivo es obtener el nucleo mas estable posible.

En este caso, las iinicas modificaciones efectuadas en el rnicleo son generalmente correcciones y algunas mejoras menores, Los mimeros de version de estos mlc1eos llamados estabJes son pares como 1.0, 1.2 y, mas recientemente, 2.0.

Actualmente, Linux es un sistema Unix complete, estable, que sigue evolucionando. Ademas de gestionar los ultimos dispositivos del mercado (memorias flash. discos 6pticos. etc.), su rendimiento es comparable al de ciertos sistemas Unix cornerciales, y es incluso superior en algunos puntos. Finalmente, aunque Linux ha permanecido mucho tiempo encerrado en el mundo universitario (a menudo debido aI acceso a Internet. con el que s610 contaban los universitarios), actualmente empieza a implantarse en el mundo de la empresa, Su gratuidad, su potencia y especial mente su flexibilidad seducen a un mlmero creciente de empresas.

En este momento, la ultima versi6n estable es la versi6n 2.0, y es la versi6n analizada en este libro.

Linux: IntroducciOn

7

2

Descripci6n de Linux y de sus funcionalidades

Linux se disei'i6 inicialmente como un c16nico de Unix. distribuido Jibremente que funcionaba en maquinas PC con procesador 386, 486 0 superior. Aunque se desarro1l6 inicialmente para la arquitectura x.86, en la actualidad funciona sobre otras platafonnas como los procesadores Alpha, Spare, ciertas plataformas basadas en los 68000 como Amiga y Atari, las maquinas de tipo MIPS y sobre PowerPC.

Linux es una implementaci6n de Unix. que respeta las especificaciones POSIX pero que posee tambien ciertas extensiones propias de las versiones System V y BSD de Unix, Esto simplifica la adaptaci6n del c6digo de aplieaciones desarrolladas inicialmente para otros sistemas Unix.

EI termino POSIX signifiea Portable Operating System Interface. Se trata de documentos producidos por el IEEE y estandarizados por el ANSI y el ISO. EI objetivo de POSIX es permitir tener un e6digo fuente transportable. La version Linux 2.0 respeta la norma POSIX.I y algunas lIamadas definidas por POSIX.4 (vease [Lewine 1991) y [Gallrneister 1995]).



EI de Linux es un c6digo original. que no es propietario en absoluto y cuyos programas en e6digo fuente se distribuyen Iibremente bajo cobertura de la licencia GPL. que es la licencia publica general GNU.

Las funcionalidades de este sistema operativo son multiples y corresponden a la idea que puede hacerse de un sistema Unix. modemo:

• multitarea, multiprocesador: puede ejecutar programas al mismo tiempo. ya sea con uno 0 varios procesadores;

• multiplataforma: vease mas arriba;

• multiusuario: como en todo sistema Unix, Linux permite trabajar a varios usuarios al mismo tiempo en la misma maquina;

• soporte de comunicaciones interprocesos (pipes.lPC. sockets);

• gesti6n de las diferentes sefiales;

• gesti6n de terminales segun la norma POSIX. Linux proporciona tambien los pseudoterminales y los controles de procesos;

..

r

.':

8

Programacion Linux 2.0

• soporte de un gran ndmero de dispositivos ampliamente extendidos (tarjetas de sonido, graficas, de red, SCSI ... );

• bufer cache: zona de memoria intermedia para las entradas/salidas de los diferentes procesos;

• gesti6n de memoria a la carta: una pagina s610 se carga si es necesaria en memoria;

• bibliotecas compartidas y dinarnicas: las bibliotecas dinarnicas s610 se cargan cuando son necesarias y su c6digo se comparte si varias ap1icaciones las utilizan;

• sistemas de archives que permiten gestionar tanto particiones Linux con el sistema de archivos Ext2, por ejemplo, como particiones en otros fonnatos (MS·DOS, is09660 ... );

• soporte de la capa TCPIIP y de otros pretocolos de red.

Linux es ante todo un sistema Unix rapido y completo, que puede instalarse facilmenteo Adernas, su difusi6n entre el gran publico Ie permite evolucionar rapidamente. Finalmente, algunas distribuciones permiten la facil insta1aci6n de este sistema, por 10 que Ie han permitido adquirir una cierta popularidad.

3 ,Gracias, Internet!

Si Linux es hoy tan popular se debe a que sus fuentes se han difundido por 1a red mundial Internet de manera libre y gratuita. Esta red ha borrado las distancias entre los desarrolladores, Los servicios de correo electr6nico han permitido a los desarrolladores dialogar facilmente y, ante todo, rapidamente. Las sedes ftp tambien han facilitado ' la difusi6n rapida de los fuentes y las herramientas de desarrollo.

En estos momentos, la comunicaci6n entre los desarrolladores se efecnia por medio de foros Usenet, pere especialmente por correo electr6nico. Asi, existen muchas listas de difusi6n de correo sabre temas variados respecto a ciertos ambitos del desarrollo de Linux.

Existen varias listas de desarrolladores que estan abiertas a todos. Tarnbien es posible discutir problemas encontrados, asf como aportar posibles extensiones, afiadir nuevas funcionalidades al micleo, y asf sucesivamente. Se preporcionan algunas direcciones electr6nicas en la proxima secci6n.

Linux: Introducci6n

9

4 Referencias

/

Presentamos una lista no exhaustiva de referencias y enlaces que el usuario y el desarrollador pueden consultar libremente: es rica en enseiianzas respecto a numerosos documentos .

. Libras de referenda

Se da una amplia bibliograffa al fin de esta obra, con la gran mayorfa de las obras de referencia existentes. Sin embargo. es necesario citar tres obras:

• la obra [Beck et al. 1996] en ingles que detalla el funcionamiento interne del mlc!eo ... pero de la version 1.2 de Linux;

, ellibro [Welsh and Kaufman 1995] que es la referencia en materia de iniciacion y administraci6n bajo Linux;

• finalmente, citemos [Kirch 1995] que es el libro de referenda respecto a la configuraci6n e instalaci6n de una red bajo Unix.

Foros Usenet

En Jengua inglesa:

• comp.os.linux.advocacy: ventajas de Linux respecto a otros sistema" operatives;

• comp.os.linux.announce: anuncios para la comunidad Linux (grupo moderado):

• comp.os.linux.answers: difusi6n de ciertos documentos como las FAQ (Frequently Asked Questions), HowTo's •... (grupo moderado);

• comp.os.linux.development.apps: escritura y portabilidad de aplicaciones bajo Linux;

• comp.os.linux.networking: Linux y la red;

• comp.os.linux.setup: instalaci6n y administraci6n del sistema;

• cornp.os.linux.x: X Windows bajo Linux;

• comp.os.linux.misc: todo 10 que no se trata en los otros grupos.

10

Programacion Linux 2.0

Listas de correo electr6nico

Existen numerosas listas de difusi6n respecto a Linux. Su multiplicaci6n impide establecer una lista complete, por 10 que presentamos las principales:

• 1 inux- kerne 1 ivger . ru tger s . edu: destinada a los desarro II adores ;

• 1 inux- see i ivger . ru tger s . edu: dedicada a los problemas y al desarrollo de controladores SCSI;

• 1 inux- gee ivger . ru tgers . edu: para todo 10 que respecta a la bi bl ioteca estandarC y gcc;

• linux-seeuri tyitarsier. ev. nrae. edu: lista que trata de problemas de seguridad;

• linux-alertitarsier. ev. nrao. edu: lista de difusi6n de mensajes de alerta.

Sedes FTP

Todas las herramientas necesarias parael eorrecto funcionamiento de Linux se agrupan en dos sedes principales:

• sunsite. une. edu: /pub/Linux;

• tsx-ll.mit. edu: /puh/linux.

Las actuaJizaciones de los micleos se efecnian en las sedes siguientes:

• ftp.cs.helsinki.£i:/pub/Software/Linux/Kernel;

• ftp.funet.fi:/puh/Linux/PEOPLE/Linus.

Sin embargo. existen numerosos espejos de estas sedes por todas partes. y es interesante buscar la mas cercana al lector.

Linux: Introducci6n

11

Sedes Web

A medida que Linux evoluciona, el mimero de sedes Web dedicadas a 61 no cesa de aumentar. Presentamos aquf las dos sedes principales a partir de las que son accesibles numerosas informaciones y enlaces a otras paginas:

• http://www .linux. org;

• http://www.cs.Helsinki.FI/linux/.

Las dos direcciones siguientes se encuentran en ingles y frances:

• http://www.freenix.fr/linux;

• http://www.loria.fr/linux.

Distribuciones

Linux es el micleo del sistema operativo. La instalaci6n en una maquina (can la recornpilaci6n de todas las herramientas) no es cosa reaJmente facil. Por esta raz6n. se difunden un cierto numero de distribuciones «llaves en mana». Se eneuentran en los principales servidores ftp, y se difunden tambien ampliamente en soportes como el CD-ROM a precios que desaffan toda competencia. Para referencia, aquf tiene algunas de las distribuciones corminmente difundidas:

• Red Hat: ftp: Ilftp.redhat.com/puh/redhat;

• Slackware: ftp. cdrom. com: Ipub/Linux/slackware;

• Debian: ftp. debian. org: Idebian;

• lurix:susix.jura.uni-sb.de:/pub/linux.

Estas distribuciones se agrupan en las sedes centrales Linux; 10 mismo puede decirsede los numerosos espejos de los que hemos hablado anteriormente.

Capitulo 2

Presentacion general

Este capftulo se dedica a presentar las caracterfsticas de un sistema de tipo Unix en genetal y de Linux en particular. No nos cansaremos de repetir que Linux es ante todo un sistema Unix, y por tanto hereda todas las caracterfsticas de este tipo de sistema operativo.

No cabe duda que, aunque se sabe bien el papel que juega una aplicaci6n, sigue flotando una nebulosa sabre el termino sistema opera/iva. Efectivamente, se emplea (demasiado) a menudo inadecuadamente. y sin embargo ocupa un lugar esencial en eualquier sistema. Este capftulo presenta la funci6n que debe cumplir un sistema operativo asf como su estructura y su funcionamiento. Posteriormente, entrando en mayor profundidad, se detallanin las nociones de modo micleo y usuario.

1 Los diferentes tipos de sistemas operativos

EI sistema operativo es un terminc generico que designa, en realidad, varias «familias» de sistemas:

• Sistemas monotarea: 5610 puede ejecutarse un programa a la vez. Por tanto, 5610 una persona puede trabajar a la vez en la maquina, Sin embargo, puede aprovechar todos los recursos y la potencia de la maquina,

• Sistemas multitarea: pueden ejecutarse varios procesos en paralelo. EI tiernpo se divide en pequeilas unidades y cada uno de los procesos se ejecuta durante ese intervalo. para que los procesos no se vean perjudicados, se implementa un complejo a1goritmo de ordenamiento y prioridad de ejecuci6n para asegurar un cierto reparto entre ellos, Estos sistemas pueden ser multiusuario 0 no. y multiprocesador.

14

Programaci6n Linux 2.0

Las primeras versiones de Unix para el gran publico eran sistemas multitarea y multiusuario. Pero actualmente, gracias al progreso de la tecnologta y la informatica, numerosos sistemas Unix son capaces ademas de utilizar las maquinas multiprocesador.

Las primeras versiones de Linux 5610 funcionaban sobre PC mono proce sador, pero la versi6n 2.0 ya pennite gestionar sistemas multiprocesador.

2 Funci6n del sistema operativo

El sistema Unix se ha desarrollado en un lenguaje de alto nivel (Ienguaje C). a diferend a de otros sistemas que se han desarrollado en ocasiones en lenguaje ensamblador. La utilizaci6n de un lenguaje de alto nivel ha permitido la portabilidad del sistema a muchas maquinas diferentes. Lo mismo ocurre con Linux, Por ella, era primordial que el c6digo de las aplicaciones pudiera compilarse de manera transparente (0 casi), sea cual sea la rnaquina y los dispositivos utilizados.

De hecho, el transporte de Linux a otra maquina se resume en adaptar la parte del c6digo que es especffica de 18 maquina. Los m6dulos independientes de 1a arquitectura pueden reutilizarse tal cual.

2.1 Maquina virtual

Un sistema operativo ofrece una nuiquina virtual al usuario y a los programas que ejecuta. Se ejecuta en una mAquina ffsica que posee una interfaz de programaci6n de bajo nivel, y proporciona abstracciones de alto nivel y una nueva interfaz de programaci6n y uso mas evolucionada.

En los primeros sistemas operativos que existfan en los anos cincuenta, el programador debra conocer la interfaz fisica de la maquina y programarla directamente. Un sistema modemo ofrece una interfaz de mas alto nivel y traduce las peticiones de alto nivel, efectuadas por el usuario, en peticiones fisicas de bajo nivel,

El sistema operativo es pues una interfaz entre las aplicaciones y la rnaquina, como se representa en la figura 2.1.

Par ello es por 10 que todas las tareas ffsicas (acceso a dispositivos extemos 0 internos, a la memoria ... ) se delegan en el sistema operative. Esta encapsulaci6n del hardware (y

Presentaci6n general

15

r>.
8 ' I
8 ~ -.;;rig I
-::
t
I
_J __ Sistema operativo

EJ

I

1--' -]

, Maq'

L ~:_

FIG. 2.1 - Entre las aplicaciones y fa mdquina

de su diversidad) libera a los desarrolladores de la complejidad de gestionar todos los dispositivos existentes: el sistema es quien se encarga de ello.

Bsto evita tambi~n que el usuario se limite a una maquina, Si el sistema esta disponible IObre varias arquitecturas, la interfaz de usuario y de programaci6n sera la misma en todas.

Cuando un desarrollador desea, por ejemplo, leer el contenido de un archive, efectda II misma operaci6n sin irnportar si el archivo esra en una cinta. en disco, en CD-ROM o en otto soporte, EI c6digo del prograrnador es el mismo, pero el ruicleo efecnia operaciones diferentes en funci6n del dispositive sobre el que se encuentre el archivo, Es m4s simple efectuar una apertura de archivo y lecturas de datos que leer ffsicamente bytes proporcionando una direcci6n ffsica formada por mimeros de disco, cilindro, cabeza de lecturalescritura y sector.

2.2 Compartir el procesador

Una de las caracterfsticas principales del sistema Unix es que es multitarea, es decir, 'que varios programas (procesos) pueden ejecutarse al mismo tiempo. Por ejemplo, el lanzamiento de una impresi6n. el formateo de un disquete, el envio 0 la recepci6n de eorreo electr6nico pueden realizarse at mismo tiempo.

Para elIo, el sistema implementa un sistema de ordenamiento, que se presenta en el capItulo 4. secci6n 1.8, y que tiene por objetivo distribuir el procesador entre los procesos, De hecho, si s610 hay un procesador, se ejecuta un solo programa en un momen-

16

Programaci6n Linux 2.0

to dado. Pero aI efectuar una rotaci6n muy rapida, el a los usuarios de la maquina tie-

o nen 18 impresi6n de que todos los procesos se ejecutan de manera paralela.

&ta gesti6n debe ser muy sofisticada para no perjudicar a nadie, y se (rata de uno de los mecanismos clave del sistema.

2.3 Gesti6n de la memoria

EI sistema se encarga de gestionar Ia memoria ffsica del ordenador. En efecto, en un entomo multiusuario y por tanto multitarea, el sistema debe efectuar una gesti6n muy rigurosa de 18 memoria. Como la memoria ffsica de la rnaquina es a menudo insuficiente, el sistema utiliza entonces una parte del disco duro como memoria virtual (area de intercambio a swap).

El sistema operative debe ser capaz de gestionar habilmente la memoria para poder satisfacer las peticiones de los distintos procesos tan deprisa como sea posible. Ademlis, debe asegurar 18 protecci6n de las zonas de memoria asignadas a los procesos para evitar las modificaciones no autorizadas.

La gesti6n de 18 memoria se expone en el capitulo 8.

2.4 Gesti6n de recursos

De manera general. el sistema operative se encarga de gestionar los recursos disponibles (entre los cuales el procesador y la memoria son casos particulares),

EI sistema ofrece a los procesos una interfaz que permite eompartir los recursos (discos, irnpresoras, etc.) de la maquina fisiea. Implementa un sistema de protecci6n que pennite a los usuarios y a los administtadores proteger el acceso a sus datos.

EI sistema mantiene listas de recursos disponibles y en eurso de utilizaei6n, 10 que Ie permite atribuirlos a los procesos que los necesiten. En todo momenta eonoce los procesos que utilizan los recursos de la maquina, y puede detectar asf los eontlietos de aceeso.

2.5 Centro de comunicaci6n de la maquina

Una de las tareas del sistema operativo es gestionar los diferentes eventos provenientes del hardware (interrupciones) 0 de las aplicaciones (llarnadas al sistema). Estos

1

'PresentaciOn general

17

eventos son importantes, y el sistema debe tratarlos y, llegado el caso, enviarlos a los procesos afectados.

Pero si el sistema operative debe ser capaz de responder a un even to. tambien debe ser capaz de comunicar varies procesos. De esta manera, los procesos podran comunicar entre sf, intercambiar informaciones. sineronizarse, etc. Unix pone a disposici6n del desarrollador varios mecanismos que van de las sefiales a los IPC, pasando por las tuberfas (pipes) y los sockets (que no se ttatan en este libro).

Bs por ello por 10 que el ndcleo es el centro de comunicaci6n de la maquina, Cuando dos procesos intercambian datos, es porque el sistema operativo impiementa mecanismos sofisticados junto con recursos especfficos.

3 Estructura general del sistema

, Bt sistema operative tal como se ha presentado se compone de varios elementos. Unix , y Linux en particular son sistemas bastante importantes, su desarrollo se ha realizado de manera modular de modo que se puedan distinguir facilmente las diferentes partes que los componen.

"La ventaja de esta estructuraci6n, aparte del hecho que puede estudiarse facilmente, es " que permite su modificaci6n y mejora sin excesiva dificultad. La adici6n de ciertos elementos, como las I1amadas aI sistema. controladores de dispositivos u otros, es bastante simple y no obliga a redisefiar la estructura del sistema. Par esta raz6n. Unix, aun" que se disefi6 a fines de los sesenta, ha evolucionado y sigue en activo en nuestros dIas.

Los distintos elementos que encontramos en el n6cleo del sistema Unix son los siguienres:

• lIamadas al sistema: implementaci6n de operaciones que deben ejecutarse en modo mlcleo;

,. sistemas de archives: entradaslsaIidas de los dispositivos;

• bufer cache: memoria intermedia sofisticada para entradaslsalidas;

• controladores de dispositivos: gesti6n de bajo nivel de discos. tarjetas, impresoras ... ;

• gesti6n de la red: protocolos de comunicaci6n de red;

• interfaz con la maquina: c6digo (generalmente en ensamblador) de acceso de bajo nivel aI hardware;

18

Programaci6n Linux 2.0

• centro del m1cleo:

- gesti6n de procesos (creaci6n. duplicaci6n. destrucci6n ... );

- gestor de 6rdenes:

- seftales:

- m6dulos cargables (carga de ciertas partes del nacleo cuando se requieren);

- gesti6n de memoria (gesti6n de la memoria ffsica y de la memoria virtual).

La figura 2.2 representa la estructura del sistema operativo Unix asi como la interacci6n entre las diferentes partes que 10 componen. Este esquema ha sido adaptado ligeramente para Linux y difiere poco respecto a la estructura tradicional que se puede encontrar en [Bach 1993].

Este esquema evidencia la frontera que existe entre la maquina y las aplicaciones. Bajo Unix. no se trata de acceder directamente a la memoria ffsica de Ja rnaquina, a la tarjeta de vfdeo ni a cualquier otro dispositivo ffsico, Adernas, la separaci6n del nucleo en entidades distintas facilita su depuraci6n y su desarrollo.

Finalmente. para acceder a las funcionalidades ofrecidas por el sistema operative, el sistema Unix pone a disposici6n de los procesos una interfaz de comunicaci6n Ilamada «l1amadas al sistema».

4 Modo micleo, modo usuario

4.1 Principia

Un proceso en un sistema Unix posee des niveles de ejecuci6n: nacleo y usuario,

EI modo micleo constituye un modo privilegiado: en este modo. no se impone ninguna restricci6n aI nncleo del sistema. Este ultimo puede utilizar todas las instrucciones del procesador, manipular toda la memoria y dialogar directamente con todos los controladores de dispositivos.

EI modo usuario es el modo de ejecuci6n normal de un proceso. En este modo, el proceso no posee ningun privilegio: ciertas instrucciones eshin prohibidas, s610 tiene acceso a las zonas que se Ie han asignado, y no puede interactuar con la maquina ffsica. Un

Presentaci6n general

19

Proceso
+
I
,
Interfaz de llamadas al sistema

Sistemas de archi vas Centro del mlcleo
ext2{. Aim. g~ti6n de procesos
proc:
miail!. 1If' IIIIdot I-- ~ rganizador
~fta1es
iJ09660 !M6dulos cargables
ra-esti6n de Ia memoru

.-J BMer cacM
~ .
Gestorcs de dispositivos L
Bloque I Oricter Gesti6n de red

milo cdrom ildn ipv4
ethernet
M:Ii pd RId , ..

Interfaz con la m;1quina
T
M";uina FIG. 2.2 - Estructura del sistema

proceso en modo usuario efecnia operaciones en su entorno, sin interferir con los denms procesos, y puede ser interrumpido en cualquier momento. Esto no obstaculiza so funcionamiento.

4.2 Llamadas al sistema

Un proceso que se ejecute en modo usuario no puede acceder directamente a los recursos de la maquina. Para ello, debe efectuar llamadas at sistema.

20

Programaci6n Linux 2.0

Una Hamada aI sistema es una petici6n transrnitida por un proceso al micleo, Este ultimo trata la petici6n en modo micleo, con todos los privilegios, y envfa el resultado aI proceso, que prosigue su ejecuci6n.

Bajo Unix, la lIamada aI sistema provoca un cambio: el proceso ejecuta una instrucci6n del procesador que Ie haec pasar aI modo ruicleo. Seguidamente ejecuta una funci6n de tratamiento vinculada a la lIamada aJ sistema que ha efectuado, y luego vuelve al modo usuario para proseguir su ejecuci6n. De este modo. el propio proceso trata su Hamada aI sistema. ejecutando una funci6n del nucleo. Esta funci6n se supone que es fiable y puede ejecutarse pues en modo privilegiado, contrariamente al programa ejecutado por el proceso en modo usuario.

, , ..

f !

io°·

1

;

[

Capitulo 3

Desarrollo bajo Linux

Este cap!tulo es~ destinado a presentar las diferentes herramientas de desarrollo, as! como las ~cnicas utilizadas bajo Linux, Linux es el nucleo del sistema operativo, y va acoropaftado por toda una serie de herramientas destinadas a los desarrolladores. La caracterfstica comun a todos estos productos es que son gratuitos, disponibles para su descarga en la mayorfade sedes ftpdel planeta, como el propio sistema. A pesar de ser de Iibre distribuci6n, estos productos son generalmente tan rapidos y potentes como los programas de desarrollo del comercio, 0 incluso mas,

En este capitulo se detalla la organizaci6n de los programas fuente del rnicleo. Tarnbien se introducen algunas nociones de programaci6n del sistema.

1 Los productos GNU

1.1 Presentaci6n

GNU son las iniciales de Gnu's Not Unix. La paIabra inglesa gnu designa el fiu (numerosos programas lie van nombres de animaIes: yace, bison ... ), una especie de bdfalo de Africa del Sur.

Se trata de un vasto proyecto iniciado por Richard Stallman (Ilamado nns) en 1983. Cuando se anunci6 este proyecto, RMS era el autor de un tratamiento de texto potente: emacs. Tras su entrada en ellaboratorio de inteligencia artificial del MIT, decidi6 el lanzamiento de un vasto proyecto orientado a reaIizar un sistema operative cuyo c6di-

22

Programaci6n Linux 2.0

go fuente se distribuirfa Iibremente, Sin embargo, el proyecto GNU se orient6 rapidamente hacia la realizaci6n de todas las herramientas que de ben acompafiar a un sistema asf, desde el compilador hasta el tratamiento de texto,

Pero Linux no es GNU, y no hay que confundirlos: Linux es el sistema operative, y algunas de estas herramientas de desarrollo provienen del proyecto GNU. Todas estas herramientas se difunden con una licencia particular de uso: la OPL. Gnu Public License. que corresponde a un CopyLeft (ja diferencia de un Copyright!). Esta licencia pennite difundir Iibremente el c6digo fuente, modificarlo, etc.

Es necesario precisar que el sistema operativo deseado por RMS no es Linux. Este sistema se esta de sarro II ando y lleva el nombre de Hurd (vease http://www . gnu. ai .mi t. edu/ para mas informaci6n).

1.2 Herramientas GNU

1.2.1 Presentad6n

La cantidad de herramientas GNU es muy importante: abarca desde compi I adores (gee, gnat ... ) a tratamiento de textos de prop6sito general (emacs) pasando por un editor de CUTvas (gnuplot) y juegos (nuehgess ... ). Se pueden encontrar productos GNU que cubren la mayor parte de los arnbitos, tanto para desarrolladores como para el usuario final. Estas herramientas son generalmente de buena caJidad y bastante potentes, Se incluyen en la mayorfa de distribuciones Linux y se difunden a menudo con el c6digo fuente.

Estas herramientas se difunden ampliamente en las distintas sedes ftp (consulte la sede principal de las herrarnientas GNU: prep. ai .mi t. edu). Gracias a la difusi6n del c6digo fuente, estas herramientas se corrigen, se mejoran y optimizan con las diferentes actuaIizaciones. Para estar al corriente de estas actualizaciones, basta con abonarse al foro Usenet gnu.announce que difunde estos anuncios.

Una herramienta en particular ha marcado a Linux: el compilador gee.

1.2.2 gee

Como todo sistema operativo de tipo Unix, Linux esta impiementado en lenguaje C, y ha sido necesario desde el principio de su desarrollo disponer de un compilador C. El programa gee, de GNU C Compiler. fue el primer compilador C que permiti6 la gene-

."

Desarrollo bajo Linux

23

raci6n de c6digo para Linux. gee se considera como uno de los rnejores productos GNU existentes. Hay que observar que existe un documento particular ([Barlow 1996]) que proporciona ciertos detalles respecto a- Linux y gee.

EI compilador gee se considera generalmente como uno de los compiladores mas poten~. Ademas de ser eficaz en terminos de rapidez, de c6digo generado y de opti mizacion, soporta todos los est4ndares de programaci6n en C. tanto el ANSI como la forma llamada K&R (Kernighan y Ritchie), u otras extensiones dellenguaje C. Para mas detalles respecto a las formas dellenguaje C, consulte [Kernighan and Ritchie 1992].

gee es tambi~n un compilador de C++. que gestiona practicarnente todas las caracterlsticas de la 1lltima versi6n del lenguaje (3.0) definida por Margaret Ellis y 8jame Sb'oUstrup en [Ellis and Stroustrup 1990]. Gestiona por ejemplo las plantillas (templates), las excepciones, la herencia mdldple ...

Finatmente, gce permite compilar tambi~n un Jenguaje bastante particular: Objective C. Se trata de un tenguaje orientado a objetos que no ha gozado de la misma difusi6n que C++ (fue ellenguaje elegido para el sistema operativo NextStep).

2 Las herramientas del desarrollador

Para un desarrollador, el cornpilador, el enlazador y eJ depurador son vitales, EI compilador le indica si hay errores de sintaxis en su codigo y el enlazador resuel ve los diferentes sfmbolos.

Sin embargo. no basta con que un programa pase can exito la etapa de la compilaci6n para que funcione. Aquf es donde entra en juego el depurador, que permitini ejecutar paso a paso la aplicaci6n deseada.

2.1 Las diferentes fases de la compilacien

La fase de compilaci6n que empieza con un c6digo en C y produce un c6digo ejecutable es de heche el resultado de un cierto ndmero de acciones. EI objetivo de este libro no es detallar con precisi6n 10 que ocurre desde el punto de vista del amilisis sintactico.l~xico 0 serruintico. Algunas obras especializadas en este ambito como [Aho et al, 1991] detallan todo el funcionamiento de un compilador. Por esta razon, s610 se presenta el funcionamiento de las herramientas a disposici6n del desarroll ado r.

24

Programacion Linux 2.0

C6digo fucnte C original

ejemplo.c

Prepux:esador

cpp

Compilador eel

Propama C completo

Propama en ensamblador ejemplo.s

Ensamblador as

OSdigo objeto ejemplo.o

Erdamcjor Id

~e a.out

FIG. 3.1 - Desarrollo de una compilaci6n

EI desarrollo de una compilacion, como se puede constatar en la figura 3.1, esta constituido por una multitud de etapas:

• EI c6digo C se envfa a traves de un preprocesador que efecnia la inclusion de archivos de cabecera asf como el reemplazo de las diferentes macroinstrucciones definidas. EI programa cpp es quien se encarga de esta operaci6n.

• Se efecttia la compilaci6n efectiva del c6digo para generar un c6digo ensamblador.

EI compilador no 5610 convierte el c6digo, sino que rea1iza un buen mirnero de optimizaciones. Esta operaci6n la realiza el programa cc I.

Desarrollo bajo Linux

• La operaci6n de ensamblado efectuada por el programa as consiste en generar el archive objeto asociado,

• Finalmente, la 6ltima operaci6n consiste en generar el ejecutable propi amente dicho del programa. Se trata de reunir todos los archives objeto y efectuar el enlazado. Esta aperaci6n compleja la realiza el prograrna ld.

B1 apendice A presenta las diferentes etapas de la compiiaci6n de un programa en C.

2.2 gee

BI mandata gee permite encadenar las diferentes fases de la compilaci6n de un pro'jrama. Se trata de un lanzador de programas que ejecuta las diferentes etapas (preproeesador, compilaci6n, ensamblado y enlazado) transmitiendo a los prograrnas las ,opc:iones proporcionadas par el programador.

'La opci6n -v permite visualizar los diferentes programas lanzados par gee:

1ft gcc -v exemple.c

,ding spec. from lusr/lib/gcc-lib-i486-1inuxI2.7.2Ispecs c _raion 2.7.2

Ulr/lib/gcc-lib/i486-1inux/2.7.2/cpp -lang-c -v -undef -D __ GNUC __ =2 -D_GNUC_MlNUR_=7 -O_ELF _ -Dunix -oi386 -Dlinux -D __ ELF __ -D __ unlx_ D __ i386 __ -O_linux__ -D_unix -0_1386 -O_linux -As, '~em(unix) 'Aay.tem(posixl ~AcpU{i386) -Amachine(i386) -0_i486 __ exemple.c tmp/cca01212. i

Cpp version 2.7.2 (i386 Linux/ELF)

starts here, starts here,

IUlr/local/include

"Jun I i48 6 -1 inuxl inc lude

, IUlr/lib/gcc-lib/i486-1inuxI2.7.2/include IUlr/ include

h of search list.

:lulr/llb/gcc-lib/ 1486-1 inux/2. 7. 2/ccl 1t.mp/cca01212. i -quiet ~dumpbase le.c -version -0 /tmp/ccaOI212.s

eversion 2.7.2 (i386 Linux/ELP) compiled by GNU eversion 2.7.2

luar/i486-linuxJbin/as -v -Qy -0 /tmpJcca)12121.o /tmp/cca01212.s a.sembler version 960228 (i486-1inux), using BFO version 2.6.0.12

··'Ulr/U86-1inux/bin/ld -Ifl el f_i386 -dvnalIIic-linker / lib/ld-linux. so. 1 r/lib/crtl.o /uarJlib/crti.o lusr/lib/crtbegin.o L/uar/lib/gcc-libJi486-1inux/2.7.2 ~L/usr/i486-1inux/1ib /tmp/cca012121.0 locc -lc -lgcc lusrJlibJcrtend.o lusrJlib/crtn.o

25

26

Programaci6n Linux 2.0

Ademas de las diferentes opciones definidas de modo predeterminado (como _lima_), se puede observar que se indican todos los mirneros de versi6n de las diferentes herramientas, 10 cual es muy practice cuando el administrador desea actualizar el entomo de la maquina,

Como indica la primera linea que sigue a la lIamada a gee -v, el compilador recupera las opciones predeterminadas en el archive /usr//ib/gcc-Lih/i486-lilluxl2. 7.2/specs. EI camino de acceso es variable segdn la versi6n del compilador y de la instalaci6n efectuada. En algunos casos, puede ser interesante modificar ciertas opciones 0 integrar otras, a fin por ejemplo de especializar el compilador para su procesador.

Veamos un pequeiio resumen de las principales opciones que pueden pasarse directamente a gee:

• -M: parada tras la etapa del preprocesador;

• -8: parada tras la generaci6n del c6digo ensamblador;

• -c: parada tras la generaci6n del c6digo objeto;

• -g: inserci6n de los sfmbolos para la depuraci6n;

• -onomdest: nombre del archivo generado;

• -DMACRO: define la macroinstrucci6n;

• -DMACRO=valor: define Ia macroinstrucci6n y Ie da un valor:

• -IDIRECTORIO: directorio donde cpp debe ir a buscar los archivos de cabecera;

• -LDIRECTORIO: directorio donde ld debe ir a buscar las bibliotecas:

• -lbiblioteca: incluye Ja biblioteca para el enlazado;

• -pipe: encadenamiento de las diferentes opciones de compilaci6n sin utilizar archivos tempora1es. Esta opci6n acelera la compilaci6n perc requiere mas memoria.

• On: nivel de optimizaci6n (0 --+ 3).

EI mlmero de opciones de gee es enonne. Consulte la pagina de manual. 0 bien (Stallman 1995] para mas detaiJes.

i

~

Desarrollo bajo Linux

27

2.3 Depurador

Que un programa supere la compilaci6n con 6xito no significa que funcione. Por esta raz6n, una de las herramientas mils utilizadas es el depurador. Existen varios depuradares bajo Unix. Bajo Linux, el que se utiliza es gdb.

Para poder depurar un prograrna, es necesario que este ultimo se haya compilado con la opci6n - g, ya que un depurador requiere ciertas infonnaciones sobre el programa que no se incluyen en una compilaci6n normal. Resulta de ello un c6digo generado de tamafio mayor.

BJ campo de acci6n de gdb es muy amplio, y se proporciona un ejemplo de uso en el ap6ndice B. Se aconseja consultar [Stallman and Support 1994] para saber mas.

2.4 strace

BJ mandato strace pennite seguir las llamadas al sistema ejecutadas por un prograrna. Indica las prirnitivas llamadas, asf como sus parametres (traduciendo ciertos val ores por constantes simb6licas) y el c6digo de retorno que devuelven.

; Damos a continuaci6n un ejemplo de utilizaci6n del strace:

(0, ~096, READ WRITE, PRIVATE, 4294967295, 0) = Ox40006000 SYS_125 (OxOa048000, Ox7ce, Ox7, Ox8048000, Ox8048084} = 0

tat("/etc/ld. 8o.cache" , {deY 3 2 ina 14351 mode 0100644 nlink ~ uid 0 gid 0 be 3154 ... ») = 0

("/etc/ld.8o.cache", RDONLY) = 3

p(O, 3154, READ, SHARED, 3, 0) = Ox40007000

108e(3) " 0

("/usr/lib/libc.so.5.3.9", ROONLY) = -1 (No such file or directory ("/lib/1ibc.80.5.3.9·, RDONLY) = 3 (3,"\7fELF\1\1\1\0\0\0\0\0\0\O\0\O\3\0\3\O\1\0\O\0\fO\3\1\04\0\0\0" .. ,

096) = 4096

(0, 724992, , PRIVATB, 4294967295, 0) " Ox4000aOOo

(Ox40008000, 492382, RBAD I EXBC, PRIVATE I FIXED, 3, 0) = Ox40081000 (Ox40081000, 20304, READIWRITB, PRIVATBIFIXED, 3, Ox78000) " Ox40081000

p(Ox40086000, 204856, RBADIWRITB, PRIVATBIFIXED, 4294967295. 0) " Ox40086000 10se(3) = 0

S_12S(Ox40008000, Ox7835e, Ox7, Ox40008000, Ox7835e) = 0 p (Ox40007000, , 3154, ) = 0

S_125 (Ox8048000, Ox7ce, OxS, Ox8048000, Ox7ce) : 0

S_125 (Ox40008000, Ox7835e, Ox5, Ox40008000, Ox783Se) : 0 out of range: 136

ir(Bogu. sy8cal1: 107377(592) = 0 k(Ox8049918) ; Ox8049918 k(Ox804aOOO) = Ox804aOOO

htat(l. (dev 0 0 ino 3~430 IDOde 010600 nlink 1 uid 501 gid 100 size 0 ... 11 = 0

mmap(O. 4096, RBADIWRITB, PRIVATE, 4294967295. OJ ~ Ox40007000

write(1, 'Cha\_ne initial. : exeqlle \n Cha' ..• 68 Cadena inicial ejemplo

Cact.na duplicada : .jeaplo -> ejamplo

)-68

exit(1074283076) • ?

28

Programacion Linux 2.0

En el ejemplo anterior, el programa empieza por cargarse y seguidamente busca la biblioteca din4mica C. Tras un fracaso (la biblioteca no se encuentra en lust/lib), se carga la libc que se encuentra en /lib.

Las diferentes llamadas a mmap y a mprotect (SYS_12S) realizan las cargas del programa y de Ia biblioteca. Las dos Ilamadas brk corresponden ados asignaciones de memoria efectuadas en el programa.

Pinalmente, las llamadas a/stat y write corresponden a 1a escritura en la salida estandar del resultado de la operaci6n. EI programa tennina por una lIamacla a exit.

2.5 make

2~.1 ~D~6D

La herramienta mQ/ce facilita la compilaci6n de proyectos. Es una herramienta estandar instalada en todo sistema Unix. Este programa pennite efectuar una compilaci6n inteligente de prograrnas, en funci6n de los archives modificados que necesitan realmente ser recompilados.

Sin embargo, la sintaxis de los archives Makefile es relativamente compleja de escribir porque utiliza reglas de reescritura. Una muestra de las capacidades de esta herramienta se presenta en el apmdice C. Para mas detalles, se aconseja referirse a la pagina de manual de make, 0 a 18 documentaci6n de la version GNU [Stallman and McGrath 1995].

3 Formato de los ejecutables

Linux soporta dos fonnatos de programas ejecutables. EI primer formato binario utilizado por Linux foe eI fonnato lIamado a. out. Sin embargo. este formate era de uso poco practice para implementar bibliotecas dinarnicas, y ahora el formato binario utilizado es ELF.

Desarrollo bajo Linux

29

3.1 a.out: el ancestro

EI fonnato a.out (Assembler.OUTput) es el fonnato de las bibliotecas y ejecutables utilizado en las primeras versiones de Unix en general y de Linux en particular.

Existen diversas variantes de este fonnato (ZMAGIC. QMAGIC ... ). QMAGIC es el formato de los ejecutables que se parece alga a los antiguos binarios a.out (tarnbien conocidos como ZMAGIC), pero deja la primera pagina del programa libre. Ella permite recuperar mas f4cilmente las din:cciones no asignadas (como NULL) en el intervale 0-4096.

Los enlazadores anticuados s610 gestionan el fonnato ZMAGIC. mientras que los mu recientes gestionan los dos. Los dos tipos son, de todos modos, soportados par el nticleo,

Para saber si un programa es de formato a.out, basta can utilizar el mandato file:

gandalft file lusr/local/bin/karmit

lusr I local Ibinlkermi t : Linuxi 1386 demand-paged executable ('Zl<IJIGIC)

Si la cadena Linux/ i 3 8 6 aparece, el binario especificado esta en fonnato a.out. Asimismo, se precisa que se trata de un binario en fonnato ZMAGIC.

El fonnato de los binaries de tipo a.out se implementa en el archive fslbinfmt_aout.c. Sin embargo, la gesti6n de este formato s610 se conserva por razones historicas, Par ella no detallaremos so funcionamiento.

3.2 ELF

3.2.1 Bienvenida al mundo ELF

El nuevo fonnato de binarios para Linux es el fomato ELF (que no tiene nada que ver can el mundo de Talkien y sus anillos, aunque a primera vista algunas caracterfsticas parezcan extrafias, enigmaticas a magicas), ELF es la abreviatura de Executable and Linking Format. Este formato fue inicialmente disefiado y desarrollado por el USL (Unix System Laboratories), y es utilizado por los sistemas de tipo SVR4 y Solaris 2.x.

Dado que ELF es mucho mas flexible y manejable que el fonnato a.out, los desarrolIadores de Linux decidieron migrar hacia este formate en 1994. La tecnica de migraci6n se detalla en [Barlow 1995) y en [Dumas 1996).

...

30

Programaci6n Linux 2.0.

3.z.z ELF Y so formato

ELF se ha convertido en un fonnato extendido y muy utilizado (en varios sistemas Unix) porque es de manipulaci6n simple. Esta facilidad proviene de su estructura, EI formato ELF so detalla completarnente en [11S 1993].

EI fonnato ELF permite generar tres tipos de archives:

• archivo relocalizable (archive objeto);

• archivo ejecutable;

• archivo compartido (bibliotecas),

Secci6n I

Cabecera ELF

Thbl. de cabecera del programa (opci6n)

Secci6n 2

Secci6n n

Secci6n de tabla de cabecera

FIG 3.2 - Formato ELF: estructura

En todos los casos, el formate del archivo es el mismo, como 10 ilustra la Figura 3.2.

La cabecera del archivo ELF constituye una descripci6n del archive y describe su organizaci6n. Es la t\nica cosa que tiene una posicion fija en el formato de un archive ELF: las demas secciones pueden colocarse en cualquier lugar en el archive. Pero es posible acceder directamente a estos datos. EI archi vo de cabecera < elf. h> (en realidad, eJ archivo <linuxlelf.h> es quien contiene los datos) contiene la declaraci6n de la estructufa de cabecera de un archivo ELF. Se trata de la estructura Elf 32 Ehdr.

Desarrollo bajo Linux

31

ti1Jii campo aescripcion
unsigned char e_ident Numero magico del archive con
[EIJUDENTl ciertas indicaciones
E1£32_Ha1£ e_type Tipo del archive
E1£32_Hal£ e_machine Arquitectura del archivo
E1£32_Word e_version Versi6n del fonnato de archive
E1£32_Addr e_entry Oirecci6n virtual del punic de entrada
del programa
E1£32_0ff e_phoff Desplazamiento para encontrar la tabla
de cabecera del programa
E1£32_0ff e_shoff Deplazamiento para encontrar la sec-
ci6n de cabecera del program a
E1f32_Word e_flags Opciones particulares para el procesador
E1£32_Ha1£ e_ehsize Tamano de la cabecera en bytes
E1£32_Ha1£ e_phentsize Tamano de una entrada en la tabla de
cabecera del programa
E1£32_Ha1£ e_pbnurn Numero de entradas en la tabla de
entrada del programa
E1£32_Ha1£ e_shentsize Tamai'io de una cabecera de seccion
E1£32_ha1£ e_shunm Ndmero de entradas en la tabla de
secciones
E1f32_ha1£ e_shstrndx fndice de la tabla de secciones EI campo de identificaci6n, constituido por una tabla de bytes, es muy importante. Se puede descomponer de la forma siguiente:

IDosicion

funcion

BI_llAGO, J:I_DGtl numero rnagico BI_llAG2,J::r__IIAQ3

_I_CLASS

BI_DATA

BI_VDBIOItI .I_PAD

significado

Constituido por 4 bytes: Ox7 f ELF. Este ndmero magico esta constituido en realidad por cuatro macrodefiniciones:

BLrMAQO,BLFKAG1,ELFMAG2y BLrMAG3.

I ELF es un formate portable, por 10 que las

, direcciones del archive pueden cstar en fonna de 32 064 bits. Esie byte puede tener los valores ELFCLASSNOrm (invalido), BLJ'CLASS32 0 BLPCLASS64.

Detennina si se encuentra en un entorno de mayor 0 menor peso. Pueden darse los valores BLJ'DATANONE (invalido), BLl'DATA2LSB y BLrDATA2MSB. version de la cabecera Debe ser BV CURRENT.

Marea , Oa el inicio de los bytes no utilizados y

i asignados para extensiones futuras.

clase del arehivo

tipo de codificaci6n

32

Programacion Linux 2.0

A partir de esta cabecera, es posible acceder a las diferentes secciones del archivo, Su mimero y posici6n son completamente variables, en funci6n del compilador que ha generado el codigo, las opciones especificadas en la generaci6n del archive objeto, 0 simplemente dellenguaje en el que se haya escrito el c6digo fuente.

Sin embargo. explorar un archivo binario ELF a mana es una operaci6n que resulta en ocasiones oscura y compleja, Una biblioteca facilita los accesos a las in formaciones de un archivo ELF, proporcionando funciones de analisis. Para utilizar estas iiltimas, hay que incluir el archi vo < 1 ibe 1 f . h> Y afiadir la ope i6n -1 e 1 f en e len I azado.

4 Presentacion de las bibliotecas

4.1 Utili dad

Las bibliotecas constituyen una manera simple de agrupar varios archivos objeto, Existen dos tipos de bibliotecas:

• estaticas: en el enlazado, el c6digo de la biblioteca se integra al ejecutable;

• dinamicas: el c6digo de la biblioteca se carga en la ejecuci6n del programa.

Las bibliotecas dinamicas permiten una economfa de espacio en disco pero mas atin de ocupaci6n de memoria porque una biblioteca dinamica se carga una sola vez, y el c6digo puede ser cornpartido por todas las aplicaciones que la necesiten. Finalrnente, cuando una biblioteca dinamica se actualiza, no es necesario recornpilar las aplicaciones que la utilizan.

La biblioteca dinamica que se utiliza cotidianamente es la biblioteca en C. Todas las aplicaciones (salvo a1gunas excepciones) se enlazan dinarnicamente con la biblioteca C. EI programa ldd permite conocer la lista de bibliotecas enlazadas con una aplicaci6n:

i

gandalf# 1dd /usr/X386/bin/xv

libXext.so_6 => /usr/Xll/1ib/libXext.so.6.0 libxll.so.6 => /usr/Xl1/1ib/libxll.so.6.0 libm.so.5 => /lib/libm.so.5.0.5

libc.so.5 => /lib/libc.so.5.3.9

Desarrollo bajo Linux

33

4.2 Utilizaci6n de bibliotecas

La utilizaci6n de una biblioteca es muy simple: basta can especificar en el enlazado la biblioteca. Par ejemplo:

ganda1f# gcc -0 demo_comp1eja main.c -L/usr/local/compleja - comp1eja -1m

gandalf# Idd demo_compleja

libm.so.5 => Ilib/libm.so.5.0.5 libc.so.5 => Ilib/libc.so.5.3.9

EI resultado anterior corresponde al caso en que la biblioteca haya side generada de forma estatica, y no dinamica,

EI apendice D expone varias herramientas de gesti6n de bibliotecas.

5 Organizaci6n del c6digo fuente del micleo

5.1 Nucleo

Los programas fuente del mlc1eo Linux se instal an normalmente en el directorio /usr/src/linux.

Se organizan de manera jerarquica, como se puede ver en la figura 3.3. Cada directorio 0 subdirectorio se dedica a ciertas funcionalidades del micleo:

• Documentacion: un cierto numero de archives de documentaci6n respecto a 1a configuraci6n del micleo 0 e) funcionamiento de ciertos m6dulos;

• include: todos los archives de cabecera necesarios para la generaci6n del micleo pero tambien para la compilaci6n de aplicaciones;

• Is: sistemas de archivos;

• init: el main.c de Linux:

• ipc: gesti6n de las comunicaciones interprocesos segun la norma System V;

• mm: gesti6n de la memoria;

• kernel: principales Ilamadas al sistema;

34

Programacion Linux 2.0

• lib: m6dulos diversos;

• drivers: controladores de dispositivos;

• net: protocolos de red;

• arch: c6digo dependiente de la plataforma;

• scripts: scripts utilizados para Ja configuraci6n y para la generaci6n de las dependencias del nucleo,

5.2 Archivos de cabecera

Los archives de cabecera utiJizados por el preprocesador del lenguaje C (como <s tdio. h> por ejemplo) se sinian en el directorio /usr/include, Definen la interfaz de las bibliotecas utilizadas por los programas que se compilan.

Estos archivos de cabecera se enlazan con la biblioteca C, que se distribuye independientemente del mleleo.

EI micleo Linux dispone tambien de archives de cabecera que se utilizan en su compilaci6n. Estos archivos se sinian en el directorio /usr/src/linux/include. Encontramos principalmente dos subdirectorios:

• linux: este directorio contiene las declaraciones independientes de la arquitectura;

• asm: este directorio contiene las declaraciones dependientes de la arquitectura: se trata de un enlace con otro directorio (asm-i386 para la arquitectura x86 par ejemplo).

Dos enlaces simb6licos permiten tambien acceder a estos archives desde el directorio /usr/include. Tambien es posibJe incluir en un programa archivos de cabecera que definen constantes y tipos utilizados por el micleo utilizando las notaciones <asm/ file. h> y <linux/ file. h>. Hay que observar, sin embargo, que no es aconsejable la inelusi6n de tales archi vas. Es preferible i nelu it los arch i vos estandar de la biblioteca C, porque estan previstos para ello. Estos archives de cabecera se encargan de importar las definiciones del mlcJeo.

En los capftulos siguientes, la descripci6n de lIamadas al sistema de Linux presenta los archivos de cabecera estandar, que se pueden encontrar en todo sistema Unix. Ciertas definiciones de constantes y de tipos se efecnian en los archivos de cabecera del micleo, pero estos ultimos no se detail an en las primeras partes de cada capitulo, por razones de portabilidad.

Desarrollo bajo Linux

35

n..,._
..... l ::--1
IIDlWOrtioa: boo!
...,
Qdlam nun
0.... ek, "'po
iD rnaIII~u
i386
lib
nil PI'"
kemeI
I ..... I IIIIiIIl
IIlIIpII
mcI* u.... .........

- ......
III> _...,
111Inm.2.0 r- -nB6 1If •
- ....... -
--I" GI2
...... --we .....
_..., ~.
I.., .. la.
.... .... .
r. IIIIdoI
..... ..".
.. .r •
8O'Z
IIfIFIeIaIk ..-
"'1 .. III'.
a,25
IJ"
--
11m .. .......
........
m.
Ipo4 uti
II-
-
IIIIl
--
bkx:k
IIIidfe ..... I~ I

...
-
pc:
- I leo I
I
- "I .. I ...
.... pcbil
FlG. 3.3 - Arbol de fuentes

Por el contrario, el contenido de los archives de cabecera del micleo se describe en la explicaci6n del funcionarniento de las diversas partes del micleo.

36

Programacion Linux 2.0

6 Funcionamiento del micleo

6.1 Llamadas al sistema

Como se explica en el capftulo 2. seccion 4.1, un proceso se ejecuta normal mente en modo usuario y debe pasar al modo micleo para ejecutar las llamadas al sistema.

6.1.1 Implementaci6n de una lIamada al sistema

Una Hamada at sistema se caracteriza par un nombre y un rnirnero unico que la identifica. Este ruimero puede encontrarse en el arch i vo < a sm / un is t d . h >. Por ejemplo, la Hamada aJ sistema open tiene el mimero 5. El nombre se define en cl archive ensamblador archli3861kerneVenlry.S (aunque este archive se encuentra en un directorio dedicado a la arquitectura x86. existe para las otras arquitecturas), y se llama sys_open.

La biblioteca C proporciona funciones que permiten ejecutar una lIamada al sistema. Estas funciones afectan aJ nombre de las Uamadas al sistema. Basta, pues, para ejecutar una Hamada aI sistema con lIamar ala funci6n correspondiente.

En los programas fuente del micleo, una lIamada al sistema posee el prototipo siguiente:

asm1inkage int sys_nom11amada(lista de argumentos) {

/* C6digo de 1a 11amada a1 sistema */ }

EI mimero de argurnentos debe estar comprendido entre 0 y 5. La palabra clave asm- 1 inkage es una macroinstrucci6n definida en el archive <1 inux/l inkage. h>:

#ifdef __ cplusplus

#define asmlinkage extern ~C~ #else

#define asmlinkage #endif

Cuando un proceso ejecuta una lIamada al sistema. llama a la funci6n eorrespondiente de 1a biblioteca C. Esta funci6n trata los parametres y haee pasar al proceso al modo micleo.

Desarrollo bajo Linux

37

En la arquitectura x86, este paso al modo micleo se efecnia de 1a forma siguiente:

• los parametres de la lIamada al sistema se colocan en ciertos registros del procesador;

• se provoca un bloqueo desencadenando 1a intenupci6n 16gica 0x.80:

• este bJoqueo provoca el paso deJ proceso al modo micleo: el proceso ejecuta 1a funci6n system_call definida en el archive Fuente archii386lkernel/entry.S;

• esta funci6n utiliza eJ mimero de Hamada al sistema (transrnitido en el registro eax) como Indice en la tabla sys_call_table, que contiene las direcciones de las lIamadas al sistema, y llama ala funci6n del micleo correspondiente a la lIamada al sistema:

• aJ volver de esta funci6n, system_call vuelve a quien ha llamado: este retorno vuelve a pasar al proceso al modo usuario,

6.1.2 Creaci6n de una 118mada aI sistema

Para comprender bien el funcionamiento de una Hamada al sistema, nada mejor que crear una. La Hamada al sistema que varnos a crear consiste en tomar tres argumentos. hacer la multiplicaci6n de los dos primeros y colocar el resultado en el tercero.

En un primer memento, es necesario «declarar» la Hamada a1 sistema, y por tanto asignarle un mirnero. La version 2.0 de Linux cuenta con 164 llarnadas al sistema. La lIamada al sistema show _mult tendra pues como mimero el 164 (Ia pri mera Ilamada al sistema, setup, tiene por mirnero 0). Para declarar nuestra lIamada, hay que afiadir en eJ archivo lnclude/asm/unistd.h:

/* Llamadas al sistema del nucleo *1 #define __ NR_sched_get_priority_min 160 #define __ NR_sched_rr_get_interval 161 #define __ NR_nanosleep 162

#define __ NR_mremap 163

1* Llamada al sistema afiadida */ #define __ NR_show~lt 164

.Seguidamente, en eJ archivo archii3861kemellentry.S (0 bien en el archivo entry.S de 1a arquitectura):

/* Llamadas a1 sistema del nucleo */

.long SYMBOL_NAME(sys_sched_get_priority_min) /* 160 */

38

Programaci6n Linux 2.0

.long SYMBOL_NAME(sys_scheq_rr_get_interval) .long SYMBOL_NAME(sys_nanosleep)

.long SYMBOL~(sys~emap)

/* Valor inicial del nlirnero de llamadas */ /* .space (NR_syscalls-163)*4 */

/* Llamada al sistema aBadida */ .long SYMBOL_NAME(sys_show_mult) .space (NR_syscalls-164)*4

En este estado, se efecn1an todos los enlaces que permiten 1a utilizaci6n de la lIamada al sistema. No queda mas que implementarlo. EI c6digo de la Ilamada al sistema puede estar integrado en el archive kemel/sys.c que agrupa un cierto m1mero de Ilamadas a1 sistema. EI c6digo a af'iadir es el siguiente:

asmlinkage int sys_show_mult(int x, int y, int *res) (

int error; int compute;

/* Verificaci6n de la validez de 1a variable res */ error: verify_area(VERIFY_WRITE, res, sizeof(*res)); if (error)

return error;

/* ca1culo del valor */ compute : x*y;

/* Copia el resultado en 1a memoria de usuario *( put_user(compute, res);

printf(~Value computed: %d x %d

%d \nW, x, y, compute):

/* Llamada terminada */ return o.

}

Una vez recompiJado eJ micleo y reiniciada la maquina, es posible probar la Hamada al sistema recien implementada. Para poder utilizar esta Hamada al sistema. es necesario declarar una funci6n que ejecuta esta lIamada al sistema. Esta funci6n no existe en la biblioteca C, y hay que declararla expllcitamente, Varias macroinstrucciones que permiten definir este tipo de funciones se declaran en el archive de cabecera <syscall. h>. En el caso de una II am ada al sistema que acepta tres parametres, hay que utilizar 1a macroinstrucci6n _syscaI13:

Desarrollo bajo Linux

39

#include <stdio.h> #include <stdlib.h> #include <linux/unistd.h>

_syscal13 (int, show~u1t, int, x, int, y, int *resul);

main () {

int ret = 0;

show mult (2, 5, &ret);

printf (-Resultado %d %d = %d \n-, 2, 5, ret);

}

La macroinstrucci6n _syscal13 es expandida por el preprocesador y proporciona el c6digo siguiente:

int show~ult(int x, int y, int *resu1} {

long _res;

_as~ __ volatile (-int $OxBO~ : "=a" ( __ res)

: "0· (164 ),

"b" ((long) ( x )}, "c" ((long) ( y I},

"d" ((long) ( resul n i. if (_res>=O)

return ( int ) _res: errno=_res;

return -1;

} ;

La funci6n show_mult es generada por _syscal13. que iniciaJiza los registros del procesador (el numero de la Hamada at sistema se coloca en el registro eax y los parametros se colocan en los registros ebx, ecx y edx), y seguidamente desencadena la interrupci6n oxeo. De vuelta de esta interrupci6n. es decir, al volver de la lIamada al sistema. el valor de retorno se comprueba. Si es positive 0 nulo, se devuelve a quien llama. En caso contrario, este valor contiene eI c6digo de error devuelto; entonces se guarda en la variable global errno y se devuelve el valor -1 .

6.1.3 C6digos de retorno

EI ruicleo puede detectar errores en la ejecuci6n de una Hamada al sistema. En ese caso, se devuelve un c6digo de error al proceso que hace la lIamada.

40

Programacion Linux 2.0

Generalmente, se devuelve el valor -1 en caso de error. Este valor indica unicamente que se ha producido un error. A fin de pennitir al proceso que ha llamado detenninar la causa del error.Ia biblioteca C proporciona una variable globaillamada errno. Esta variable se actualiza tras cada Ilamada al sistema que cause un error, y contiene un c6digo que indica la causa del error. No se actualiza tras una Hamada al sistema con exito, par 10 que hay que comprobar el valor de retorno de cada llamada al sistema y utilizar el valor de errno s610 en caso de fallo,

EI archivo de cabecera <errno. h> define numerosas constantes que representan los posibles errores. En los capftulos siguientes, se detalla en la presemaci6n de las llamadas al sistema la lista de c6digos de error que pueden ser devueltos.

La biblioteca C proporciona tambien las dos variables siguientes:

extern int _sys_perr;

extern char *_sys_errlistl];

La variable _sys_nerr contiene el mimero de c6digos de error implementados. La tabla _sys_errlist contiene las cadenas de caracteres que describen todos los errores. EI mensaje de error correspondiente al ultimo error detectado puede obtenerse pues par media de _sys_errlist [errno).

Ademas, la biblioteca C proporciona dos funciones:

#include <stdio.h> #inclue <errno.h>

void perror (const char *s);

char *strerror (int errnum);

La funci6n perror muestra un mensaje en la salida de errores del proceso que llama. Este mensaje contiene la cadena especificada por el parametro s y el mensaje de error correspondiente al valor de errno. La funci6n strerror devuelve la cadena de caracteres correspondiente aI error cuyo codigo se especifica en el pararnetro errnum.

6.2 Funciones de utilidad

EI rnicleo contiene numerosas funciones de utilidad que hay que presentar ya ahora. Aunque estas funciones sean descritas en capftulos ulteriores. es necesarie conocer su funcionamiento para comprender la descripci6n de las funciones internas.

Desarrollo bajo Linux

41

6.2.1 Manipulaci6n de espacio de direccionamiento

EI espacio de direccionamiento de un proceso en modo ruicleo es diferente de su espacio de direccionamiento en modo usuario. Le resulta par tanto imposible aeceder directamente a los datos cuya direcei6n se ha pasado como parametro a una Hamada al sistema.

Linux proporciona varias funciones para acceder a estos datos:

int verify_area (int type, const void -addr, unsigned long size);

void put_user (unsigned long value, void -a.ddr); unsigned long get_user (void *addr);

void memcpy_tofs (void *to, const void -from, unsigned long size); void memcpy_fromfs (void -to, const void ·from, unsigned long size);

La funci6n ver i fy _area veri fica que la direcci6n pasada (pararnetro addr) es vAlida. EI parametro size representa el mirnero de bytes de la zona. y tipe especifica el tipo de la verificaci6n. Este panimetro puede tomar el valor VERIFY_READ para verificar que la zona de memoria es accesible para lectura 0 VERIFY_WRITE para escritura.

La funei6n put_user escribe el valor especificado por el pararnetro value en el espacio de direccionamiento del proceso que llama. en la direcci6n especificada por el parametro addr. La funci6n get_user devuelve el valor situado en la direcci6n pasada en el pararnetro addr, en el espacio de direccionamiento del proceso que llama.

La funci6n rnemcpy_tofs copia datos desde el espacio de direccionarniento del micleo bacia el espacio de direecionamiento del proceso que llama. EI parametro to contiene la direcci6n en el espacio de direccionamiento del proceso. from contiene la direcci6n en el espacio de direccionamiento del ruicleo y size especifica el mimero de bytes a copiar. La funci6n rnerncpy_fromfs efecnia 1a copia de datos desde el espacio de direccionamiento del proceso que llama hacia el espacio de direeeionamiento del micleo.

Estas funciones se detallan en el capitulo 8, secci6n 6.5.

6.2.2 Asignaciones y liberaciones

Se proporcionan varias funciones de asignaci6n dinamica y liberacion de memoria para las necesidades intemas del micleo:

42

Programacion Linux 2.0

void *kmalloc (unsigned int size, int priority); void kfree (void *addr);

void *vmalloc (unsigned long size); void vfree (void *addrl;

La funci6n malloe asigna una zona de memoria cuyo tarnafio se especifica por el panimetro size, y devuelve la direcci6n de la zona asignada. En caso de fracaso, se devuelve eJ valor NULL. EI panbnetro priori ty especifica el tipo de la asignaci6n:

constante siRnijicado
Asignaci6n de memoria para el bufer cache.
Ql'p_BUfla
Ql'P _A'l'OIIIC Asignaci6n de memoria para un gestor de interrupciones.
Ql'P_O_ Asignaci6n de memoria para un proceso en modo usuario,
QI'P_KDDL Asignaci6n de memoria para el ruicleo.
CD'P_"'S Asignaci6n de memoria para el soporte del sistema de archivos NFS. La funci6n kfree libera una zona de memoria cuya direcci6n se pasa en el pararnetro addr. Esta direcci6n debe corresponder con un valor devuelto por krnalloe.

Las funciones vrnalloc y vfree impiementan tambien la asignaci6n y la liberaci6n de zonas de memoria, que son mas flexibles que kmalloc y kfree.

Estas funciones se detallan en el capitulo 8, secci6n 5.3.2.

Capitulo 4

Procesos

Primitivas detalladas--------------, _exit, clone, exit, rork, getegid, geteuid, getgid, getgroups, getpgid, getpgrp, getpid, getppid, getpriority, getrlimit, getrusage, getsid, getuid, nice, ptrace, sched_yleld, setegid, seteuid, setfsgid, setrsuid, setgid, setgroups, setpgid, setpgrp, setpriority, setregid, setreuld, setrlimit, setsid, setuid, times, wait, waitJ, wait4, waitpid

1 Conceptos basicos

1.1 N oci6n de proceso

De manera informal. puede considerarse como un programa en curso de ejecuci6n. Este progresa de manera secuencial: en todo momento, se ejecuta una instrucci6n como maximo de la serie del proceso.

Sin embargo, un proceso no se limita al programa que ejecuta, Tambien se caracteriza por su actividad puntual, representada por el valor del contador ordinal y los registros del procesador. Inc1uye una pita. que contiene datos temporaies, y un segmento de datos que contienen variables globales.

Un programa en sf mismo no es un proceso: un programa es una entidad pasiva (archivo ejecutable residente en un disco), mientras que un proceso es una entidad activa con un contador ordinal que especifica la instrucci6n siguiente a ejecutar y un conjunto de recursos asociados.

44

Programaci6n Linux 2.0

1.2 Estado de un proceso

En el transcurso de su ejecucion, un proceso cambia de estado. EI estado de un proceso se define por su actividad actual. Los diferentes estados posibles de un proceso son los siguientes:

• en ejecuci6n: el proceso es ejecutado por el procesador;

• a punto: el proceso podrfa ser ejecutado pero otto proceso se esta ejecutando en ese momenta;

• suspendido: el proceso est! en espera de un recurso: por ejemplo, espera el fin de una entrada/salida;

• parado: el proceso ha sido suspendido por una intervenci6n extema;

• zombi: el proceso ha terminado su ejecuci6n pero sigue siendo referenciado en el sistema.

Los cambios de estado de un proceso serepresentan en el grafo de estados, figura 4.1.

Fin de: e:ntrada/sali

Finalizaci6n

FIG. 4.1 - Grafo de est ados de Wl proceso

Procesos

45

1.3 Atributos de un proceso

Durante su ejecuci6n, un proceso se caracteriza por varios atributos mantenidos por el sistema:

• su estado;

• su identificador (numero -unico);

• el valor de los registros, incluyendo el contador ordinal;

• la identidad del usuario bajo

cuyo nombre se ejecuta:

• las informaciones utilizadas por el micleo para proceder al ordenamiento de los procesos (prioridad ... );

• las in formaciones respecto al espacio de direccionamiento del proceso (segmentos de codigo, de datos, de pita);

• las informaciones respecto a las entradaslsalidas efectuadas por el proceso (descriptores de archivos abiertos, directorio actual ... );

• infonnaciones de contabilidad que resumen los recursos utilizados por el proceso.

1.4 Identificadores de un proceso

A un proceso se le asocian varios identificadores de usuarios y de grupos:

• el identificador de usuario real: es el identificador del usuario que ha lanzado el proceso;

• el identificador de usuario efectivo: es el identificador que utiliza el sistema para los controles de acceso; puede ser distinto del iclentificador de usuario real, por ejemplo en el caso de programas que poseen el bit setuid;

• el identificador de grupo real: es el identificador de grupo primario del usuario que ha lanzado el proceso;

• el identificador de grupo efectivo: es el identificador que utiliza el sistema para los controles de acceso; puede ser diferente del identificador de grupo real, por ejemplo en el caso de programas que poseen el bit setgid;

46

Programacwn Linux 2.0

• una lista de identificadores de grupos: todo usuario puede pertenecer a varios grupos de manera simultanea, y el nucleo mantiene una lista de grupos asociados a cada proceso a fin de proceder a los controles de acceso. Bajo Linux, un proceso puede poseer basta 32 grupos.

Linux mantiene tambi~n otros dos identificadores: el saved uid y el saved gid. Cuando un proceso modifica su identificador de usuario 0 de grupo efectivo, por una llamada Ii las primitivas setreuid 0 setregid, el micleo autoriza la modificaci6n en los casos siguientes:

• el proceso posee los privilegios de superusuario;

• el proceso especifica el mismo valor para el nuevo identificador;

• el nuevo identificador es igual al identificador guardado.

Estos identificadores guardados son particulannente 6tiles para un proceso que ejecute un programa que posee el bit setuid, resp. setgid, es decir, un proceso que posee identificadores de usuario, res. grupo, real Y efectivo diferentes. Este proceso puede utilizar las primitivas setuid, resp. setgid, y setreuid, resp. setregid, para anular sus privilegios, utilizando el identificador de usuario 0 de grupo real. efectuar un tratamiento que no necesita ningun privilegio particular, y luego restaurar su identificador de usuario 0 de gtupo efectivo.

1.5 Filiaci6n

La creaci6n de un proceso se efect6a duplicando el proceso actual: la llamada al sistema fork permite a un proceso crear una copia conforme a sf mismo, exceptuando el identificador de proceso. El proceso que se duplica se llama el proceso padre, y el nuevo proceso se llama el proceso hijo.

Cuando Linux arranca, crea el proceso mimero 1 que ejecuta el programa init, encargada de inicializar el sistema. Este proceso crea a su vez procesos para efectuar diferentes tareas, pudiendo estas a so vez crear nuevos procesos. El resultado es una jerarquia de procesos emparentados.

La figura 4.2 muestra unajerarqufa tfpica de procesos, mediante el mandato pstree.

1.6 Grupos de procesos

Linux mantiene grupos de procesos. Un grupo de procesos es un conjunto que contiene uno 0 mas procesos. Todo proceso forma parte de un grupo, y sus descendientes pertenecen en principio al mismo gtupo. Un proceso puede elegir crear un nuevo grupo y

Procesos

47

init(l) auto I-(agetty, 9700) 1-(agetty,9699) 1-(agetty,9698) 1-(agetty,71) l-cron(26)

l-innd(63) -p4 -iO -c360

, -overchan (72) - (kflushd, 2)

-(kswapd,3)

-selection(40) -t mac -c 1 -p m

-syslogd(36)

-(tcsh,9701)

'-(startx,9724)

'- (xinit, 9725) I-X(9726) :0 , -fvwm(9728)

I-FvwmPager(973S) 9 4 /hame/card/,fvwmrc 0 B 0 2 I-GoodStuff(9733) 7 4 /home/card/,fvwmrc 0 B 1-(xclock,9734)

l-xterm(9731) -geometry 80x50+20+50 I '-tcsh(9737)

'-xterm(9732) -geometry 80x20+530+70 '-(tcsh,9736)

'-bash (l0771)

-update (9)

-xterm (10311)

, -tcsh(10316) -xterm(10321)

, -tcsh(10328) -xterm(1032S) '-tcsh(10330)

, -vi (30664) " / Processus/ConceptsBase, tex '-tcsh(30716) -c pstree -a -c -p '-pstree(30720) -a -c -p

-xterm( 17889)

'-tcsh(17B93) I-make (30696)

I '-latex (30715) Livre,tex '-xdvi(2B449) Livre

I '-gs(28531) -sDEVICE=x11 -dNQPAUSE -q -

I-xterm (10788)

I '-tcsh (10791) '-xterm( 10790)

'-tcsh(10792)

FIG, 4,2 - Jerarquia tipica de procesos

convertirse asf en jefe (leader) del grupo. Un grupo se identifiea por su mimero de grupo, que es igual a1 mlmero de su proceso leader.

48

Programacion Linux 2.0

Esta noci6n de grupo permite enviar sefiales a todos los procesos miembros de un grupo (vease el capitulo 5, secci6n 2.1), a fin de implementar el job control. Los interpretes de mandatos (bash, csh; Icsh ..• ) utilizan estos grupos para permitir al usuario suspender la ejecuci6n de procesos y proseguirla, en primer plano 0 en segundo plano.

Los grupos de procesos se utilizan asimismo en la gesti6n de terminates (vease el capttulo 9, secci6n 2.6).

1.7 Sesiones

Una sesi6n es un conjunto que contiene uno 0 mas grupos de procesos. A cada sesi6n se le asocia un terminal de control dnico. Este terminal de control es 0 bien un dispositivo terminal (en una conexi6n a la consola), a bien un dispositivo pseudoterminal (en una conexi6n remota). Cuando un proceso crea una nueva sesi6n:

• se convierte en el proceso leader de la sesi6n;

• se crea un nuevo grupo de procesos y el proceso que llama se convierte en su leader;

• el proceso que llama no tiene terminal de control.

Una sesi6n se identifica por su numero, que es igual al numero de su proceso leader.

Generalmente. se crea una nueva sesi6n por parte del programa login en la conexi6n de un usuario. Todos los procesos creados forman parte de la misma sesi6n. En el caso de encadenamiento de mandatos (por medio de tuberias, por ejemplo), el interprete de mandatos (shell) crea nuevos grupos de procesos, para implementar eljob control.

1.8 Multiprogramaci6n

En un instante dado, bay un solo proceso en ejecuci6n (al menos en un ordenador monoprocesador). Este proceso se llama el proceso actual. El sistema mantiene una lista de procesos a punto que podria ejecutar y procede peri6dicamente a un ordenamiento.

A cada proceso se le atribuye un lapso de tiempo. Linux elige un proceso a ejecutar, y Ie deja ejecutarse durante esc lapso. Cuando ba transcurrido, el sistema hace pasar al proceso actual al estado a punto, y elige otro proceso que ejecuta durante otro lap so. EI lapso de tiempo es muy corte y el usuario tiene Ia impresi6n que varios procesos se ejecutan simultaneamente, aunque s610 un proceso se ejecuta en un instante dado. Se dice que los procesos se ejecutan en pseudoparalelismo.

Procesos

49

2 Llamadas al sistema de base

2.1 Creaci6n de procesos

EI proceso actual puede crear un proceso hijo utilizando la Hamada al sistema/ork. Esta primitiva provoca la duplicaci6n del proceso actual. Su prototipo es el siguiente:

.include <unistd.h>

pi~t fork (void);

En la Hamada a/ork. el proceso actual se duplica: se crea una copia que Ie es id6ntica. excepto en su identificador y el de so padre. AI volver/ork. dos procesos, el padre y el hijo, ejecutan el mismo c6digo.

La prirnitiva fork devuelve el valor 0 al proceso hijo, y devuelve el identificador del proceso creado al proceso padre. Es pues imperativo comprobar su valor de retorno para distinguir el c6digo que debe ser ejecutado por el proceso padre y el que debe ser ejecutado por el proceso hijo. En caso de fallo./ork devuelve el valor -I, y la variable errno puede tomar los valores siguientes:

error significado
IlAQA.IIIiI Se ha Uegado al mimero maximo de procesos del usuario actual 0 del sistema.
lDlOIIDI' E1 nueleo no ha podido asignar suficiente memoria para crear un nuevo proceso. EI programa siguiente itustra la llamada al sistema/ork para crear un proceso hijo.

*include <ermo. h> .include <stdio.h> .include <unistd.h>

void main (void) {

pid.....t

pid;

pid = fork (); if (pid == -1)

perror (. fork' ) ; else if (pid == 0)

printf ('soy el hijo: pid = td\n',pid);

else

pr int f (. soy el padre: pid = M\n', pid) ;

50

Programacion Linux 2.0

2.2 Finalizaci6n del proceso actual

EI proceso actual tennina automaticamente cuando deja de ejecutar la funci6n main, utilizando la instrucci6n return. Tambien dispone de llamadas at sistema que Ie permiten parar explfcitamente su ejecuci6n:

iinclude <unistd.h>

void _exit lint status);

void exit (int status):

Las primitivas _exit y exit provocan la finalizaci6n del proceso actual. EI parametro status especifica un c6digo de retorno, comprendido entre 0 y 255, que hay que comunicar at proceso padre. Por convenci6n, un proceso debe devolver el valor 0 en caso de finalizaci6n normal, y un valor no nulo en caso de finalizaci6n debida a un error.

Antes de tenninar la ejecuci6n del proceso, exit ejecuta las funciones eventual mente registradas por llamadas a las funciones de biblioteca atexit yon_exit.

Si el proceso actual posee procesos hijos, estos se vinculan al proceso m1mero I, que ejecuta el programa init. La seftal SIGCHLD se envfa al proceso padre para prevenirle de la finalizaci6n de uno de sus procesos hijos.

2.3 Espera de la finalizaci6n de un proceso hijo

Un proceso puede alcanzar la finalizaci6n de un proceso hijo mediante las primitivas wait y waitpid. Su sintaxis es la siguiente:

finclude <sys/types.h> iinclude <sys/wait.h>

pid_t wait (int *statusp):

pid_t waitpid (pid_t pid, int *statusp. int options):

La primitiva wait suspende la ejecuci6n del proceso actual hasta que acabe un proceso hijo. Si un proceso hijo ya ha terminado, wait devuelve el resultado inmediatamente.

La primiti va waitpid suspende la ejecuci6n del proceso actual hasta que un proceso hijo especificado por el parametro pid termine. Si un proceso hijo correspondiente a pid ha terminado ya, waitpid devuelve el resultado inmediatamente.

Procesos

51

EI resultado de waitpid depende del valor del parametro p i d:

• si pid es positive, especifica el mimero del proceso hijo a esperar;

• si pid es nulo, especifica todo proceso hijo cuyo mimero de grupo de procesos sea igual al del proceso que llama;

• si pid es igual a -I, especifica la espera de la finalizaci6n del primer proceso hijo: en este caso, waitpid ofrece la misma semantica que wait;

• si pid es inferior a -L especifica todo proceso hijo cuyo ruimero de grupo de procesos es igual aI valor absoluto de pid.

Dos constantes, declaradas en < sys / wa it>, pueden utilizarse para inicializar el parametro options. a fin de modificar el comportamiento de waitpid:

constante significado
WIIOBAIIO Provoca un error inmediato si no ha tenninado aun ningtin proeeso hijo.
wtm'l'RACBD Provoca 1a consideraci6n de los bijos cuyo estado cambia. es decir,
los procesos hijos euyo estado ha pasado de a punto a suspendido. Las dos primitivas devuelven el namero del proceso hijo que ha terminado, 0 el valor -1 en caso de fallo. EI estado del proceso hijo se devuelve en la variable cuya direcci6n se pasa en el parametro statusp.

La interpretaci6n de este estado se efecnia gracias a macroinstrucciones definidas en el archi vo de cabecera < sys / wa it. h>:

mac roinstruccion significado
w:IPBXITBD No nulo si el proceso hijo ha terminado por una Hamada a _exit 0 exit.
WBXITSTA'l"DS C6digo de retorno transmitido por el proceso hijo en su finalizacion,
WIFS IGHlU.BD No nulo si el proceso bijo ha sido interrumpido por la recepci6n de
una serial.
W'l'BlUISIQ Numero de sefial que ha provocado la finalizaci6n del proceso hijo.
w:IFS'1'OPPBD No nulo si el proceso hijo ha pasado del estado a punto a suspendido,
WSTOPSIQ Ndmero de seiia1 que ha causado la suspension del proceso hijo, Linux implementa tambien otras dos llamadas al sistema que aseguran una compatibilidad con los sistemas BSD Unix.

iinclude <sys/resource.h> .include <sys/types.h> iinclude <sys/wait.h>

piQ_t wait3 (int *statusp, int options, struct rusage *rusage);

52

Programaci6n Linux 2.0

pi<t_t waiU (pid,_t pid, int *8tatusp, int options, struct rusage *rusage);

Estas llamadas son relativamente parecidas a wait y waitpid. Aceptan un parametro suplementario, rusage, que apunta a una variable en la que se colocan las informaciones de compatibilidad del proceso. La estructura rusage. definida en el archivo de cabecera < sys Ire S ourc e . h>, contiene los campos siguientes:

tipo campo tkscripcwn
struct timeval ru_utime Tiempo de procesador consumido por el proceso
en modo usuario.
struct timeval ru_stime Tiempo de procesador consumido por el proceso
en modo ndcleo.
long ru_maxrss Tameo maximo del espacio de direccionamiento
del proceso residente en memoria, en kilobytes.
long ru_ixrss NOmero de kilobytes del espacio de
direccionamiento del proceso, compartidos con
otros procesos.
long ru_idrss NOmero de kilobytes del segmento de datos del
proceso, no compartidos con otros procesos.
long ru_isrss NOmero de kilobytes del segmento de pila del
proceso.
long ru_minflt N6mero de fallos de pagina provocados por el
proceso que se han resuelto sin lanzar una
entrada/salida.
long ru_majflt NOmero de fallos de pagina provocados por el
proceso que se ban resuelto lanzando una
entrada/salida.
long ru_nswap Numero de veces que el proceso ha sido
descartado de la memoria para ubicarlo en
memoria secundaria.
long ru_inblock Numero de veces que el sistema de archives ha
efectuado una lectura de datos para el proceso.
long ru_oublock Nt1mero de veces que el sistema de archives ha
efectuado una escritura de datos para el proceso.
long ru_msgsnd Numero de mensajes enviados por el proceso.
long ru_msgrcv Numero de mensajes recibidos por el proceso.
long ru_nsignals Nt1mero de sei\a1es recibidas por el proceso.
long ru_nvcsw Nt1mero de veces que el proceso ha abandon ado
voluntariamente el procesador (generalmente
para esperar la Ilcgada de un evento, como el fin
de una entrada/salida).
long ru_nivcsw Numero de veces que el proceso ha abandonado
el procesador porque habfa agotado.su porcion de
tiempo 0 porque un proceso mas prioritario entr6
en el estado a pun to. Procesos

53

La estructura timeval, utilizada para definir los campos ru_utime y ru_stime, es la siguiente:

tipo campo descripcwn
long tv_sec Segundos
long tv_usee Microsegundos La funci6n wait3 corresponde a la llamada at sistema wait4, a la que se pasa el valor -1 para el parametro pid.

En caso de fallo de estas primitivas, la variable errno puede tomar los val ores siguientes:

error siRnijicodo
BCBILD El proceso especificado por pid no existe,
D'AtJLT statusp 0 rusage connene una direccion invalida.
ZIN'l'R La llamada at sistema ha sido inlCrrurnpida por la recepcion de una seftal.
ZPBRIl EI proceso que llama no es privilegiado y su identificador de usuario
efeetivo no es igual at del proceso especificado por pid. 2.4 Lectura de los atributos del proceso actual

Un proceso cuenta con varias llamadas al sistema para obtener los atributos que Ie caracterizan :

tinclude <unistd.h>

piQ_t getpid (void);

piQ_t getppid (void);

uiQ_t getuid (void);

uiQ_t geteuid (void);

giQ_t getgid (void);

giQ_t getegid (void);

int getgroups (int size, giQ_t list[]);

getpid devuelve el identificador -unico del proceso actual, getppid devuelve el identificador dnico del padre del proceso actual.

54

Programaci6n Linux 2.0

getuid devuelve el identificador del usuario real del proceso, geteuid devuelve el identificador de usuario efectivo del proceso actual.

getgid devuelve el identificador de gropo real del proceso, getegid devuelve el identificador de grope efectivo del proceso actual.

Para terminar, getgroups permite obtener la lista de grupos asociados at proceso actual. Los identificadores de estos gropes se devuelven en el pararnetro list, y el parametro size especifica el tamano de la tabla list. getgroups devuelve el numero total de grupos asociados at proceso actual.

2.5 Modificaci6n de atributos

Un proceso puede, en ciertas circunstancias, modificar sus atributos. Linux proporciona varias Ilamadas al sistema para ella:

'include <unistd.h>

int setuid (uicLt uid);
int setreuid (uicLt ruid, uicLt euid);
int seteuid (uicLt euid) ;
int setgid (gicLt gid);
int setregid (gid_t rgid, gicLt egid) ;
int setegid (gid_t egid); 'define __ USE_BSD #include <grp.h>

int setgroups (size_t size, const gicLt *list);

La Hamada setuid pennite que un proceso modifique su identificador de usuario efectivo. EI proceso debe ser privilegiado, es decir, debe poseer los derechos del superusuario, 0 el nuevo identificador debe ser igual al anterior 0 aI identificador del usuario guardado. En el caso que el proceso sea privilegiado, el identificadorde usuario real y el identificador de usuario guardado tambien se modifican, 10 que significa que un proceso que posea privilegios del superusuario que modifica su identificador de usuario por setuid no puede restaurar ya sus privilegios.

Los identificadores de usuario real y efectivo del proceso actual pueden modificarse por setreuid. Los parametres ruid y euid representan estos identificadores. Si se utiliza el valor -I, el identificador correspondiente no se modifica. Un proceso no privi-

Procesos

55

legiado puede invertir estos dos identifieadores. La llamada seteuid eorresponde a una Hamada de setreuid donde el parametro ruid tiene el valor-I.

La lIamada setgid pennite a un proceso modifiear su identificador de grupo efectivo. El proceso debe ser privilegiado 0 el nuevo identifieador debe ser igual al anterior 0 al identificador de grupo guardado. En el caso en que el proceso sea privilegiado, el identificador de grupo real y el identificador de grope guardado tambien se modifican.

Los identifieadores de grope real y efectivo del proceso actual pueden modificarse por setregid. Los parametres rgid y egid representan estos identificadores. Si se utiliza el valor -I, el identificador correspondiente no se modifiea. Un proceso no privilegiado puede invertir estos dos identificadores. La lIamada setegid corresponde a una llamada de setregid donde el partmetro rgid tiene el valor -I.

La Hamada al sistema setgroups pennite modificar los identifieadores de grope asociados al proceso actual. EI parametro list especifiea los gropes a posieionar, con el tarnafio de la tabla indicado por el panimetro size. S610 un proceso privilegiado puede modificar los gropes que Ie est4n asociadas.

Ademas de estas lIamadas al sistema, Linux ofrece tambien dos primitivas especializadas respecto a los eontroles de acceso a los archivos:

int setfsuid (uiQ_t fsuid);

int setfsgid (giQ_t fsgid);

La primitiva setfsuid modifica el identificador de usuario del cual se sirve el micleo en los controles de aceeso a los archivos.

La primitiva setfsuid modifica el identifieador de gropo del que se sirve el micleo en los controles de acceso a los archivos.

Estas dos llamadas at sistema norma1mente no son utilizadas por un proceso «clasico». De modo predeterminado, el nucleo utiliza.los identifieadores de usuario efectivo y de grupo efectivo para los controles de acceso a los archives, 10 que corresponde a su semantica clasica, Estas dos primitivas estan sin embargo disponibles para permitir a los servidores acceder a los archivos utilizando los derechos de un usuario y de un grope particulares, cuando tratan una petiei6n por euenta de dicho usuario. EI servidor NFS, par ejemplo, utiliza estas dos primitivas para modificar sus derechos a cada petici6n de acceso a los archivos.

Todas estas llamadas al sistema devuelven el valor 0 en easo de exito, 0 el valor -I en caso de fallo. La variable errno puede tomar el valor EPERM que indica que el proceso no posee los privilegios necesarios para modifiear sus identifieadores.

56

Programaci6n Linux 2.0

2.6 Informaci6n de contabilidad

La Hamada al sistema getrusage permite que un proceso conozca los recursos que ha consumido. Su sintaxis es la siguiente:

'include <.ys/time.h> .include <ays/re8ouroe.h> 'include <uniatd.h>

ing getrusage Cint who, atruct rueage *rusage);

El pan1metro who especifica a qu~ proceso debe aplicarse la operaci6n: puede tomar el valor RUSAGE_SELF para obtener los recursos consumidos por el proceso actual, o RUSAG E_CH I LOREN para obtener los consumidos por los procesos hijos. EI resultado Be devuelve en una variable apuntada por el pan1metro rusage (vease la secci6n 1.3 para la definici6n de la estructura rusage). En caso de exito, se devuelve el valor 0, y en caso de fallo getrusage devuelve el valor -I y la variable errno puede tomar el valor EFAULT. que indica que el parimetro rusage contiene una direcci6n invalida.

Linux proporciona tambi6n la primitiva times que permite a un proceso obtener el tiempo de procesador que ha consumido. Su sintaxis es la siguiente:

'include <aya/times,h>

clock._t times (struct tms *bJ.f);

EI panimetro buf especifica la direcci6n de una variable en la que se devolvera el resultado, La estructura tms, defmida en el archivo de cabecera <sys/ times. h>, contiene los campos siguientes:

tipo campo ducripci6n
time_t tIns_utime liempo de procesador consumido par el proceso en
modo usuario, expresado en segundos,
time_ t bns_stime liempo de procesador consumido par el proceso en
modo n(icleo, exprcsado en segundos,
time_t. trn8_cutime liempo de procesador consumido par los procesos hijos
en modo usuario, expresado en segundos.
time_t bns_cstime liempo de procesador consumido par los procesos hijos
en modo nacleo, expresado en segundos. times devuelve el nemero de ciclos de reloj transcurridos desde el manque del sistema. Si el panbnetro buf contiene una direcci6n inv8.lida, devuelve el valor -1 y la variable ermo torna el valor EFAULT.

Procesos

2.7 Limites

57

Un proceso puede imponer lfmites sobre los recursos que puede consumir. Genera1mente, estos lfmites se posicionan en la conexi6n aI sistema, y son heredados por los procesos creados, perc un proceso puede modificarlos mediante las lIamadas aI sistema:

#include <sys/time.h> #include <sys/resource.h> #include <unistd.h>

int setrlimit (int resource, canst struct rl~t *rlim);

int getrlimit (int resource, struct rl~t *rlimJ;

La primitive setrlimit permite posicionar un lfmite. EI parametro resource indica el recurso a limitar, y el lfmite se especifica par el pararnetro rlim. En caso de exito, se devuelve el valor 0, si no setrl imi t devuelve el valor -I.

La estructura r 1 imi e, definida en el archivo < sys / res ourc e . h>, contiene los campos siguientes:

lipo campo descripcion
int rlim_cur Limite «suave»
int rlim_max Limite absoluto Un proceso no privilegiado puede aumentar su limite «flexible», que no puede exceder el lfrnite absolute, 0 disminuir este, 5610 un proceso priviJegiado puede aumentar este limite.

La Hamada al sistema getrlimit permite a un proceso conocer el limite asociado a un recurso. En caso de exito, se devuelve el valor 0, si no setrlimit devuelve el valor -1.

Para estas dos llamadas al sistema, se definen constantes en el archivo de cabecera <sys I resource. h> para representar los diferentes recursos:

constante Significado

RLIIIIT_CPO' RLIIIIT_I'SIZB RL:IM:IT_IlATA RL:IIIIT_STACJ::

RL:IMIT_CORB

RL:IMIT_RSS

Tiempo de procesador expresado en milisegundos Tamaiio maximo de archive, expresado en bytes

Tamafio maximo del segmento de datos, expresado en bytes Tamaiio mbimo del segmento de pita, expresado en bytes Tamaiio maximo del archivo core a crear en caso de error fatal del programa. expresado en bytes

Tamai'io maximo de los datos residentes en memoria central, expresado en bytes

58

Programacion Linux 2.0

lU.J:JIIJ:T_NPROC lU.J:IIJ:T_NOFJ:LB lU.J:JIIJ:T_1IDILOCJI:

lU.J:YJ:T_AB

Nt1mero maximo de proccsos por usuario Numero maximo de archives abiertos

Tamano maximo de datos bloqueados en memoria central, expresado en bytes

Tamano maximo del espacio de direccionamiento, expresado en bytes

En caso de fallo de estas primitivas, la variable errno puede tamar los valores siguientes:

error siJznfflcado
BFAULT r 1 im contiene una direcci6n in vAl ida
BJ:NVAL resource contiene un valor invalido
EPIIRM EI proceso que llama no posee los privilegios que le permitan
aumentar su Ifmite absoluto 2.8 Grupos de procesos

Linux proporciona varias llamadas at sistema que permiten gestionar los grupos de procesos:

#include <unistd.h>

int setpgid (pid_t pid, piQ_t pgid);

int setpgrp (void);

piQ_t getpgid (piQ_t pid);

pid_t getpgrp (void);

La primitiva setpgid modifiea el grupo asociado al proceso especificado par eI parametro pid. EI parametro pgid especifica el mimero del grupo. Si pid es nulo, la modificaci6n se aplica at proceso actual. Si pgid es nulo, el mimero del proceso actual se utiliza como mimero de grupo.

La Hamada al sistema getpgid devuelve el mimero del grupo al que pertenece el proceso especificado por el parametro pid. Si pid es nulo, se devuelve el mimero del grupo del proceso actual. La lIamada al sistema getpgrp devuelve el rnimero del grupo del proceso actual.

La funci6n setpgrp modifiea el mimero del grupo del proceso actual y conesponde a la Hamada setpgid (0, 0).

Procesos

59

En caso de fallo de estas primitivas, la variable errno puede tomar los valores siguientes:

error significado
ZINVAL pgid conticne un valor negativo
ZPDII EI proceso no est4 autorizado a modificar el grupo al que
pcrtenece el proccso espccificado por pid
BSRCH EJ proceso especificado por pid no existe 2.9 Sesiones

Dos lIamadas al sistema penniten manipular las sesiones de procesos:

piq_t setsid (void);

piq_t getsid (piq_t pid);

La Hamada al sistema setsid crea una nueva sesi6n. EI proceso actual no debe ser un leader de grupo de procesos. Como consecuencia de esta llamada, el proceso actual es ala vez elleader de una nueva sesi6n y elleader de un nuevo grupo de procesos, y adernas no tiene asociado ning6n terminal. EI numero del proceso actual se utiliza como identificador de la nueva sesi6n y del nuevo grupo de procesos. Este identificador es devuelto por setsid. En case de fallo, se devuelve el valor -1. y la variable errno toma el valor EPERM, que indica que el proceso actual es ya un leader de grupo de procesos.

La asociaci6n de un terminaJ de control a una sesi6n se efectua automaticamente cuando el proceso leader de la sesi6n abre un dispositivo terminal 0 pseudoterminal aun no asociado,

La primitiva getsid devuelve el numero de sesi6n asociada al proceso especificado por el parametro pid. Si pid es nulo, se devuelve el mimero de la sesion del proceso actual. En caso de fallo, se devuelve el valor -1, y la variable errno toma el valor ESRCH, que indica que el proceso especificado por el parametro pid no existe,

2.10 Ejecuci6n de programa

Un nuevo proceso, creado por una llamada a la primitivafork, es una copia conforme de su proceso padre, y por tanto ejecuta el mismo programa. Una lIamada at sistema permite que un proceso ejecute un nuevo programa:

60

Programacum Linux 2.0

iinclude <unistd.h>

int excve (canst char *pathname. const char * argv [J. cons t char *envp [ J ) ;

La primitiva execve provoca la ejecuci6n de un nuevo programa. pa thname especifica el nombre del archivoa ejecutar. que debe ser un programa binario 0 un archivo de mandatos que empiece por Ia lfnea I=! nombre_de_interprete. El parametro argv indica los argumentos del programa a ejecutar: cada elemento de la matriz argv debe apuntar a una cadena de caracteres que representa un argumento. EI primer elementa de la matriz debe cootener el nombre del programa. los elementos siguientes contienen los argumentos. y ell1ltimo elemento debe contener el valor NULL. EI pararnetro envp especifica las variables de entomo del programa. Cada uno de los elementos debe contener la direcci6n de una cadena de caracteres de la forma nombre_de_variable=valor. y el dltimo elemento de Ia matriz debe contener el valor NULL.

La llamada aI sistema execve provoca el recubrimiento de los segmentos de codigo, de datos y de pila por los del programa especificado. En caso de exito no hay pues retorno, porque el proceso que llama ejecuta ahora un nuevo programa. En caso de fallo, execve devuelve e) valor -1. y la variable errno puede tamar los valores siguientes:

error sillnificQl./o
.2.1Q La lista de argumentos 0 variables de entomo es de tamano excesivo
DCCKS B1 proccso no ticne acceso en ejccuci6n al archi vo especificado por
pathname
"'A1JL"1' pathname contiene una direcci6n inv41ida
:DmIIM'OOLOIIQ pathname espccifica un nombre de archive demasiado largo
&NOD'1' pathname se refiere a un nombre de archivo inexistente
J:LOOP Se ha encontrado un cicio de enlaces simb6licos
DO&U EI archivo especificado por pathname no es un programa ejecutable
..,_ La memoria disponible es insuficiente para ejecutar el programa
DOTDIB. Uno de los componentes de pathname, utilizado como nombre de
direetorio, no es un directorio
u __ El sistema de archivos que contiene el archivo especificado par
pathname se ha montado con opciones que impiden la ejecuci6n de
programas Linux proporciona diversas funciones de biblioteca que ofrecen variantes de execve:

iinclude <unistd.h>

int execl (conat; char *pat:hl'\ame, const char *arg, ... );

int execle (const char *pathnlmle, const char *arg, ...• char *const envp[]);

int execlp (const char *pathname. const char *arg. . .. );

Procesos

61

int execv (const char *pathname, char *const argv[ 1);

int execvp (const char *pathname, char *const argv(J);

Para todas las funciones, el pmimetro pathname especifica el programa a ejecutar. EI parametro argv de execv y execvp indica los parametres a transmitir al programa, de la misma manera que para execve. BI parametro envp indica las variables de enterno a transmitir al programa. Finalmente, en el caso de las funciones execl, execle y execlp, los argumentos del programa se citan por panimetros explfcitos: arg debe contener la direcci6n de una cadena de caracteres que representa el nombre del programa y debe ir seguido de una lista de punteros con la direcci6n de los argumentos. y un ultimo pan1.metro de la lista que debe valer NULL.

Las dos funciones execlp y execvp consideran pa thname como un nombre simple de mandato, contrariamente a las otras funciones y a execve: eJ camino de busqueda asociado al proceso actual (variable de entomo PATH) se utiliza para buscar el programa ejecutable especificado.

3 Conceptos avanzados

3.1 Coordinador

EI coordinador es la funci6n del n6c1eo que decide que proceso debe ser ejecutado por el procesador: el coordinador explora la lista de procesos a punto y utiliza varios criterios para elegir el proceso a ejecutar.

EI coordinador de Linux proporciona tres polfticas de coordinaci6n diferentes: una para los procesos «normales», y dos para los procesos de «tiempo real».

A cada proceso se Ie asocia un tipo de proceso, una prioridad fija y una prioridad variable. EI tipo de proceso puede ser:

• SCHED_FIFO para un proceso de «tiempo real» no preemtivo;

• SCHED_RR para un proceso de «tiempo real» preemtivo;

• SCHED_OTHER para un proceso clasico.

62

Programaci6n Linux 2.0

La polftica de coordinaci6n depende del tipo de procesos contenidos en la lista de procesos a punto de ejecutar:

• Cuando un proceso de tipo SCHED_FIFO est! a punto, se ejecuta inmediatamente.

EI coordinador prioriza la elecci6n del proceso de tipo SCHED_FIFO que posea la mas alta prioridad, y 10 ejecuta. Este proceso no es normalmente preemtible, es decir, que posee el procesador. y el sistema s610 interrumpira su ejecuci6n en tres casos:

1. otro proceso de tipo SCHED_FIFO que posea una priori dad mas elevada pasa al estado a punto: se ejecuta inmediatamente;

2. el proceso se suspende en espera de un evento, como por ejemplo el fin de una entrada/salida;

3. eJ proceso abandona voluntarlamente el procesador por una Hamada a la prirnitiva sched_yield. EI proceso pasa al estado a punto y se ejecutan otros procesos.

• Cuando un proceso de tipo SCHED_RR esta a punto, se ejecuta inmediatamente. Su comportamiento es similar al de un proceso de tipo SCHED_FIFO, con una excepci6n: cuando el proceso se ejecuta, se Ie atribuye un lapso de tiempo. Cuando este lapso expira, puede elegirse y ejecutarse un proceso de tipo SCHED_FIFO 0 SCHED_RR de prioridad superior 0 igual a la del proceso actual.

• Los procesos de tipo SCHED_OTHER llnicamente pueden ejecutarse cuando no existe ningdn proceso de «tiempo real» en estado a punta. El proceso a ejecutar se elige teas examinar las prioridades dinmucas. La prioridad dinamica de un proceso se basa por una parte en el nivel especificado par el usuario por las lIamadas al sistema nice y setpriority, y por otra parte en una variaci6n calculada por el sistema. Todo proceso que se ejecute durante varios ciclos de reloj disminuye en prioridad y puede asf llegar a ser menos prioritario que los procesos que no se ejecutan, cuya prioridad no se ha modificado.

Puede encontrarse una defmici6n mas completa de estas diferentes politicas de coordinaci6n en [Gallmeister 1995].

3.2 Personalidades

A fin de pennitir la ejecuci6n de prograrnas provenientes de otros sistemas operatives, Linux soporta la noci6n de personalidad. A cada proceso se Ie asocia un ambito de ejecuci6n. Este ambito especifica la forma como el proceso efectua lIamadas al sistema, y la forma como se tratan las senates.

Procesos

63

Una personalidad define c6mo se tratan:

• las llamadas al sistema: Linux utiliza una interrupci6n 16gica para pasar al modo nucleo, mientras que otros sistemas Unix utilizan un salto intersegmento;

• los mlmeros de seftales especificados por los procesos: cuando un proceso especifica un mimero de seftal, por ejemplo llamando a las primitivas sigaction 0 kill, el mimero de la sefial se convierte utilizando una tabla de correspondencias;

• los numeros de senates enviadas a los procesos: cuando una seftal debe enviarse a un proceso, su numero se convierte utilizando una tabla de correspondencias.

De modo predetenninado, los procesos utilizan el ambito de ejecuci6n nativo de Linux, que especifica que las llarnadas al sistema se efecnian por interrupci6n 16gica y los mimeros de sefiales no se convierten. Un sistema de emulaci6n puede utilizar sin embargo ambitos de ejecuci6n diferentes para ejecutar programas binarios provenientes de otros sistemas operativos.

3.3 Clonado

Bajo Linux, de la misma manera que bajo Unix, los procesos poseen un espacio de direccionamiento diferente, y deben utilizar medios de comunicaci6n especializados como las tuberfas (vease capftulo 10) 0 los !PC System V (vease capitulo 11), para intercambiar datos.

Pero Linux ofrece una extension que pennite crear «clones» de procesos. Un proceso cion se crea, por la primitiva clone, por duplicaci6n de su proceso padre. Pero, contrariamente a un proceso clasico, puede compartir una parte de su contexte con su padre.

Segun las opciones especificadas en la Uamada a clone, se puede compartir una 0 mas partes de su contexte:

• EI espacio de direccionamiento: los dos procesos comparten los mismos segmentos de c6digo y de datos. Toda modificaci6n efectuada por uno es visible por parte del otro.

• Las infonnaciones de control del sistema de archivos: los dos procesos comparten los mismos directorios rafz y actual. Si uno de estos directorios es modificado por uno de los procesos (por las primitivas chdir 0 chroot), la modificaci6n es efectiva para el otro.

• Los descriptores de archivos abiertos: los dos procesos comparten los mismos descriptores de archivos abiertos. Si uno de ellos eierra un archive, el otro ya no puede acceder a 61.

64

Programacion Linux 2.0

• Los gestores de sefiales: los des procesos comparten la tabla de funciones llamadas en la recepci6n de una sei'ial. Toda modificaci6n par parte de uno de los procesos, mediante la primitiva sigaction por ejemplo, provoca el cambio de la rutina de tratamiento de la sefial por el otro proceso.

• EI identificador de procesos: los dos procesos pueden compartir el mismo numero.

En el caso extremo en que los dos procesos compartan el maximo de cosas, se diferencian unicamente per el valor de los registros del procesador y par su segmento de pila.

Esta posibilidad de clonado permite, entre otras cosas, implementar servidores en los que se ejecuten varias actividades (threads). Estas actividades pueden compartir simplemente datos. sin emplear mecanismos de comunicaci6n interprocesos.

4 Llamadas al sistema complementarias

4.1 Cambia de personalidad

Linux permite a un proceso que modifique su personalidad, a fin de poder ejecutar un programa proveniente de otro sistema operativo. Esta posibilidad es utilizada por los emuladores, par ejemplo el emulador iBCS2 que permite ejecutar programas binarios prvistos para SCQ Unix 0 System V Release 4.

La Hamada al sistema personality permite que un proceso modifique su ambito de ejecuci6n, a fin de que Linux emule el comportamiento de otro sistema operativo. No se incluye en la biblioteca C estandar y debe declararse pues explfcitamente:

#include <syscall.h>

_syscalll (int personality, int persJ;

Esta declaraci6n corresponde al prototipo siguiente:

int personality (int persJ;

El parametro pers especifica el sistema operative a emular. En caso de exito, la antigua personalidad se devuelve en personality. En case de error, se devuelve el valor -I, y la variable ermo toma el valor EINVAL, que indica que el pararnetro pers contiene un valor invalido,

Procesos

65

El archi vo de cabecera < 1 inux/per S ona 1 i ty _ h> define varias constantes que especifican los sistemas operativos a emular:

constasse sil(lIifjiiiilii
PBR_LlNUX Linux, es decir, ninguna emulaci6n
PBR_SVR~ System V Release 4
PD_SVJ\3 System V Release 3
PD_SCOSVJ\3 SeQ Unix versi6n 3.2
PD_WISD386 UNIX System Vf386 Release 3.2.1
PBR_ISClt' Interactive Unix
PD_BSD BSDUnix
PBR_XBNXX Xenix 4.2 Modificaci6n de la coordinaci6n

Varias llamadas al sistema penni ten modificar la polftica y los parametres de coord inaci6n asociados a un proceso:

tinclude <sched.h>

int sch~etscheduler (pi~t pid, int policy,

const struct sched....Param ·param);

int schedlgetscheduler (pi~t pid);

int sched_setparam (pid,_t pid, const struct schedJ>aram ·param);

int sched_getparam (pid,_t pid, struct scheCl..param ·param);

La Hamada at sistema sched_setscheduler pennite modificar la polftica y los parametros de coordinaci6n asociadas a un proceso. EI panUnetro pid especifica el proceso sobre el que conviene actuar. Puede ser nuIo para indicar el proceso actual. EI parametro po 1 icy especifica la polftica de coordinaci6n a aplicar at proceso, y debe tener uno de los valores SeHED_FIFO, SCHED_RR, 0 SCHED_OTHER. EI parametro param especifica los parametres de coordinaci6n a utilizar. La primitiva sched getscheduler permite obtener la polftica de coordinacion asociada al proceso caracterizado por pid, 0 al proceso actual si pid es nulo.

La UarDfda al sistema sched_setparam pennite modificar los parametros de coordinaci6n asociadas a un proceso. EI panimetro pid especifica el proceso sobre el cual cooviene actuar. Puede ser nulo para indicar el proceso actual. EI parametro param indica los parametres de coordinaci6n a utilizar. La primitiva sched_getparam permite obtener los parametros de coordinaci6n asociadas aI proceso caracterizado por pid, 0

66

Programaci6n Linux 2.0'

al proceso actual si pid es nulo. Estos par.Unetros se envfan en la variable cuya direcci6n se pasa en el parametro paramo

Linux 2.0 s610 pennite modificar la prioridad estatica asociada a un proceso. La estructura sched_param. definida en el archivo de cabecera <sched. h>, contiene un solo campo. sched_priority:

tipo campo descripci6n
int sched....priority Prioridad estatica asociada aJ proceso En caso de fallo, esas primitivas devuelven el valor -I. y la variable errno puede tamar los valores siguientes:

error significado
D'AULor param contiene una direccion invdlida
BINVAL policy 0 la variable apuntada par param contiene un valor invalido
EP_ EI proceso no posee los privilegios necesarios para modificar sus
pan\metros de ordenaci6n
.'RCH EI proceso especificado por pid no existe Las primitivas sched_get_priority_min y sched_get_priority_tnax penniten obtener las prioridades estaticas mfnima y maxima asociadas a una polltica de coordinaci6n. Su sintaxis es la siguiente:

*include <sched.h>

int sched....get_priority.Jllin (int policy);

int Bched....get_priorityJMX (int policy);

La primitiva sched_rr_get_interval pennite obtener ellapso de tiempo atribuido a un proceso de tipo SCHED_RR. Su sintaxis es la siguiente:

iinclude <sched.h>

int Bched....rr_get_interval (pid....t pid, struct timespec -interval);

El parametro pid especifica el proceso. Puede ser nuIo para indicar el proceso actual. EI proceso en cuesti6n debe ser de tipo SCHED_RR. EI parametro interval debe contener la direcci6n de una variable en la que se colocara el lapso de tiempo asociado al proceso especificado, En caso de exito, se devuelve el valor 0, si no sched rr _get_interval devuelve el valor -1 y la variable errno puede tomar los valores siguientes:

Procesos

67

error significado
DAULT interval contiene una direcci6n invalida
DOSTS La llamada aI sistema no est'- implementada (ocurre en Linux 2.0)
BSRCH EI proceso especificado por el parametro pid no existe La estructura t irnespec compona los campos siguientes:

tipo campo descripcio«
long tv_sec Ndmero de segundos
long tv_nsec Namero de nanosegundos La primitiva sched_yield permite al proceso actual liberar al procesador. Su sintaxis es la siguiente:

*include <sched.h>

int sched_yield (void);

Al ejecutar esta primitive, el proceso actual se coloca al final de la lista de procesos a punto, y se ejecuta el coordinador. Si existen otros procesos a punta en el sistema, cambia el proceso actual.

4.3 Prioridades de los procesos

Linux proporciona varias llamadas al sistema que penniten manipular las prioridades de los procesos:

iinclude <unistd.h>

int nice (int inc);

iinclude <sys/resource.h>

int setpriority (int which, int who, int prio);

int getpriority (int which, int who);

La primitiva nice permite modificar la prioridad dinamica del proceso actual. EI parametro inc se atiade ala prioridad actual. S610 un proceso privilegiado puede especificar un valor negative a fin de aumentar so prioridad. En caso de exito, se devuelve el valor 0, si no nice devuelve el valor -I y la variable ermo toma el valor EPERM, que indica que el proceso que llama no posee los privilegios necesarios para aumentar su prioridad.

68

Programaci6n Linux 2.0

La Hamada al sistema setpriority modifiea la prioridad de un proceso, de un grupo de proeesos 0 de todos los procesos de un usuario. EI parametro which puede tomar como valor PRIO_PROCESS, PRIO_PGRP 0 PRIO_USER. EI parametro who especifica un ndmero de procesos, de grupo de procesos 0 de usuario seg6.n el valor del which. EI parametro prio indica la prioridad a colocar. S610 un proceso privilegiado puede dar a uno 0 mas procesos mayor prioridad. La primitiva setpriority devuelve el valor 0 en caso de 6xito, 0 el valor -1 en caso de error.

La Hamada al sistema getpriority permite obtener la priori dad de un proceso, de un grupo de procesos 0 de todos los procesos de un usuario. Los parametres which y who tienen el mismo significado que en setpriority, EI valor devuelto es la prioridad mas importante atribuida a los procesos especificados. En la medida en que getpriority puede devolver el valor -1 sin que ella indique un error, es necesario volver a poner a o la variable errno, y comprobar su valor teas el retorno de la Hamada al sistema.

En caso de fallo de estas dos primitivas, la variable errno puede tomar los valores siguientes:

error siRnijicado
:u.CCBS EI proceso que llama no posee los privilegios necesarios para aumentar la
prioridad de otros procesos
B:ElfVAL which contiene un valor invAiido
IDPBJUI El proceso actual no pasee los mismos identificadores de usuaries reales y
efectivos que el proceso 0 procesos especificados por.who
IIBIlCH Ningdn proceso corresponde a la combinaci6n especificada por los
parametres which y who 4.4 Control de la ejecucion de un proceso

La Ilamada al sistema ptrace permite que un proceso controle la ejecuci6n de otro proceso. Su sintaxis es la siguiente:

#include <sys/ptrace.h>

int ptrace (long request, piq_t pid, long addr, long data);

EI parametro request especifica la operaci6n aefectuar sobre el proceso cuyo namero se pasa en el parametro pid. EI significado de los parametres addr y data depende del valor de request.

Las operaciones disponibles se definen en el archivo de cabecera <sys/ptrace. h>. Las constantes son las siguientes:

Procesos

69

constante significado
P'1"R.ACII:_TRACBIII: EI proceso actual indica que sera controlado por otro proceso
PTRACB_A'l'TACB EI proceso actual indica que oontrolani el proceso identificado
par pid. La sei'ia! srQ8TOp se envfa a! proceso bajo control
para suspender su ejecuci6n
PTRAClI:_PBBDATA EI contenido de la palabra situada en la direccion addr. en el
segmento de datos del espacio de direccionamiento control ado.
se devuelve en la variable direccionada por la variable data
PTRACB:_PBBltTBXT EI contenido de la palabra situada en la direccion addr. en el
segmento de c6digo del espacio de direccionamiento del proceso
controlado, se devuelve en la variable direccionada por la
variable data
PTRACB:_PBBlCtJSR. EI contenido de la palabra situada en la direcci6n addr en la
estructura user del proc:eso control ado (vease la seccion 5.2)
se devuelve en la variable direccionada por data
PTR.ACB_POKZDATA EI valor contenido en da ta se escribe en la palabra situada en
la direcci6n addr, en el segmento de datos del espacio de direc-
cionamiento del proceso controlado
PTRACB_PODTJIXT EI valor contenido en da ta se escribe en la palabra situada en
la direccion addr, en el segmento de c6digo del espacio de
direccionamiento del proceso controlado
PTRACI:_PODUSR. EI valor contenido en data se escribe en la palabra situada en
la direccion addr en la estructura user del proceso controlado
PTRACB_SYSCALL La ejecuci6n del proceso controlado se prosigue hasta la
ejecuci6n de la proxima Hamada al sistema, EI mandato strace
utiliza esta opci6n para mostrar las lIamadas al sistema
ejecutadas por un proc:eso
PTRAClI:_CON'l' La ejecuci6n del proceso controlado se prosigue
PTR.ACB_ULL La ejecuci6n del proc:eso controlado se finaliza
PTRACB_SINOLBSTBP La ejecuci6n del proceso controlado se prosigue para una sola
. instrucci6n maquina
PT:RA.CB__DDBTACB EI proceso ya no esta bajo control En caso de error, ptrace devuelve el valor -1 y la variable errno puede tomar los valores siguientes:

error significado
I!:J'AtJLT addr contiene una direcci6n invalida
BIO request 0 data contiene un valor invalido
BPBRM E1 proccso que llama no posee los privilegios necesarios para controlar el
proceso especificado por pid, 0 este ultimo esta ya bajo control
mSRca EI proceso especificado por pid no existe Los depuradores, como gdb, utilizan ptrace para ejecutar un programa instrucci6n por instrucci6n, y para perrnitir al usuario visualizar las variables, del programa.

70

Programacum Linux 2.0

4.5 Clonado

La Hamada al sistema clone crea un «clon» del proceso actual. Esta primitiva no se incluye en la biblioteca estandar yes necesario declararla explfcitamente.

Antes de Hamar a clone, debe asignarse un segmento de pila (Ilamando a Ia funci6n mailoc, por ejemplo). y los pan1metros de la funci6n a ejecutar deben apilarse en esta zona de memoria. Seguidamente. los registros del procesador deben inicializarse de la forma siguiente (en un procesador x86):

• eax debe contener el c6digo de la Hamada clone. representado por la constante __ NR_clone;

• ebx debe contener una combinaci6n de constantes presentadas mas adelante;

• ecx debe contener el puntero de pila para el proceso hijo.

EI programa clone.S siguiente. derivado de un archivo fuente de la biblioteca C del proyecto GNU, implementa la Hamada de la primitiva clone en lenguaje ensamblador x86. EI prototipo de la funci6n clone proporcionado es el siguiente:

int clone (int (*fnJ (J, voic *chil~tack, int flags, int nargs, ... J;

EI pararnetro fn es un puntera a la funci6n a ejecutar por el proceso hijo. EI parametro child_stack es un puntero a Ia zona de memoria asignada para la pila del proceso hijo. El parametro flags define las modalidades de «clonado». Finalmente, el parametro nargs define el mimero de argumentos a pasar a la funci6n apuntada por fn y va seguido por estes argumentos.

Varias constantes, definidas en el archive de cabecera <linux/sched.h>. definen las modalidades del «clonado»:

constante significado
ct.ONE_VII EI proceso hijo comparte el espacio de direccionamiento del
proceso padre
CLOD_PS EI proceso hijo comparte los directories rafz y actual del proceso
padre
CLOD_PILBS E1 proceso hijo comparte los descriptores de archivos abiertos del
proceso padre
CLOD_SIIDARD EI proceso hijo comparte los gestores de sefiales del proceso padre
CLOD_PID EI proceso hijo posee el mismo ndmero que el proceso padre Procesos

71

Ademas, puede especificarse tambien la sefiai a enviar ai proceso padre en la terminaci6n del proceso hijo.

idefine ____ASSEMBLY_

iinclude <linux/linkage.h> #include <asm/errno.h> #include <asm/unistd.h>

. text

ENrRY{clone)

/* Verificaci6n de los argumentos *1 movl $-EINVAL, teax

movl 4{tesp),tecx I*El puntero de funci6n debe ser no nulo*1 testl tecx,tecx

j % syscall_error

movl B{tesp),tecx 1*14 direcci6n de pi1a debe ser no nu1a*1 testl %ecx, %ecx

j% sysca11_error

movl 16 (%esp) , tedx I·E1 nUmero de argumentos debe ser posi ti vo* 1 testl tedx,tedx

js sysca11_error

1: movl
mov1
dec
jnz
2: 1* Asignaci6n de espacio en la pila y copia de argumentos *1 mov1 'edx,'eax

negl %eax

lea -4{%ecx,%eax,4),tecx

jz 2f

16 ('esp,%edx,4),%eax teax, ° (tecx, tedx, 4) tedx

1b

1* Guardado del puntero a la funci6n

Se ret ira de la pila tras llamar al cIon */

movl 4(tesp),%eax

mov1 teax,O(%ecx)

1* Llamada a 1a pr~tiva clone ·1 pushl tebx

movl 16 (tesp) , tebx

movl $~clone,'eax

int $OxBO

popl tebx

/ * Conprobaci6n del c6digO de retorno * I

test 'eax,teax

jl sysca11_error

jz thread_start

72

Programacion Linux 2.0

ret

syscall_error:

1* Error, se devuelve -1 *1

movl $-l,'eax

ret

threacLstart:

1* C6digo del proceso cIon *1 subl' 'ebp, ,et:p

call *'ebx 1* Llamada a la funci6n *1

mov I $___NR,,_exi t , 'eax 1* Finalizaci6n del proceso * /

int $Ox80

EI programa EjempJoCJone.c es un ejemplo simple (y poco iitil) del usa de la funei6n clone. Crea un proceso hijo que eomparte el espacio de direccionamiento, los deseriptores de archivos y la gesti6n de las seftales con su proceso padre. El proceso hijo modifica una variable y eierra un archivo. EI proceso padre muestra el contenido de la variable y eomprueba si el archivo sigue abierto,

iinclude <signal.h> iinclude <stdio.h> iinclude <stdlib.h> 'include <fcntl.h>

'include <linux/sched.h> iinclude <linux/unistd.h>

idefine STACKSlZE 16384

/*

* Esta funci6n es s~lar a thr_create() de la biblioteca " pthreads, pero es menos evolucionada

*1

int start_clone (void (*fn) (void *1, void *datal

long retval; void *newstack;

/*

* Asignaci6n de la pila de la nueva tarea -til

newstack = (void **) malloc (STACKSlZE); if (! newstack)

return -1;

1-tI

Procesos

73

* Inicializaci6n de la pila */

newstack '" (void *) (STACKSlZE + (char *) newstack);

/*

* Creaci6n del cIon */

retval = clone (fn, nelolStack, ~VM I CLClNE_.FS I CLONEJlLES I cu::tm_SIGHMm I SIGCHLD, 1, data);

if (retval < 0) {

errno = -retval; retval = -1;

return ret val;

int shOW'_s&ne_vm;

void cloneq_process~tarts_here (void *data) {

printf ('child:\t got argument %d as fd\n', (int) data); show_sarne_ vm " 5;

printf ('child:\t vm '" %d\n', show_S&ne_vm); close ( t Lnt ) data);

int main (void)

int fd, pid;

fd = open ('/dev/null', O_RI)CfiL¥); if (fd < 0) {

perror ('/dev/null'); exit (1);

print! ('mother: \ t fd show_same_vm = 10;

printf ('mother; \ t vm = %d\n', show_same_vrnJ;

pid'" start_clone (cloneq_process_starts_here, (void *) fd); if (pid < 0) {

%d\n', fd);

perror (' start_clone' ) ; exit (1);

sleep (I);

pr intf (. mother: \ t vm '" %d \n', show_sarne_vm); if (write (fd, 'c', 1) < OJ

print! ('mother:\t child closed our file descriptor\n'); exit (0);

74

Programacion Linux 2.0

La ejecuci6n del programa provoca la visualizaci6n siguiente:

mother: fd = 3 mother: vm '" 10

child: got argument 3 as fd child: vm '" 5

mother: vm '" 5

mother: child closed our file descriptor

Hay que observar que la primitiva clone es una Hamada al sistema de muy bajo nivel, yes probablemente bastante compleja de usar directamente. Xavier Leroy esta desarroUando actuaimente una biblioteca de threads utilizando clone y esta disponible en elURL http://pauillac.inria.fr/-xleroy/linuxthreads/.

5 Presentaci6n general de la implementaci6n

5.1 La tabla de procesos

S.I.1 Descriptor de proceso

Cada proc~so se referencia por un descriptor. Este descriptor contiene los atributos del proceso, asf como las informaciones que permiten gestionar el proceso.

La estructura task_struct, defmida en el archivo <Iinuxlsched.h>, caracteriza un proceso. Contiene los campos siguientes:

tiDO camoo descripcWri
volatile long state Estado del proceso
long counter Nl1mero de ciclos de reloj durante los que el
proceso actual est! autorizado a ejecutarse
long priority Prioridad del proceso
unsigned long signal Senales en espera (vease el capitulo S,
secci6n 5.1)
uns igned long blocked Seftales ocultas (vease el capitulo 5,
seeeion 5.1)
unsigned long flags V6tse nW adeJante
int errno C6digo de error originado por las llamadas
aI sistema
long (8) debugreg Copia de los registros de hardware de
depuraci6n Procesos

75

struct exeC_domain * struct lin~infmt *

struct tas~struct * struct tas~struct * struct tas~truct *

struct tas~truct *

unsigned long unsigned long

int

int

unsigned long int:l

int:l

int int int int

int [OOROUPS]

struct tas~truct *

struct tas~struct * struct tas~truct *

struct tas~struct *

struct tas~struct * struct wait_queue *

unsigned short

unsigned short

unsigned short

uns igned short

exec_dcxnain binfmt

next_task prev_tilBk next_run

prev_run

exit_code

exitJignal

personality duq)able

pid pgrp session leader

groups P_OA'tr

p_pptr p_cptr

p_osptr wait_chldexit

uid

euid

suid

fsuid

Ambito de ejecuci6n del proccso

Puntero a las operacioncs relacionadas con el rormato del programa ejecUiado par el proceso Puntero a1 proceso siguiente en la lista Puntero a1 proceso anterior en Ia lista Puntero aI proceso siguiente en la lista de procesos a punto

Puntero al proceso anterior en la lista de procesos a punto

Puntero de pila usado en modo nucleo Direcci6n de la P'gina de memoria que conliene la pila ulilizada en modo nacteo C6digo de retorno a devolver al proccso padre: los 8 bits de menor peso (bits 0 a 7) conlienen el ndmero de la sefta! que ha ceusado la finalizaci6n del proceso, 0 bien los 8 bits liguientes (bits 8 a IS) conlienen el c6digo de retorno devuelto por el proceso tras lIamar ala primitiva _exit

Nlimero de la seftal a enviar a! proceso padre en la finalizaci6n

Penonalidad asociada a! proceso

Booleano que indica si debe creane un archivo core en caso de error fatal Booleano que indica si el proceso ha usado ~C1Je para ejecutar un programa

Nlimero del proceso

Nilmero del grupo que contiene el proceso Nlimero de la sesi6n que contiene el proceso Booleano que indica Ii el proceso es eillder de su sesi6n

Grupos asociados al proceso

Puntero al descriptor del proceso padre original

Puntero aJ descriptor del proceso padre Puntero aJ descriptor del proceso hijo creado oW redentemente

Puntero aI proceso «hermano» siguiente, que ha sido creado por eI mismo proceso padre Puntero aI proeeso .hermanOlt anterior Variable utilizada para esperar la finalizaci6n de un proceso hijo

Identificador de usuario real asociado a1 proceso

Identificador de usuario efeetivo asociado a1 proceso

Idenlificador de usuano guardado asociado a1 proceso

Identificador de usuario asociado a1 proeeso para los controles de acceso a los archives

76 Programacion Linux 2.0
unsigned short gid Identificador de gropo real asociado at proceso
unsigned short egid Idendficador de grupo efectivo asociado al
proceso
unsigned short sgid Identificador de gropo guardado uociado al
pnxcso
unsigned short tsgid Identificador de gropo asociado al proceso
para los controles de acceso a los archi vos
unsigned short timeout Lapso de espera mtximo durante el que el
pnxcso debe estar suspendido
unsigned short policy Polftica de coordinaci6n asociada al proceso
unsigned short rt_priority Prioridad esdtica asociada al proceso
long utime TIempo de procesador consumido en modo
usuario
long stima TIempo de procesador consumido en modo
ndeleo
long cutime TIempo de procesador consumido por 105
procesos hijos en modo usuario
long C8time TIempo de procesador consumido por los
procesos hijos en modo naeleo
long IItart_time Pecha de creaci6n del proceso
unsigned lOIlg' min....f1t Ndmero de excepciones de memoria tratadas
por el proceso sin cargar pAginas
unsigned long maj_flt Ndmc:ro de excepciones de memoria tratadas par
el proceso cargando una pigina desde el disco
unsigned long nswap Ndmero de piginas del proceso que se han
guardado en la zona de swap
unsigned long crnin....f1t Ndmero de excepciones de memoria tratadas
por los proeesos hijos sin cargar paginas
unsigned long ooaj_f1t Ndmero de excepciones de memoria tratadas
par los prooesos hijos cargando una pagina
desde el disco
unsigned long cnswap Ndmero de pAginas de los procesos hijos
guardadas en la zona de swap
int:l swappab1e Booleano que indica si el proceso puede
guardarse en memoria secundaria
unsigned long SWBp_cnt Ndmero de pAginas de memoria a descartar
struct rlimit rlim Umites asociados al proceso
[RLIl(_Jd,IMITS J
WlBigned short usec1_.math BooIeano que indica si el proceso ha utilizado
el coprocesador matem4tico
char [16] caIIII Nombre del prognuna ejecutado par el proceso
int 1ink....count Ndmero de enlaces simb6licos explorados en
la resoluci6n de un nombre de archivo (v6ase
el cap{tuIo 6)
struct tty_struct * tty Puntero aI descriptor del lerminal asociado al
proceso (vUse el cap{tuIo 9)
struct sem.....undo * seaamdo Puntero a una lista de semMoros System V 8
Iiberar (v6ise el capftulo 11)
struct sem.....queu. * sems1eeping Puntero a 18 cola de espera del semMoro
System Venia que el proceso esta suspendido Procesos

77

struct desc_struct * Idt

struct thread.....struct tss

struct fs_struct * fs

struct files_struct * files

struct mmLStruct * mm

struct signal_struct * sig

int

int

Puntero aJ descriptor de la tabla de segmentos local a este proceso. Esta tabla se usa y modifica por el emulador Wine.

VaJor de los registros del proccsador Informaciones de control utilizadu en los accesos a los archivos (v6ase el capCtulo 6, secci6n 5.2.S)

Puntcro a los descnptores de archives abiertos por el proce5O (v6ase el capftulo 6, secci6n 5.2.5)

Informaciones de control utilizedas para la gcsti6n de memoria (vCase el capCtulo 8, secci6n 5.4.1)

Puntcro a los descriptores de acciones asociadas a las sellales (vease el capftulo 5, secci6n 5.1)

Idcntificador del procesador sobre el que se ejecuta el proceso

ldentificador del III time procesador sobre el ~ se ha ejecutado el proceso

processor

last_processor

EI estado del proceso (campo state) puede expresarse por varias constantes:

constants sill1liticado
'1'~ EI proceso eslA a punto 0 en curso de ejecuci6n
'l'ASJt.._1Ii'1'&RKUPtmLB EI proceso esLa suspendido perc puede sec despertado por una senal
'l'AB..JIlUJt1'BlUWPI'1Bla E1 proceso eslA suspendido y no puede ser despertado per una senal
'l'ASlLZCMBD E1 proceso ha tcrminado su ejecuci6n
'l'ASlLS'l'OPPED E1 proceso ha sido suspendido por el usuario Tambien se definen varias constantes para el campo flags:

cons/ante significado
PF _P'l'RACED E1 proceso esta controlado por otro
Pl' _'l'RACZS!"S EI proceso esta controlado por otro y debe eieeutarse basta la proxima lIamada
a! sistema
Pl'~ El proceso no ha ejecutado 18 lIamada aJ sistema execve para ejecutar otro
programa
Pl' __9O'PBRPRIV El proceso ha utiliZ8do los privilegios del superusuario
PI' _DIlM5'COlU!: El proceso ha terminado produciendo un archivo core
PF _Bl:GHU.BD El proceso ha terminado poe la Jlegada de una &efta!
PF _8'l'All"l'DXI EI proceso se est! creando
Pl' _!:XI'l'DXI EI proceso est! terminando
PF_OSiibi'PO EI proceso ha utilizado el coprocesador matem8tico durante su ultimo lapse de
tiempo (este estado es utilizado por el c6digo de gesti6n de los
multiprocesadores ) 78

Programaci6n Linux 2.0

S.1.2 Organizaci6n de la tabla de procesos

Los descriptores de proceso los asigna dimimicamente el micleo, llamando a la funci6n kmalloc. La matriz task, definida en el archive fuente kemel/sched.c, contiene punteros a estos descriptores. La matriz current_set contiene punteros a los descriptores de procesos en curso de ejecuci6n en cada procesador. Una macroinstrucci6n, Hamada current, corresponde ala direcci6n del descriptor del proceso ejecutado por el procesador actual.

La variable ini t_task contiene el descriptor del primer proceso creado en el arranque del sistema. Tras el arranque, este proceso s610 se ejecuta cuando ninguno mas este a punto, y su descriptor sirve para recuperar el inicio de la tabla de procesos.

Los descriptores de procesos se organizan en forma de una lista doblemente encadenada, por los campos next_task y prev_task. Los descriptores de los procesos a punto 0 en curso de ejecuci6n se colocan en otra lista doblemente encadenada, mediante los campos next_run y prev_run.

p~ p_oppb'

p_eptr

p....)'lptr p_Ylper

F2 FI

p_osptr p_ospCr

FIG. 4.3 - Relaciones entre descriptores de procesos

Los campos p_opptr. p-pptr, p_cptr, PJsptr Y p_osptr se utilizan para gestionar las filiaciones entre procesos. Cuando un proceso se duplica, llamando a la primitiva fork:

• los punteros p_opptr y p_pptr del descriptor del proceso hijo contienen la direcci6n del proceso padre;

• el puntero p_osptr del descriptor del proceso hijo toma el valor del puntero p_cptr del descriptor del proceso padre;

Procesos

79

• el puotero p_ysptr del descriptor del proceso hijo se inicializa aI valor nulo;

• el puntero p_ysptr del proceso «hermano» mas reciente (referenciado por el puntero p_cptr del descriptor del proceso padre) contiene la direccion del descriptor del nuevo proceso hijo;

• el puotero p_cptr del descriptor del proceso padre contiene fa direcci6n del descriptor del proceso hijo.

La figura 4.3 representa estos punteros en el caso de un proceso P que ha creado sucesivamente tres procesos hijos Fl, F2 Y F3.

5.1.3 Manlpulaci6n de la tabla de procesos

En el archivo < 1 inux / s c hed . h> se definen varias macroinstrucciones que permiten gestionar las listas de descriptores de procesos:

macroinstruccior: s if(ni/icfUio
~:mM Esta macroinstrucci6n suprime un descriptor de todas las listas a las que
pertenece
SI:l'_LINltS Esta macroinstrucci6n inserts un descriptor en todas las listas: actualiza los
punteros del descriptor para insertarlo en la lista de sus .. hermanos»
!or_uclLt_k Esta macroinstrucci6n permite explorar todos los descriptores de procesos,
haciendo variar su pan1metro S.2 Registros del procesador

El contexto de un proceso induye el contenido de los registros del procesador. En un cambia de contexto, 0 en la Hamada a una primitiva del sistema, estos registros son guardados en memoria par el nucleo, La estructura pt_regs, definida en el archivo de cabecera <asm/ptrace. h>, contiene los campos siguientes para la arquitectura x86:

tipo campo descripcion
long ebx. Valor del registro ebx
long ecx Valor del registro ecx
long edx Valor del registro edx
long esi Valor del rcgistro es i
long edi Valor del registro edi
long et:p Valor del registro et:p
long eax Valor del registro eax a restaurar al volver de la !lamada al
sistema
unsigned short ds Valor del registro de scgmcnto ds (descriptor del segmento
de datos) 80 Programaci6n Linux 2.0
unsigned short es Valor del registro de segmento es
unsigned short fs Valor del registro de segmento fs
unsigned short 98 Valor del registro de segmento gs
long orig_eax Valor del registro eax en la Uamada at sistema (eax
contiene el nl1mero de la primitiva a ejecutar)
long eip Valor del registro eip (contador ordinal)
unsigned short cs Valor del registro de segmento cs (descriptor del segmento
de c6digo)
long eflags Valor de los indicadores del procesador
long esp Valor del registro esp (puntero de pila)
unsigned short 8S Valor del registro de segmento ss (descriptor del segmento
de pila) La estructura user, definida en el archive de cabecera <asm/user. h>, es utilizada par el nncleo cuando debe crearse un archivo core: esta estructura se coloca al principia del archive para que un depurador pueda acceder al contexte del proceso cuando ha terminado. La Hamada al sistema ptrace utiliza tambien esta estructura permitiendo a un proceso leer y modificar su contenido.

Los campos contenidos en la estructura user son los siguientes:

tipo campo tkscripci6n
struct pt_regs regs Valor de los regislros del procesador
int u_fpvvalid Booleano que indica si el proceso utiliza el coprocesador
matem!tico
struct i387 Valor de los registros del coprocesador matematico
user_i387_struct
unsigned long int u_tsize Tamallo del segmento de c6digo. expresado en paginas de
memoria
unsigned long int u_dsize TamaJ\o del segmento de datos. expresado en pdginas de
memoria
unsigned long int u,_ssize Tamaoo del segmento de pila, ex pres ado en paginas de
memoria
unsigned long start_code Direcci6n virtual del inicio del segmento de c6digo
unsigned long S tar t_s tack Direcci60 virtual del inicio de la pila
long int signal NI1mero de la seiiaI. que ha causado el fin del proceso
int reserved No utilizado
struct pt__regs .. u_uO Direcci6n del valor de los registtos en Ja estructura user
(utilizado por gdb)
struct
user_i387_struct * u,_fpstate Direcci6n del valor de los registros del coprocesador en 1a
estructura user (utilizado por gdb)
unsigned long magic Firma que identifica un archivo core
char{32J u,_comn Nombre del programa ejecutado por el proceso
intr8] u_debugreg Valor de los registros de hardware de depuraci6n Procesos

81

5.3 Sincronizaci6n de procesos

5.3.1 Principio

En un instante dado, un solo proceso puede ejecutarse en modo nucleo, Aunque es posible que se apliquen interrupciones de hardware y software a este proceso, Linux no provoca Ia coordinaci6n si el proceso actual esta activo en modo micleo. Un proceso que se ejecuta en modo m1c1eo puede provocar sin embargo un cambia de proceso actual suspendiendo su ejecuci6n. Esta suspensi6n voluntaria se debe generalmente a la espera de un evento, tal como et fin de una entrada/salida 0 la terminaci6n de un proceso hijo.

Linux proporciona dos herramientas que permiten a los procesos sincronizarse en modo rnicleo: las colas de espera (wail queues) y los semaforos. Las estructuras correspondientes se definen en el archi vo de cabecera < 1 inux I wai t . h>.

5.3.2 Colas de espera

Una cola de espera es una lista encadenada y circular de descriptores. Cada descriptor contiene la direcci6n de un descriptor de proceso asf como el puntero al elemento siguiente de la cola. La estructura wai t_queue caracteriza los elementos de la cola de espera:

lipo campo tkscrifJfjOn
struet task..._struet * task Puntero al descriptor del proceso en espera
struet wait_queue * next Puntero al elemento siguiente de la cola 5.3.3 Semliforos

Los semaforos constituyen un mecanismo general de sincronizaci6n entre procesos.

Un semaforo no es realmente un mecanismo de comunicaci6n, sino mas bien un mecanisme de sincronizaci6n de procesos.

En informatica, y mas particulannente en el caso de los sistemas operativos, un semaforo se utiliza para controlar el acceso a un recurso.

EI semaforo y las operaciones asociadas fueron definidos en 1965 por E. W. Dijkstra [Dijkstra 1965]. Un semMoro comprende un valor entero (un contador) y des operaciones:

82

Programaci6n Linux 2.0

• P (del holandes proberen, probar): esta operaci6n se utiliza cuando un proceso quiere entrar en una secci6n crftica. Esta operaci6n realiza las etapas siguientes:

1. probar el valor del contador del semaforo que controla el recurso;

2. si este valor es positive, el proceso puede servirse del recurso, y decrementa el valor en I para indicar que utiliza una unidad del recurso;

3. si este valor es nulo, el proceso se duerrne hasta que el valor sea de nuevo positivo, Cuando el proceso se despierta, vuelve 8 18 etapa I.

• V (del holandes verhogen, incrementar): esta operaci6n es simetrica a la anterior, y se utiliza cuando un proceso abandona la secci6n crltica. EI valor del contador del semaforo se incrementa y los procesos en espera son despertados.

Las operaciones P y V deben realizarse de manera at6rnica, es decir, que no deben ser interrumpidas.

En 1a literatura inglesa, las operaciones P y V se denorninan frecuentemente down y up.

Los semaforos se utilizan en el Mnbito de los sistemas informaticos principalmente para resolver dos problemas:

• La exclusi6n mutua: se trata de impedir ados procesos el acceso a un mismo recurso en un mismo instante. Si esto se produjera, el recurso podrfa encontrarse en un estado inconsistente.

• EI problema de los productoreslconsumidores: se trata de permitir la cooperaci6n de dos procesos: uno produce infonnaciones que el otro uti I izara, EI semaforo se utiliza para prevenir al consurnidor que los datos estsn a punto.

Estos problemas se resuelven mediante semaforos binarios. pero el contador del sernaforo puede tomar otros valores positivos. Es el caso cuando varias unidades de un mismo recurso estan disponibles; el contador torna entonces el valor del mirnero de unidades accesibles simultaneamente,

Bajo Linux, la estructura semaphore. definida en el archivo <asm/ semaphore. h>, contiene los campos siguientes:

tipo campo ckscripciOn
int count Contador del scm4foro
int waiting N1lmero de procesos en espera
struct wait_queue * wait Lista de procesos en espera en el semaforo Procesos

83

5.4 Los timers

Linux gestiona una lista de timers a fin de poder poner procesos en espera durante un lapso especificado. Estos timers se organizan en forma de una lista circular doblemente encadenada. Los timers a desencadenar en un futuro proximo se colocan al principia de la lista, mientras que los elementos a desencadenar en un futuro lejano se sinian al final de la Iista.

La estructura timer _1 is t, definida en el archi vo < 1 inux / timer. h>, define el fonnato de los elementos de la lista:

tiJ1Q_ campo iMscripci6n
struct timer_list • next Puntero aJ elemento siguiente en la lista
struct timer_list • pre'll Puntero aJ elemento anterior de la lista
unsigned long expires Fecha de expiraci6n del timer
unsigned long data Palimetro a transmitir ala funci6n asociada
void (. ) (unsigned long) function Direcci6n de la funci6n a llamar cuando el timer expire La variable timer_head. definida en el archivo fuente kernellsched.c, contiene la direcci6n del primer elemento de la !ista.

La fecha de expiraci6n (campo expires) se expresa en mimero de ciclos de reloj desde el arranque del sistema. La variable global jiffies es mantenida por el m1cleo (su valor se incrementa en cada interrupci6n del reJoj) y contiene siempre el mimero de ciclos de reloj transcurridos desde el arranque.

5.5 Ambitos de ejecuci6n

El micleo mantiene los ambitos de ejecuci6n soportados. Para ello, una Iista encadenada simple contiene los descriptores de ambitos, La estructura exec_domain. definida en el archi vo < 1 Lnux / per s ona 1 i ty . h>, describe los elementos de esta lista:

tipo ClJl1l{)O MscripciOn
const char • name Nombre del ambito
lca117_func handler Direccion de 1a funci6n Hamada si el proceso efecnia
una Ilamada a1 sistema par un salta intrasegmento al
segmento mlmero 1 (metoda de lIamada utilizado par
System V y BSD Unix)
unsigned char pers_low C6digo de la personaJidad asociada al ambito
unsigned char pers_high C6digo de 1a personaJidad asociada a1 ambito 84

Programaci6n Linux 2.0

uns i.qned long * signal...JMP Tabla de correspondencias que permite convertir los ndmeros de sei\al.es proporcionados por el proceso que llama

W1Signed. long * signal_invmap Tabla de correspondencias que permite convertlr los

numeros de seftales enviados al proceso que llama

long * use_count Numero de procesos que utilizan este ambito

struct exec_dcmain * next Puntero al descriptor del ambito siguiente en la lista

La variable exec_domains. definida en el archivo fuente kerneVexec_domain.c. contiene la direcci6n del primer descriptor de la lista. En el arranque del sistema. la lista se inicializa y 5610 contiene un elernento, llamado defaul t_exec . domain. que define la personalidad de Linux.

5.6 Formatos de los archivos ejecutables

Linux soporta varies fonnatos de programas ejecutables, como los binarios a.out y ELF. A cada fonnato se Ie asocian varias funciones de manipulaci6n de los programas . ejecutables.

La estructura linux_binfmt. definida en el archivo de cabecera <linux/ binfmts. h>. contiene los punteros que son necesarios:

• int (*load_binary) (struct linux_binprm *binprm, struct pt_regs *regs)

Esta funci6n se llama para cargar un programa ejecutable en memoria en la ejecuci6n de la Hamada al sistema execve. EI primer parametro especifica el program a a ejecutar as! como su contexto; el segundo parametro indica el valor de los registros a posicionar.

• int (*load_shlib) (int fd)

Esta funci6n se llama para cargar una biblioteca compartida en memoria. EI parametro fd especifica el descriptor de entradaslsalidas asociado al archivo que contiene la biblioteca compartida.

• int (*core_dump) (long signr, struct pt_regs *regs)

Esta funci6n se nama para crear un archive core. EI panimetro signr indica el mimero de la serial que ha causado la tenninaci6n del proceso, y regs especifica el contexte del proceso en la recepcion de la seftal.

Procesos

85

La funci6n de carga de un ejecutable, load_binary, utiliza su primer parametro para conocer el contexte del proceso. La estructura 1 inux_binprm, definida en el archivo < 1 i nux I binfmt s . h>, se utiliza a este efecto y contiene los campos siguientes:

Ii po campo I u.rcripciOn
char [1281 buf Primeros 128 bytes del archi vo ejecutable
unsigned page Direcciones de las paginas de memoria que contiencn los
long [MAXJRG_PAGES] argumentos
int sh....bang 800Jeano que indica si se ha interpretado ya una Jfnea del
tipo • !nati:lr8_interprete
struct inode * inode Descriptor del i-nodo del archivo a ejecutar
int e_uid Jdentificador de usuario efectlvo
int e_gid Identificador de grupo efectivo
int argc Ndmero de argumentos
int envc Ndmero de variables de entorno
char * filename Nombre del archivo a ejecutar
unsigned long loader Campo utilizado solamente en 1a arquitectura Alpha
int dont_lput 800leano que indica si debe lIamane a la funci6n iput
para liberer el descriptor del i-nodo 6 Presentaci6n detallada de la implementaci6n

6.1 Funciones intemas

6.1.1 Sincronizaci6n de procesos

EI archivo fuente kemel/sched.c contiene funciones de servicio que penniten la sincronizaci6n de procesos en modo micleo. Estas funciones se utilizan en todas las partes del mlcleo cuando un proceso debe suspenderse en espera de un evento, y cuando debe ser «despertado».

La funci6n add_to_runqueue inserta un descriptor de proceso en la lista de procesos a punto. La funci6n del_from_runqueue pennite suprimir un descriptor de esta lista, Un descriptor de proceso puede colocarse at fin de la lista por la funci6n move_last_runqueue.

La funci6n wake_up_process despierta un proceso suspendido: pone su estado a TASK_RUNNING y 10 inserta en la lista de procesos a punta.

Вам также может понравиться