Forum Discussion
Altera_Forum
Honored Contributor
16 years agoLinux with MMU on NEEK
Hi, all.
I'm testing Linux MMU version, on my NEEK. http://www.nioswiki.com/linux It works fine and I can use "bash" shell. This is the evident proof that we are using the true 'fork' instead of 'vfork'. May be this will depends on the version, but TSE driver claims an error and doesn't work on this design. The error is
ERROR: altera_tse.c:1666: request_mem_region() failed
I think that this error is caused by misunderstanding of the usage for the function request_mem_region(). Inside of the request_mem_region(), the function __request_region() is called. If the resource has been already registered, this function returns a non-NULL value, that is the pointer for its resource. But the resource 'sgdma_rx_base' is already registered in the initialization process, so this function returns the 'conflict' and
if (!request_mem_region(sgdma_rx_base, sgdma_rx_size, "altera_tse")) {
is always true. So I made a dirty patch,
if (!request_mem_region(sgdma_rx_base, sgdma_rx_size, "altera_tse")) {
reg_resource = __request_region(&iomem_resource, sgdma_rx_base, sgdma_rx_size, "altera_tse", 0);
if (reg_resource != NULL && reg_resource->flags & IORESOURCE_BUSY) {
printk(KERN_ERR "ERROR: %s:%d: request_mem_region() failed\n", __FILE__, __LINE__);
ret = -EBUSY;
goto out_sgdma_rx;
}
}
Moreover, the author is forgetting that the DMA is working in the physical address world, so we need to set the pointers of descripters like
// desc->source = read_addr;
desc->source = virt_to_phys(read_addr);
// desc->destination = write_addr;
desc->destination = virt_to_phys(write_addr);
// desc->next = (unsigned int *)next;
desc->next = (unsigned int *)((unsigned long)next & 0x1fffffffUL);
and so on. Also the frame buffer fb0 will not work well, because the driver 'altfb.c' is not implemented for Linux with MMU version. So I put some codes for altfb_mmap(), like
/* We implement our own mmap to set MAY_SHARE and add the correct size */
static int altfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
unsigned long phys_addr, phys_size;
unsigned long addr;
unsigned long size = vma->vm_end - vma->vm_start;
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
// vma->vm_flags |= VM_MAYSHARE | VM_SHARED;
// vma->vm_start = info->screen_base;
// vma->vm_end = vma->vm_start + info->fix.smem_len;
/* check range */
if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
return -EINVAL;
if (offset + size > altfb_fix.smem_len)
return -EINVAL;
vma->vm_flags |= VM_IO | VM_RESERVED;
addr = vma->vm_start;
phys_addr = altfb_fix.smem_start + offset;
if ((offset + size) < altfb_fix.smem_len)
phys_size = size;
else
phys_size = altfb_fix.smem_len - offset;
vma->vm_page_prot = __pgprot(_PAGE_PRESENT|_PAGE_READ|_PAGE_WRITE);
if (remap_pfn_range(vma, addr, phys_addr >> PAGE_SHIFT, phys_size, vma->vm_page_prot))
return -EAGAIN;
return 0;
}
and rewrite the DMA descripters like
desc->next = (void *)virt_to_phys((desc + 1));
So now, I can evoke telnetd and control NEEK through ethernet, and use Nano-X on Linux MMU version, but can't enter ftp session, because 'getservbyname()' function will not work well. I don't know the directory that the souce of 'getservbyname()' is included. Would anyone please tell me where is it? Thank you, in advance.95 Replies
- Altera_Forum
Honored Contributor
Hi,
--- Quote Start --- "virtually-indexed and physically-tagged" ??? --- Quote End --- So, I think that 3) CPU |--cache --| -- Memory ............|--MMU --| is 'Bingo'. --- Quote Start --- How does this compare to ARM, that uses the cache and the MMU completely in the "wrong" order (strictly using physical addresses in the cache). Because of that, ARM-Linux needs to flush the cache completely with any task-switch. That is why for ARM systems with many task switches, not using the MMU is recommended. I sincerely hope that such a drastic method is not necessary with NIOS ! --- Quote End --- In NIOS, you don't need to flush the cache for each task-switch. But the TLB uses PID mechanism to distinguish each user tasks,
so TLB flush and loading will occur automatically. Kazuvoid set_mmu_pid(unsigned long pid) { WRCTL(CTL_TLBMISC, (RDCTL(CTL_TLBMISC) & (WAY_MASK << WAY_SHIFT)) | ((pid & PID_MASK) << PID_SHIFT)); } - Altera_Forum
Honored Contributor
Sounds good.
Is the software part already implemented in the Kernel ? Does it work ? Decent performance ? Thanks, -Michael - Altera_Forum
Honored Contributor
Hi,
--- Quote Start --- Is the software part already implemented in the Kernel ? Does it work ? --- Quote End --- Yes, of course, we are using these. Nios's TLB control parts are included in the file '/nios2-linux/linux-2.6/arch/nios2/mm/mmu_context.c, tlb.c' and cache flush functions are included in '/nios2-linux/linux-2.6/arch/nios2/mm/cacheflush.c'. But please note that the cache size is limited within 4KB. In present codes, there is no mechanism to avoid the alias problem. --- Quote Start --- Decent performance ? --- Quote End --- Though I don't have any concrete data for the performance, but I think it is not so bad. FLTK's demos. for example, 'editor' works well. It uses 'Bitblit' functionality and this is heavy task for Nios CPU and its MMU, but the scrolling speed is not so slow. Kazu - Altera_Forum
Honored Contributor
--- Quote Start --- But please note that the cache size is limited within 4KB. In present codes, there is no mechanism to avoid the alias problem. --- Quote End --- So it is not correctly implemented. All Altera example designs use much more cache ! What should we do about that ? I feel that 4K cache will degrade performance a lot.. I did not test this thoroughly, but I once did a speed test with a uCLinux vs a fill lunux design and found that the full Linux design was much slower (up to half speed). I'm not sure about the cache sizes, though . -Michael - Altera_Forum
Honored Contributor
Actually, I have it working with 32KB caches now, I'm not sure what changed (been through a few FPGA updates since I last tried it). I think at least some support for the aliasing problem is there actually - see cache_flush.c, syscall.c, Documentation/cachetlb.txt.
I did make this change, but haven't noticed any difference with or without it, but it seems more correct for the COLOUR_ALIGN macro in syscall.c and by the documentation in cachetlb.txt:--- a/arch/nios2/include/asm/shmparam.h +++ b/arch/nios2/include/asm/shmparam.h @@ -1 +1,2 @@ -#include <asm-generic/shmparam.h> +#include <asm/nios.h> +#define SHMLBA DCACHE_SIZE - Altera_Forum
Honored Contributor
Hi,
--- Quote Start --- So it is not correctly implemented. All Altera example designs use much more cache ! What should we do about that ? --- Quote End --- I'm not sure that Wind River guys had implemented a correct mechanism to deal with the 'alias problem'. So give me some time to check it. --- Quote Start --- I feel that 4K cache will degrade performance a lot.. I did not test this thoroughly, but I once did a speed test with a uCLinux vs a fill lunux design and found that the full Linux design was much slower (up to half speed). I'm not sure about the cache sizes, though --- Quote End --- Please take account of the kernel with MMU which must do many tasks compared to no-MMU version and we can enjoy many excellent features instead of its lower performance. Kazu - Altera_Forum
Honored Contributor
Hi,
--- Quote Start --- I think at least some support for the aliasing problem is there actually - see cache_flush.c, syscall.c, Documentation/cachetlb.txt. --- Quote End --- Oh, I'm sorry that my opinion " there is no mechanism to avoid the alias problem." was an overstatement. There exists the traces of implementation for 'alias problem', but I'm not sure whether these will work well or not. As mentioned in the 'Documentation/cachetlb.txt', the 'alias problem' affects only the D-cache. If we have 'alias' copies of same physical address contents, we must take special care of those flushing from the D-cache. But whether we will have the 'alias' or not depends on the functionality of Linux kernel. So the problem is a little bit difficult. It seems to me that functions 'copy_from_user_page' and 'copy_to_user_page' will work well
, beacuse these are only the 'alias problems' between user-land virtual addresses and kernel's ones. But I'm still not sure for the case of shared maps among user-lands. Kazuvoid copy_from_user_page(struct vm_area_struct *vma, struct page *page, unsigned long user_vaddr, void *dst, void *src, int len) { flush_cache_page(vma, user_vaddr, page_to_pfn(page)); memcpy(dst, src, len); flush_dcache_range((unsigned long)src, (unsigned long)src+len); if(vma->vm_flags & VM_EXEC) { flush_icache_range((unsigned long)src, (unsigned long)src+len); } } void copy_to_user_page(struct vm_area_struct *vma, struct page *page, unsigned long user_vaddr, void *dst, void *src, int len) { flush_cache_page(vma, user_vaddr, page_to_pfn(page)); memcpy(dst, src, len); flush_dcache_range((unsigned long)dst, (unsigned long)dst+len); if(vma->vm_flags & VM_EXEC) { flush_icache_range((unsigned long)dst, (unsigned long)dst+len); } } - Altera_Forum
Honored Contributor
--- Quote Start --- So give me some time to check it. --- Quote End --- Great ! Thanks, -Michael - Altera_Forum
Honored Contributor
Hi, kazu & Gurus
I'm working on using LCD in a nios2-mmu system on NEEK, I followed the instructions on nios-wiki to configure the kernel and modified altfb.c by advices of Kazu above, The result in my Linux is: "fb_test" command can be ran successfully:
but I can not run Nano-X :The framebuffer device was opened successfully. 800*480, 32bpp The framebuffer device was mapped to memory successfully.
and the image I ran is "linux.initramsfs.gz". I need your help, please give me some advice and thank you.cantnot bind to named socket - Altera_Forum
Honored Contributor
Hi.
--- Quote Start ---
--- Quote End --- At first, please check your kernel includes 'Unix domain sockets'.cantnot bind to named socket
KazuNetworking support ---> --- Networking support Networking options ---> <*> Packet socket Packet socket: mmapped IO <*> Unix domain sockets