Hi,
--- Quote Start ---
Is this confirmed by the hardware Gurus ?
--- Quote End ---
No, not yet. But where is the nest of MMU's Gurus?
--- Quote Start ---
I can't believe that Altera would choose such a silly implementation.
--- Quote End ---
Yes, of course, I want to believe that Altera is NOT silly. But the bit order of tlbacc register is silly, there is no present bit, it's silly...
Now I tested the 'modprobe' and system call 'init_module'. It works, but unfortunately, the module is loaded in the 'vmalloc' area(0x80000000~). Nios instructions 'call' and 'jmpi' can't jump beyond the boundary of 256MBytes. So the kernel can't reach the module codes and module codes can't call kernel routines.
The easiest way to solve this problem is to change 'vmalloc' to 'kmalloc' in the function 'load_module' of the file '/kernel/module.c', as follows.
/* Allocate and load the module: note that size of section 0 is always
zero, and we rely on this for optional sections. */
static noinline struct module *load_module(void __user *umod,
unsigned long len,
const char __user *uargs)
{
Elf_Ehdr *hdr;
Elf_Shdr *sechdrs;
char *secstrings, *args, *modmagic, *strtab = NULL;
char *staging;
unsigned int i;
unsigned int symindex = 0;
unsigned int strindex = 0;
unsigned int modindex, versindex, infoindex, pcpuindex;
unsigned int num_mcount;
struct module *mod;
long err = 0;
void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
unsigned long *mseg;
mm_segment_t old_fs;
DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
umod, len, uargs);
if (len < sizeof(*hdr))
return ERR_PTR(-ENOEXEC);
/* Suck in entire file: we'll want most of it. */
/* vmalloc barfs on "unusual" numbers. Check here */
// if (len > 64 * 1024 * 1024 || (hdr = vmalloc(len)) == NULL)
if (len > 64 * 1024 * 1024 || (hdr = kmalloc(len, GFP_KERNEL)) == NULL)
return ERR_PTR(-ENOMEM);
if (copy_from_user(hdr, umod, len) != 0) {
err = -EFAULT;
goto free_hdr;
}
/* Sanity checks against insmoding binaries or wrong arch,
weird elf version */
if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0
|| hdr->e_type != ET_REL
|| !elf_check_arch(hdr)
|| hdr->e_shentsize != sizeof(*sechdrs)) {
err = -ENOEXEC;
goto free_hdr;
}
............................
err = mod_sysfs_setup(mod, mod->kp, mod->num_kp);
if (err < 0)
goto unlink;
add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
add_notes_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
/* Get rid of temporary copy */
// vfree(hdr);
kfree(hdr);
/* Done! */
return mod;
unlink:
/* Unlink carefully: kallsyms could be walking list. */
list_del_rcu(&mod->list);
synchronize_sched();
module_arch_cleanup(mod);
cleanup:
kobject_del(&mod->mkobj.kobj);
kobject_put(&mod->mkobj.kobj);
ftrace_release(mod->module_core, mod->core_size);
free_unload:
module_unload_free(mod);# if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP)
free_init:
percpu_modfree(mod->refptr);# endif
module_free(mod, mod->module_init);
free_core:
module_free(mod, mod->module_core);
/* mod will be freed with core. Don't access it beyond this line! */
free_percpu:
if (percpu)
percpu_modfree(percpu);
free_mod:
kfree(args);
free_hdr:
// vfree(hdr);
kfree(hdr);
return ERR_PTR(err);
truncated:
printk(KERN_ERR "Module len %lu truncated\n", len);
err = -ENOEXEC;
goto free_hdr;
}
Yes, OK, I'm sure. It's the file inside the directory /linux-2.6/kernel !:eek:
But don't tell Linus about this tampering...
Kazu