¿Por qué los números de llamada del sistema Linux en x86 y x86_64 son diferentes?


35

Sé que la interfaz de llamada del sistema se implementa en un nivel bajo y, por lo tanto, depende de la arquitectura / plataforma, no del código "genérico".

Sin embargo, no puedo ver claramente la razón por la cual las llamadas al sistema en núcleos Linux x86 de 32 bits tienen números que no se mantienen iguales en la arquitectura similar Linux 64 bits x86_64. ¿Cuál es la motivación / razón detrás de esta decisión?

Mi primera suposición ha sido que una razón de fondo ha sido mantener las aplicaciones de 32 bits ejecutables en un sistema x86_64, de modo que a través de un desplazamiento razonable al número de llamada del sistema, el sistema sabría que el espacio de usuario es de 32 bits o 64 bits respectivamente. Sin embargo, este no es el caso. Al menos me parece que read () siendo el número de llamada del sistema 0 en x86_64 no puede alinearse con este pensamiento.

Otra suposición ha sido que cambiar los números de llamada del sistema podría tener un fondo de seguridad / endurecimiento, algo que no pude confirmar.

Al ignorar los desafíos de la implementación de las partes del código dependientes de la arquitectura, todavía me pregunto cómo cambiar los números de llamada del sistema , cuando parece que no es necesario (ya que incluso un registro de 16 bits almacenaría en gran medida más que los ~ 346 números actuales para representar a todos llamadas), ayudaría a lograr cualquier cosa, que no sea romper la compatibilidad (aunque el uso de las llamadas del sistema a través de una biblioteca, libc, lo mitiga).


3
Creo que estás haciendo la pregunta equivocada. La pregunta correcta es por qué mantenerlos iguales: responder compatibilidad. Entonces, si x86 y x86_64 son incompatibles, entonces no hay fuerzas para evitar que cambien. Ahora todas las fuerzas de los últimos 20 años que querían un cambio dominarán (tenemos la oportunidad de cambiarlas). [Tenga en cuenta que esto es solo una opinión y no se basa en la mente interna de los diseñadores del nuevo sistema.]
ctrl-alt-delor

Respuestas:


34

En cuanto al razonamiento detrás de la numeración específica, que no coincide con ninguna otra arquitectura [excepto "x32", que en realidad es solo parte de la arquitectura x86_64]: En los primeros días del soporte x86_64 en el kernel de Linux, antes de que hubiera graves restricciones de compatibilidad con versiones anteriores, todas las llamadas al sistema se volvieron a numerar para optimizarlo en el nivel de uso de la línea de caché .

No sé lo suficiente sobre el desarrollo del kernel para conocer la base específica de estas opciones, pero aparentemente hay cierta lógica detrás de la elección de renumerar todo con estos números en particular en lugar de simplemente copiar la lista de una arquitectura existente y eliminar los no utilizados. Parece que el orden puede basarse en la frecuencia con la que se les llama, por ejemplo, leer / escribir / abrir / cerrar son por adelantado. Salir y bifurcar puede parecer "fundamental", pero cada uno se llama solo una vez por proceso.

También puede estar sucediendo algo acerca de mantener las llamadas del sistema que se usan comúnmente juntas dentro de la misma línea de caché (estos valores son solo enteros, pero hay una tabla en el núcleo con punteros de función para cada uno, por lo que cada grupo de 8 llamadas del sistema ocupa una línea de caché de 64 bytes para esa tabla)


1
fork may seem "fundamental", but [...] called only once per process.¿Cómo? Entiendo que puede esperar llamar a exit una vez, pero puede bifurcarse dentro del padre y el hijo de una fork()llamada
gato el

55
@cat si ve forkque se contabiliza en el proceso secundario (es decir, lo ve como la llamada de creación del proceso), en lugar del proceso principal, la declaración de Random832 es correcta.
icarus

44
@cat OK, puedes llamar a fork () dos o tres veces, tal vez algunas más. Pero puede llamar a read () millones o incluso miles de millones de veces.
Michael Hampton

1
Sí, a eso me refería. El número de llamadas de la horquilla y el número de procesos durante la vida útil del sistema va a ser idénticos, haciendo caso omiso de detalles como init, el clon [que pueden crear procesos o hilos], etc.
Random832

15

Vea esa respuesta a la pregunta "¿Por qué los números de llamada del sistema son diferentes en amd64 linux?" en desbordamiento de pila.

Para resumir: en aras de la compatibilidad, la lista de llamadas del sistema es estable y solo puede crecer. Cuando apareció la arquitectura x86 64, el ABI (paso de argumento, valor devuelto) era diferente, por lo tanto, los desarrolladores del kernel aprovecharon la oportunidad para traer cambios que tanto habían esperado.


Genial, mi suposición fue correcta.
ctrl-alt-delor

2
Esa otra respuesta a la que se vincula es especulativa: dice "los chicos de Linux probablemente decidieron ..." (énfasis agregado). Creo que ayudaría si su respuesta aquí proporcionara alguna indicación de que aparentemente se basa en la especulación más que en la evidencia. Por cierto, un comentario más reciente publicado bajo la respuesta vinculada proporciona evidencia de que la verdadera razón no es la limpieza genérica de cruft (como esa respuesta especula), sino que se trata específicamente del "uso de la línea de caché", como se explica en la otra respuesta aquí .
DW

-3

En resumen, porque alguien pensó que "las N+1formas gratuitas de incompatibilidad de hacerlo son mejores que las Nformas". Para los arcos históricos, los números de syscall generalmente se eligen para que coincidan con algunos Unix propietarios. Pero para x86_64 los desarrolladores del kernel eran libres de elegir la numeración que quisieran. En lugar de hacer una elección simple y reutilizar una numeración existente, decidieron inventar un nuevo estándar. Luego lo hicieron de nuevo para aarch64 y muchos otros. Este es un patrón que se repite con frecuencia en el desarrollo del kernel de Linux.


3
El cambio no fue gratuito. Hay razones técnicas sólidas. Si no fuera por los requisitos de compatibilidad con versiones anteriores, también se habrían aplicado cambios similares a las arquitecturas existentes.
Jörg W Mittag

La diferencia en la numeración es 100% gratuita. No existe una ventaja técnica para ninguna numeración en particular.
R ..

2
Como explica esta otra respuesta , las llamadas al sistema se agrupan de tal manera que las llamadas al sistema que se usan juntas comparten la misma línea de caché en la tabla de llamadas al sistema. Y los números de syscall se eligen de modo que sean índices simples en esa tabla. Teóricamente, podríamos usar una capa de indirección para desacoplar la posición de una llamada al sistema en la tabla de llamadas del número del sistema, pero eso posiblemente consumiría una parte de las ganancias de rendimiento que obtenemos al colocar llamadas al sistema en la misma línea de caché.
Jörg W Mittag

@ JörgWMittag: Y eso es obviamente una optimización prematura y no una mejora medible. Solo observe cuántos ciclos toman las llamadas al sistema y cuántas líneas de caché expulsan. Guardar en el mejor de los casos una línea de caché desde el pedido de la tabla no hará la diferencia.
R ..

2
@R .. "Elegí la numeración en función de la información de perfiles de kernel tpcc con DBMS populares y salida de algunas aplicaciones de red y de escritorio". ciertamente suena como si hubiera mediciones. Sin embargo, el autor no proporcionó números o explicó adecuadamente la metodología.
user45891
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.