Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
12745 ディスカッション

Linux with MMU on NEEK

Altera_Forum
名誉コントリビューター II
5,106件の閲覧回数

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.
0 件の賞賛
95 返答(返信)
Altera_Forum
名誉コントリビューター II
493件の閲覧回数

Hi, Kazu 

I appreciate your help very much! Last time I modified my altfb.c but not use 'flush_cache_all();', so I met the problem above. And this time, with your help, I made it! My Screen is working now! 

Thank you for your advices and help again! 

 

Best Regards. 

 

--Smarter.UJS
Altera_Forum
名誉コントリビューター II
493件の閲覧回数

Hi Kazuyasu-san, 

 

I just stumbled across this thread and saw your many valuable contributions (e.g. kgdb support, swap support) some of which are not yet merged into the nios2mmu Linux Kernel branch on sopc. 

 

Currently I'm in the process of merging the unstable branch (nios2 w/o MMU) into nios2mmu and also cleaning up some edges and ends of the code along the way. 

 

I'd really like to get your contributions into the tree and thus would like to Cc: you on the patches I send to the nios2-dev mailinglist for review. Could you send me your email address via private message for that? 

 

Thanks a lot 

Tobias
Altera_Forum
名誉コントリビューター II
493件の閲覧回数

Hi,  

 

What's the difference between this Linux distribution and http://nioswiki.com/@api/deki/files/296/=neek_web_server_mmu.zip? What kernel version are they? Or perhaps, in terms of SOPC, what are the difference in terms of peripherals added, other than MMU-enabled, compared to neek_ocm_spi_mmu.zip, especially with /example/standard?  

 

Where can I find full featured SOPC for NEEK? Where can I find Linux distribution for kernel version 2.6.32? 

 

I am looking for ethernet for NFS and LCD with touch screen for display. 

 

Thanks for your help, Wiki still confuses me.
Altera_Forum
名誉コントリビューター II
493件の閲覧回数

Hi, 

 

 

--- Quote Start ---  

 

Where can I find full featured SOPC for NEEK? Where can I find Linux distribution for kernel version 2.6.32? 

 

I am looking for ethernet for NFS and LCD with touch screen for display. 

 

Thanks for your help, Wiki still confuses me. 

 

--- Quote End ---  

 

 

The Linux with MMU for Nios2 distribution is still under construction, and you must solve many problems by yourself. Frankly speaking, I think it is a little bit hard to rebuild the kernel for linux and Nios beginners. 

 

Kazu
Altera_Forum
名誉コントリビューター II
493件の閲覧回数

Hi, 

 

The previous version of 'kgdb' will not read the Nios's registers r17~r23.  

 

http://www.alteraforum.com/forum/showpost.php?p=77003&postcount=20 

 

But the kernel sometimes uses those for the locations of its local variables, so we must read and write the registers r17~r23. To do this, please add codes to the file 'entry.S' 

handle_diverror: call handle_illegal_c br ret_from_exception # ifdef CONFIG_KGDB handle_kgdb_breakpoint: SAVE_SWITCH_STACK // <-- Add this. call kgdb_breakpoint_c RESTORE_SWITCH_STACK // <-- Add this. br ret_from_exception# endif and modify the file 'kgdb.c' of the nios arch like 

 

void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) { gdb_regs = 0; gdb_regs = regs->r1; gdb_regs = regs->r2; gdb_regs = regs->r3; gdb_regs = regs->r4; gdb_regs = regs->r5; gdb_regs = regs->r6; gdb_regs = regs->r7; gdb_regs = regs->r8; gdb_regs = regs->r9; gdb_regs = regs->r10; gdb_regs = regs->r11; gdb_regs = regs->r12; gdb_regs = regs->r13; gdb_regs = regs->r14; gdb_regs = regs->r15; gdb_regs = regs->ra; gdb_regs = regs->fp; gdb_regs = regs->sp; gdb_regs = regs->gp; gdb_regs = regs->estatus; gdb_regs = regs->ea; gdb_regs = regs->ea; { struct switch_stack *swregs = (struct switch_stack *)regs; swregs--; gdb_regs = swregs->r16; gdb_regs = swregs->r17; gdb_regs = swregs->r18; gdb_regs = swregs->r19; gdb_regs = swregs->r20; gdb_regs = swregs->r21; gdb_regs = swregs->r22; gdb_regs = swregs->r23; } } void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) { regs->r1 = gdb_regs; regs->r2 = gdb_regs; regs->r3 = gdb_regs; regs->r4 = gdb_regs; regs->r5 = gdb_regs; regs->r6 = gdb_regs; regs->r7 = gdb_regs; regs->r8 = gdb_regs; regs->r9 = gdb_regs; regs->r10 = gdb_regs; regs->r11 = gdb_regs; regs->r12 = gdb_regs; regs->r13 = gdb_regs; regs->r14 = gdb_regs; regs->r15 = gdb_regs; regs->ra = gdb_regs; regs->fp = gdb_regs; regs->sp = gdb_regs; regs->gp = gdb_regs; regs->estatus = gdb_regs; regs->ea = gdb_regs; { struct switch_stack *swregs = (struct switch_stack *)regs; swregs--; swregs->r16 = gdb_regs; swregs->r17 = gdb_regs; swregs->r18 = gdb_regs; swregs->r19 = gdb_regs; swregs->r20 = gdb_regs; swregs->r21 = gdb_regs; swregs->r22 = gdb_regs; swregs->r23 = gdb_regs; } }

 

Kazu
Altera_Forum
名誉コントリビューター II
493件の閲覧回数

 

--- Quote Start ---  

Hi, 

 

 

 

The Linux with MMU for Nios2 distribution is still under construction, and you must solve many problems by yourself. Frankly speaking, I think it is a little bit hard to rebuild the kernel for linux and Nios beginners. 

 

Kazu 

--- Quote End ---  

 

 

I am now confused with your answer compared to nioswiki, and what things unresolved to have a full-running Linux (uClinux + MMU) in Nios2 distribution?
Altera_Forum
名誉コントリビューター II
493件の閲覧回数

Hi, 

 

 

--- Quote Start ---  

I am now confused with your answer compared to nioswiki, and what things unresolved to have a full-running Linux (uClinux + MMU) in Nios2 distribution? 

--- Quote End ---  

 

 

I'm using the Linux version 2.6.30 with my patches individually. And these patches are described all in this thread, but not included into the community distribution. (I don't know the reason.) 

So if you want to use NEEK's LCD and ether-net , please read this thread and apply the patches that you need. Or if you only want to use the pre-compiled NEEK's hardware and its kernel, I will attach those. 

 

Kazu
Altera_Forum
名誉コントリビューター II
493件の閲覧回数

 

--- Quote Start ---  

 

I'm using the Linux version 2.6.30 with my patches individually. And these patches are described all in this thread, but not included into the community distribution. (I don't know the reason.) 

Kazu 

--- Quote End ---  

 

Hi Kazu, 

 

The community distribution is maintained through this mailing list: 

http://sopc.et.ntust.edu.tw/cgi-bin/mailman/listinfo/nios2-dev 

 

I think it would be awesome if you could submit your patches -- you seem very knowledgeable and very helpful on this forum. The maintainers have been offering git accounts so active contributors can commit directly as well.
Altera_Forum
名誉コントリビューター II
493件の閲覧回数

 

--- Quote Start ---  

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. 

 

--- Quote End ---  

 

The current altera_tse code works, but does not do this translation. Any idea why setting virtual addresses here actually does work?
Altera_Forum
名誉コントリビューター II
493件の閲覧回数

Hi, 

 

 

--- Quote Start ---  

The current altera_tse code works, but does not do this translation. Any idea why setting virtual addresses here actually does work? 

--- Quote End ---  

 

 

In the kernel, a physical address 0x00000000 is translated to the virtual address 0xc0000000 for cached area or 0xe0000000 for non-cached area. For the DMA registers, we must convert these virtual addresses to physical ones again, but the range of physical addresses are limited within 0x00000000~0x1fffffff (that means totally 512MBytes), so the DMA does not use upper 3 bits. Thus we don't need to use the function virt_to_phys(...), because the DMA and Avalon bus will ignore upper 3bits automatically, but this is wrong from the view point of the logic. 

 

Kazu
Altera_Forum
名誉コントリビューター II
493件の閲覧回数

 

--- Quote Start ---  

Hi, 

 

 

 

In the kernel, a physical address 0x00000000 is translated to the virtual address 0xc0000000 for cached area or 0xe0000000 for non-cached area. For the DMA registers, we must convert these virtual addresses to physical ones again, but the range of physical addresses are limited within 0x00000000~0x1fffffff (that means totally 512MBytes), so the DMA does not use upper 3 bits. Thus we don't need to use the function virt_to_phys(...), because the DMA and Avalon bus will ignore upper 3bits automatically, but this is wrong from the view point of the logic. 

 

Kazu 

--- Quote End ---  

 

Thanks for the explanation Kazu, I was getting to that conclusion. Just to clarify -- these are kernel virtual addresses (e.g. from kmalloc()) if given an address from vmalloc() this would not work, right?
Altera_Forum
名誉コントリビューター II
493件の閲覧回数

Hi, 

 

 

--- Quote Start ---  

Just to clarify -- these are kernel virtual addresses (e.g. from kmalloc()) if given an address from vmalloc() this would not work, right? 

--- Quote End ---  

 

 

Yes, it's right. For the difference of the 'kmalloc()' and 'vmalloc()', please refer the next site. 

 

http://book.chinaunix.net/special/ebook/linux_kernel_development/0672327201/ch11lev1sec5.html 

 

Of course, the kernel can access the address area from vmalloc(), but must use MMU and page tables, so the 'pure' hardware like DMA can't access those without complicated address conversions, while kmalloc() uses simple straight mapping like 0xC0000000 to 0x00000000. 

 

Kazu
返信