config.in
Se configura el menú de openMosix que se mostrarán en el front-end de configuración, invocado por ejemplo por el comando make menuconfig. Véase el código:
comment 'openMosix'
bool 'openMosix process migration support' CONFIG_MOSIX
if [ "$CONFIG_MOSIX" = "y" ]; then
bool 'Support clusters with a complex network topology' CONFIG_MOSIX_TOPOLOGY
if [ "$CONFIG_MOSIX_TOPOLOGY" = "y" ]; then
int 'Maximum network-topology complexity to support (2-10)' CONFIG_MOSIX_MAXTOPOLOGY 4
fi
bool 'Stricter security on openMosix ports' CONFIG_MOSIX_SECUREPORTS
int 'Level of process-identity disclosure (0-3)' CONFIG_MOSIX_DISCLOSURE 1
#bool 'Create the kernel with a "-openmosix" extension' CONFIG_MOSIX_EXTMOSIX
bool 'openMosix File-System' CONFIG_MOSIX_FS
if [ "$CONFIG_MOSIX_FS" = "y" ]; then
define_bool CONFIG_MOSIX_DFSA y
fi
bool 'Poll/Select exceptions on pipes' CONFIG_MOSIX_PIPE_EXCEPTIONS
bool 'Disable OOM Killer' CONFIG_openMosix_NO_OOM
bool 'Load Limit' CONFIG_MOSIX_LOADLIMIT
fi
endmenu
defconfig
Se guardarán todas las opciones del kernel seleccionadas por el usuario.
entry.S
Este fichero contiene todas las rutinas que manejan las llamadas a sistema. También implementa el gestor de interrupciones para los cambios de contexto en un switch de procesos.
#ifdef CONFIG_MOSIX
#include "mosasm.H" /* libreria de codigo ensamblador de openMosix */
#endif /* CONFIG_MOSIX */
Para pasar de modo sistema a modo usuario: ENTRY(system_call)
pushl %eax # save orig_eax
SAVE_ALL
GET_CURRENT(%ebx)
testb $0x02,tsk_ptrace(%ebx) # PT_TRACESYS
jne tracesys
cmpl $(NR_syscalls),%eax
jae badsys
#ifdef CONFIG_MOSIX
testl $(DTRACESYS1|DTRACESYS2),DFLAGS(%ebx)
jne adjust_trace_before_syscall
adjusted_trace:
testb $DREMOTE,DFLAGS(%ebx)
je local_syscall
on_remote:
pushl %eax
call *SYMBOL_NAME(remote_sys_call_table)(,%eax,4)
addl $4,%esp
movl %eax,EAX(%esp)
jmp ret_from_sys_call
local_syscall:
#endif /* CONFIG_MOSIX */
call *SYMBOL_NAME(sys_call_table)(,%eax,4)
movl %eax,EAX(%esp) # save the return value
#ifdef CONFIG_MOSIX
call SYMBOL_NAME(mosix_local_syscall)
#endif /* CONFIG_MOSIX */
ENTRY(ret_from_sys_call)
#ifdef CONFIG_MOSIX
testl $(DTRACESYS1|DTRACESYS2),DFLAGS(%ebx)
jne adjust_trace_before_syscall
ret_check_reschedule:
#endif /* CONFIG_MOSIX */
cli # need_resched and signals atomic test
cmpl $0,need_resched(%ebx)
jne reschedule
cmpl $0,sigpending(%ebx)
jne signal_return
#ifdef CONFIG_MOSIX
straight_to_mosix:
call SYMBOL_NAME(mosix_pre_usermode_actions)
testl %eax,%eax
jne ret_from_sys_call
#endif /* CONFIG_MOSIX */
restore_all:
RESTORE_ALL
ALIGN
signal_return:
sti # we can get here from an interrupt handler
testl $(VM_MASK),EFLAGS(%esp)
movl %esp,%eax
jne v86_signal_return
xorl %edx,%edx
call SYMBOL_NAME(do_signal)
#ifdef CONFIG_MOSIX
jmp straight_to_mosix
#else
jmp restore_all
#endif /* CONFIG_MOSIX */
ALIGN
v86_signal_return:
call SYMBOL_NAME(save_v86_state)
movl %eax,%esp
xorl %edx,%edx
call SYMBOL_NAME(do_signal)
#ifdef CONFIG_MOSIX
jmp straight_to_mosix
#else
jmp restore_all
#endif /* CONFIG_MOSIX */
ALIGN
tracesys:
movl $-ENOSYS,EAX(%esp)
call SYMBOL_NAME(syscall_trace)
#ifdef CONFIG_MOSIX
adjust_trace_before_syscall: # only arrive here with DTRACESYS(1|2)
testl $DDEPUTY,DFLAGS(%ebx)
jne straight_to_mosix # no mess with signals/syscalls/tracesys
testl $DREMOTE,DFLAGS(%ebx)
je no_need_to_unsync
call wait_for_permission_to_continue
no_need_to_unsync:
testl $DTRACESYS2,DFLAGS(%ebx)
jne second_tracesys # skipping system-call
orl $DTRACESYS2,DFLAGS(%ebx) # next time we skip the system-call
movl $-ENOSYS,EAX(%esp)
movl ORIG_EAX(%esp),%eax
cmpl $(NR_syscalls),%eax
jae second_tracesys # prevent system-call out of range trick
jmp adjusted_trace # now do the system-call
second_tracesys: # note: "syscall_trace" clears the flags
#else
movl ORIG_EAX(%esp),%eax
cmpl $(NR_syscalls),%eax
jae tracesys_exit
call *SYMBOL_NAME(sys_call_table)(,%eax,4)
movl %eax,EAX(%esp) # save the return value
tracesys_exit:
#endif /* CONFIG_MOSIX */
call SYMBOL_NAME(syscall_trace)
jmp ret_from_sys_call
badsys:
movl $-ENOSYS,EAX(%esp)
jmp ret_from_sys_call
ALIGN
ENTRY(ret_from_intr)
GET_CURRENT(%ebx)
ret_from_exception:
movl EFLAGS(%esp),%eax # mix EFLAGS and CS
movb CS(%esp),%al
testl $(VM_MASK | 3),%eax # return to VM86 mode or non-supervisor?
#ifdef CONFIG_MOSIX
jne ret_check_reschedule
#else
jne ret_from_sys_call
#endif /* CONFIG_MOSIX */
jmp restore_all
ALIGN
reschedule:
call SYMBOL_NAME(schedule) # test
jmp ret_from_sys_call
i387.c
Guarda el contexto de los registros eprtenecientes al coprocesador i387.
ioport.c
Este fichero gestiona un mapa de bits que corresponden a los permisos que posee un proceso sobre los dispositivos de E/S.
static void set_bitmap()
Configura la máscara de permisos, esto no difiere del codigo del kernel vanilla de Linux. Al mapa bitmap se guarda el valor turn_on.
static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value)
{
int mask;
unsigned long *bitmap_base = bitmap + (base >> 5);
unsigned short low_index = base & 0x1f;
int length = low_index + extent;
if (low_index != 0) {
mask = (~0 << low_index);
if (length < 32)
mask &= ~(~0 << length);
if (new_value)
*bitmap_base++ |= mask;
else
*bitmap_base++ &= ~mask;
length -= 32;
}
mask = (new_value ? ~0 : 0);
while (length >= 32) {
*bitmap_base++ = mask;
length -= 32;
}
if (length > 0) {
mask = ~(~0 << length);
if (new_value)
*bitmap_base++ |= mask;
else
*bitmap_base++ &= ~mask;
}
}
asmlinkage int sys_ioperm()
Esta función modifica los permisos de E/S para el proceso en curso. Se invocará cuando un proceso deba dejar de mapear memoria del dispositivo de E/S o, en el caso de openMosix, cuando un proceso migrado quiera acceder a un dispositivo que se encuentre local al UHN.
asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
{
struct thread_struct * t = ¤t->thread; /*proceso en curso */
struct tss_struct * tss = init_tss + smp_processor_id();
if ((from + num <= from) || (from + num > IO_BITMAP_SIZE*32))
return -EINVAL;
if (turn_on && !capable(CAP_SYS_RAWIO))
return -EPERM;
#ifdef CONFIG_MOSIX /* si openmosix debe devolver el */
if(turn_on && !mosix_go_home_for_reason(1, DSTAY_FOR_IOPL))
return(-ENOMEM); /* proceso a su UHN por razones de E/S */
#endif /* CONFIG_MOSIX */
/* Si el proceso aun no habia invocado a ioperm() se carga el mapa en memoria */
if (!t->ioperm) {
memset(t->io_bitmap,0xff,(IO_BITMAP_SIZE+1)*4);
t->ioperm = 1;
}
/* se deberan copiar las modificaciones a los threads y TSS */
/* TSS -Task State Segment. Es un segmento especifico en arquitecturas
x86 para guardar contextos hardware */
set_bitmap(t->io_bitmap, from, num, !turn_on);
if (tss->bitmap == IO_BITMAP_OFFSET) {
set_bitmap(tss->io_bitmap, from, num, !turn_on);
} else {
memcpy(tss->io_bitmap, t->io_bitmap, IO_BITMAP_BYTES);
tss->bitmap = IO_BITMAP_OFFSET; /* Activa el mapa modificado en el TSS */
}
return 0;
}
offset.c
Este fichero proporciona rutinas a las librerrías utilizadas en entry.S para las operaciones específicas de openMosix. Como:
- Desplazamientos -offsets- constantes para los registros contenidos en la estructura task_struct.
- Bits para tests de current-
dflags
- Una copia de la tabla de llamadas a sistema - remote_sys_call_table- con todas las llamadas a sistema precedidas por el prefijo remote_.