Perché i numeri di chiamata del sistema Linux in x86 e x86_64 sono diversi?


35

So che l'interfaccia di chiamata di sistema è implementata su un livello basso e quindi codice di architettura / piattaforma dipendente, non "generico".

Tuttavia, non riesco a vedere chiaramente il motivo per cui le chiamate di sistema nei kernel x86 a 32 bit di Linux hanno numeri che non sono mantenuti uguali nell'architettura simile a Linux x86_64 a 64 bit? Qual è la motivazione / ragione dietro questa decisione?

La mia prima ipotesi è stata che un motivo di fondo è stato quello di mantenere le applicazioni a 32 bit eseguibili su un sistema x86_64, in modo che tramite un ragionevole offset al numero di chiamata del sistema il sistema sapesse che lo spazio utente è 32-bit o 64-bit rispettivamente. Questo non è tuttavia il caso. Almeno mi sembra che read () essendo il numero di chiamata di sistema 0 in x86_64 non possa essere allineato con questo pensiero.

Un'altra ipotesi è stata che la modifica dei numeri di chiamata del sistema potrebbe avere un background di sicurezza / protezione, qualcosa che non sono stato in grado di confermare.

Essendo ignaro delle sfide legate all'implementazione delle parti di codice dipendenti dall'architettura, mi chiedo ancora come cambiare i numeri di chiamata del sistema , quando non sembra necessario (poiché anche un registro a 16 bit memorizzerebbe molto più dei numeri attualmente ~ 346 per rappresentare tutto chiamate), aiuterebbe a ottenere qualsiasi cosa, oltre a interrompere la compatibilità (sebbene l'uso delle chiamate di sistema attraverso una libreria, libc, la mitiga).


3
Penso che tu stia facendo la domanda sbagliata. La domanda corretta è perché mantenerli uguali: rispondi alla compatibilità. Quindi se x86 e x86_64 sono incompatibili, allora non ci sono forze per impedire che cambino. Ora tutte le forze degli ultimi 20 anni che volevano il cambiamento domineranno (avremo la possibilità di cambiarle). [Nota che questa è solo un'opinione e non basata sulla mente interiore dei progettisti del nuovo sistema.]
ctrl-alt-delor

Risposte:


34

Per quanto riguarda il ragionamento alla base della numerazione specifica, che non corrisponde a nessun'altra architettura [tranne "x32" che è in realtà solo parte dell'architettura x86_64]: Nei primissimi giorni del supporto x86_64 nel kernel di Linux, prima che ci fossero gravi vincoli di compatibilità con le versioni precedenti, tutte le chiamate di sistema sono state rinumerate per ottimizzarle a livello di utilizzo della cache .

Non so abbastanza sullo sviluppo del kernel per conoscere le basi specifiche di queste scelte, ma a quanto pare c'è una logica dietro la scelta di rinumerare tutto con questi numeri particolari piuttosto che semplicemente copiare l'elenco da un'architettura esistente e rimuovere quelli inutilizzati. Sembra che l'ordine possa essere basato sulla frequenza con cui vengono chiamati, ad esempio read / write / open / close sono in primo piano. Exit e fork possono sembrare "fondamentali", ma ciascuno di essi viene chiamato una sola volta per processo.

Potrebbe anche succedere qualcosa riguardo al mantenimento delle chiamate di sistema che sono comunemente usate insieme nella stessa linea di cache (questi valori sono solo numeri interi, ma c'è una tabella nel kernel con puntatori di funzione per ognuno, quindi ogni gruppo di 8 chiamate di sistema occupa una riga della cache a 64 byte per quella tabella)


1
fork may seem "fundamental", but [...] called only once per process.Cosa? Capisco che potresti aspettarti di chiamare exit una volta, ma puoi biforcarti tra genitore e figlio di una fork()chiamata
cat

5
@cat se si considera il processo forkcome account del processo figlio (ovvero lo si visualizza come la chiamata di creazione del processo), piuttosto che il processo padre, l'istruzione di Random832 è corretta.
Icaro

4
@cat OK, potresti chiamare fork () due o tre volte, forse qualche altro. Ma puoi chiamare read () milioni o addirittura miliardi di volte.
Michael Hampton,

1
Sì, questo è ciò che intendevo. Il numero di chiamate fork e il numero di processi per tutta la durata del sistema saranno identici, ignorando dettagli come init, clone [che può creare processi o thread], ecc.
Casuale 832

15

Vedi quella risposta alla domanda "Perché i numeri di chiamata di sistema sono diversi in Linux amd64?" su Stack Overflow.

Per riassumere: per motivi di compatibilità, l'elenco delle chiamate di sistema è stabile e può solo crescere. Quando è apparsa l'architettura x86 64, l'ABI (passaggio degli argomenti, valore restituito) era diverso, quindi gli sviluppatori del kernel hanno colto l'occasione per apportare cambiamenti che erano attesi da tempo.


Fantastico, la mia ipotesi era corretta.
ctrl-alt-delor

2
L'altra risposta a cui ti colleghi è speculativa: dice " molto probabilmente i ragazzi di Linux hanno deciso ..." (enfasi aggiunta). Penso che sarebbe utile se la tua risposta qui fornisse qualche indicazione che apparentemente si basa sulla speculazione piuttosto che sulla prova. Per inciso, un commento più recente pubblicato sotto la risposta collegata fornisce la prova che la vera ragione non è la pulizia generica della cruft (come ipotizza tale risposta), ma riguarda in particolare "l'utilizzo della cacheline", come spiegato nell'altra risposta qui .
DW

-3

In breve, perché qualcuno pensava che "i N+1modi di farlo gratuitamente sono incompatibili con i Nmodi". Per gli archi storici, i numeri di syscall erano generalmente scelti per abbinare alcuni unix proprietari legacy. Ma per x86_64 gli sviluppatori del kernel erano liberi di scegliere qualsiasi numerazione che gli piaceva. Piuttosto che fare la scelta semplice e riutilizzare una numerazione esistente, hanno fatto la scelta di inventare un nuovo standard. Poi l'hanno fatto di nuovo per aarch64 e molti altri. Questo è un modello spesso ripetuto nello sviluppo del kernel Linux.


3
Il cambiamento non è stato gratuito. Ci sono solide ragioni tecniche. Se non fosse stato per i requisiti di compatibilità con le versioni precedenti, modifiche simili sarebbero state applicate anche alle architetture esistenti.
Jörg W Mittag,

La differenza nella numerazione è gratuita al 100%. Non vi è alcun vantaggio tecnico in nessuna particolare numerazione.
R ..

2
Come spiega questa altra risposta , i syscall sono raggruppati in modo tale che i syscall che sono comunemente usati insieme condividano la stessa cache nella tabella dei syscall. E i numeri di syscall sono scelti in modo tale da essere semplici indici in quella tabella. Teoricamente, potremmo usare uno strato di riferimento indiretto per disaccoppiare la posizione di un syscall nella tabella di syscall dal numero di syscall, ma ciò probabilmente consumerebbe una parte dei guadagni di prestazioni che otteniamo dal mettere syscalls caldi nella stessa cache.
Jörg W Mittag,

@ JörgWMittag: E questa è ovviamente un'ottimizzazione prematura e non un miglioramento misurabile. Guarda quanti cicli impiegano le syscall e quante linee cache sfrattano. Il salvataggio al massimo di una riga della cache dall'ordinamento della tabella non farà alcuna differenza.
R ..

2
@R .. "Ho scelto la numerazione in funzione delle informazioni di profilazione del kernel tpcc con DBMS popolare e output di traccia di alcune applicazioni di rete e desktop." certamente suona come se ci fossero misurazioni. Tuttavia, l'autore non ha fornito numeri o ha spiegato adeguatamente la metodologia.
user45891
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.