2011-11-05 2 views
10

Non riesco a trovare questa informazione da nessuna parte. Ovunque guardi, trovo le cose che si riferiscono a come appare lo stack una volta che hai premuto "main" (qualunque sia il tuo punto di ingresso), quali sarebbero gli argomenti del programma e l'ambiente, ma quello che sto cercando è come il sistema si configura lo stack per collaborare con la macro switch_to. La prima volta che si passa all'attività, sarà necessario avere EFLAGS, EBP, i registri che GCC salva e l'indirizzo di ritorno dalla funzione schedule() sullo stack puntata da "tsk-> thread-> esp", ma quello che non riesco a capire è come il kernel imposta questo stack, poiché consente a GCC di salvare i registri generici (usando i parametri di output per l'assembly inline).Qual è lo stato stack del kernel del processo Linux durante la creazione del processo?

Mi riferisco solo ai PC x86. Sto facendo ricerche sul sistema di pianificazione/processo di Linux per il mio piccolo kernel che sto tentando di scrivere e non riesco a capire cosa mi manca. So che mi manca qualcosa dal momento che Slackware è in esecuzione sul mio computer è una testimonianza del fatto che lo schedulatore funziona: P

EDIT: Mi sembra di averlo scritto male. Sto cercando informazioni su come lo stack del kernel task non è configurato come l'attività utente utente è impostata. Più in particolare, lo stack a cui tsk-> thread-> esp punta, e che "switch_to" passa a.

+0

Sembra che tu abbia due domande separate qui: 1) stack state su init di processo e 2) kernel 'schedule()' in un IRQ. Probabilmente dovresti postare una di queste domande come una nuova domanda e tenerne una di queste qui; in questo modo otterrai risposte focalizzate su ogni domanda. Su Stack Overflow, l'avvio di una domanda separata per ogni domanda è perfettamente soddisfacente. –

+0

Va bene, lo farò! Ho letto le risposte/domande qui da molto tempo, ma mai pubblicato! Grazie per il suggerimento :) Bene, lo farò in circa 5 minuti. Devo aspettare: P – Caleb1994

risposta

6

Lo stack del kernel iniziale per un nuovo processo è impostato su copy_thread(), che è una funzione specifica per l'arco. La versione x86, ad esempio, inizia in questo modo:

int copy_thread(unsigned long clone_flags, unsigned long sp, 
unsigned long unused, 
struct task_struct *p, struct pt_regs *regs) 
{ 
    struct pt_regs *childregs; 
    struct task_struct *tsk; 
    int err; 

    childregs = task_pt_regs(p); 
    *childregs = *regs; 
    childregs->ax = 0; 
    childregs->sp = sp; 

    p->thread.sp = (unsigned long) childregs; 
    p->thread.sp0 = (unsigned long) (childregs+1); 

    p->thread.ip = (unsigned long) ret_from_fork; 

p->thread.sp e p->thread.ip sono stack pointer kernel del nuovo filo e puntatore all'istruzione, rispettivamente.

Si noti che lo fa non posto un salvato %eflags, %ebp ecc lì, perché quando un thread appena creato di esecuzione viene commutato primo a, si inizia in esecuzione a ret_from_fork (questo è dove __switch_to() ritorna per una nuova thread), ovvero non esegue nella seconda metà della routine switch_to().

+0

Grazie! Questo e 'esattamente quello che stavo cercando! Non avrei mai immaginato di guardare in copy_thread. – Caleb1994

+0

@ Caleb1994: Ha senso quando si ricorda che tutti i nuovi thread di esecuzione vengono creati su Linux clonando uno esistente. Ho aggiunto un altro paragrafo alla fine che potrebbe essere utile. – caf

+1

Questo ha aiutato molto! Il mio piccolo kernel ora supporta fork() e una chiamata di tipo yield() :) Grazie mille per il tuo aiuto! – Caleb1994

2

Lo stato della pila alla creazione del processo è descritto nel supplemento X86-64 SVR4 ABI (per AMD64, ovvero macchine a 64 bit x86-64). L'equivalente per il processore Intel a 32 bit è probabilmente ABI i386. Consiglio vivamente di leggere anche Assembly HOWTO. E, naturalmente, dovresti forse leggere il file del kernel di Linux pertinente.

+0

Queste pagine descrivono lo stato della pila ** dopo ** l'esecuzione è iniziata. Il mio problema è lo stato dello stack ** prima ** dell'esecuzione. cioè quando il kernel sta configurando lo stack.Il mio unico problema è il fatto che Linux lascia il compilatore per salvare i registri di uso generale (che vengono salvati nello stack), ma il modo in cui questi vengono salvati potrebbe essere diverso a seconda del compilatore, quindi sono confuso su come il sistema imposta fino allo stack iniziale. Ho guardato attraverso il codice, ma non riesco a trovare dove viene riempito il processo. È nascosto dietro l'astrazione della macchina da qualche parte. – Caleb1994

+0

Lo stack non esiste prima dell'esecuzione. Quindi non capisco quello che vuoi. Il kernel sta costruendo lo stack del processo iniziale come descritto nella documentazione ABI. –

+0

Forse hai dimenticato che gli stack del kernel e dello spazio utente sono diversi? –

2

Google per "avvio del processo di layout di stack linux" fornisce il collegamento this: "Stato di avvio di un binario ELF Linux/i386", che descrive la configurazione che il kernel esegue appena prima del trasferimento del controllo al codice di avvio di libc.

+0

è lo stato subito dopo 'exec'? – osgx

+0

Sì, è lo stato appena prima che inizi la prima istruzione del processo. –