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, Kazu
Thank you for your response, the problem has been solved by your advice. But the new confusion was that nothing appeared on the screen and Nano-X seemed running correctly:
And the linux init messages is below/# nano-X & 686 nano-X /# nanowm & 687 nanowm /# nxclock & 688 nxclock
please give me some advices when your are free, and thank you again. --Smarter.UJS$ nios2-terminal nios2-terminal: connected to hardware target using JTAG UART on cable nios2-terminal: "USB-Blaster ", device 1, instance 1 nios2-terminal: (Use the IDE stop button or Ctrl-C to terminate) Linux version 2.6.30-00494-g84a224b-dirty (alex@alex-desktop) (gcc version 4.1.2)# 38 Thu Aug 12 16:36:39 CST 2010 console enabled Early printk initialized Linux/Nios II-MMU init_bootmem_node(?,0x50c, 0x0, 0x2000) free_bootmem(0x50c000, 0x1af4000) reserve_bootmem(0x50c000, 0x400) Built 1 zonelists in Zone order, mobility grouping on. Total pages: 8128 Kernel command line: NR_IRQS:32 PID hash table entries: 128 (order: 7, 512 bytes) Console: colour dummy device 80x25 Dentry cache hash table entries: 4096 (order: 2, 16384 bytes) Inode-cache hash table entries: 2048 (order: 1, 8192 bytes) We have 8192 pages of RAM Memory available: 27300k/5165k RAM, 0k/0k ROM (1577k kernel code, 3588k data) Calibrating delay loop... 49.25 BogoMIPS (lpj=246272) Mount-cache hash table entries: 512 net_namespace: 296 bytes NET: Registered protocol family 16 init_BSP(): registering device resources bio: create slab <bio-0> at 0 NET: Registered protocol family 2 IP route cache hash table entries: 1024 (order: 0, 4096 bytes) TCP established hash table entries: 1024 (order: 1, 8192 bytes) TCP bind hash table entries: 1024 (order: 0, 4096 bytes) TCP: Hash tables configured (established 1024 bind 1024) TCP reno registered NET: Registered protocol family 1 msgmni has been set to 53 io scheduler noop registered io scheduler anticipatory registered io scheduler deadline registered io scheduler cfq registered (default) fb0: Altera FB frame buffer device ttyJ0 at MMIO 0x8001410 (irq = 7) is a Altera JTAG UART console handover: boot -> real altps2 : base e8001420 irq 9 mice: PS/2 mouse device common for all mice TCP cubic registered NET: Registered protocol family 17 atkbd.c: keyboard reset failed on altps2.0 Welcome to ____ _ _ / __| ||_| _ _| | | | _ ____ _ _ _ _ | | | | | | || | _ \| | | |\ \/ / | |_| | |__| || | | | | |_| |/ | ___\____|_||_|_| |_|\____|\_/\_/ | | |_| For further information check: http://www.uclinux.org/ BusyBox v1.15.1 (2010-08-12 16:35:17 CST) hush - the humble shell Enter 'help' for a list of built-in commands. - Altera_Forum
Honored Contributor
Hi,
--- Quote Start --- But the new confusion was that nothing appeared on the screen and Nano-X seemed running correctly:
--- Quote End --- Have you revised that the all DMA descriptors use physical addresses? For example,/# nano-X & 686 nano-X /# nanowm & 687 nanowm /# nxclock & 688 nxclock
Kazu} __attribute__ ((packed)) sgdma_desc; # include <asm/cacheflush.h> // <-- to use 'flush_cache_all()' static int altfb_dma_start(unsigned long start, unsigned long len) { unsigned long base = (unsigned long)ioremap(SGDMABASE, ALTERA_SGDMA_IO_EXTENT); sgdma_desc *desc, *desc1; int ndesc = (len + DISPLAY_BYTES_PER_DESC - 1) / DISPLAY_BYTES_PER_DESC; int ndesc_size = sizeof(sgdma_desc) * ndesc; int i; writel(ALTERA_SGDMA_CONTROL_SOFTWARERESET_MSK, base + ALTERA_SGDMA_CONTROL); /* halt current transfer */ writel(0, base + ALTERA_SGDMA_CONTROL); /* disable interrupts */ writel(0xff, base + ALTERA_SGDMA_STATUS); /* clear status */ /* assume cache line size is 32, which is required by sgdma desc */ desc1 = kzalloc(ndesc_size, GFP_KERNEL); if (desc1 == NULL) return -ENOMEM; // desc1 = ioremap((unsigned long)desc1, ndesc_size); for (i = 0, desc = desc1; i < ndesc; i++, desc++) { unsigned ctrl = ALTERA_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK; desc->read_addr = (void *)start; if (i == (ndesc - 1)) { // desc->next = (void *)desc1; desc->next = (void *)virt_to_phys(desc1); desc->bytes_to_transfer = len; ctrl |= ALTERA_SGDMA_DESCRIPTOR_CONTROL_GENERATE_EOP_MSK; } else { // desc->next = (void *)(desc + 1); desc->next = (void *)virt_to_phys((desc + 1)); desc->bytes_to_transfer = DISPLAY_BYTES_PER_DESC; } if (i == 0) ctrl |= ALTERA_SGDMA_DESCRIPTOR_CONTROL_GENERATE_SOP_MSK; desc->control = ctrl; start += DISPLAY_BYTES_PER_DESC; len -= DISPLAY_BYTES_PER_DESC; } // writel((unsigned long)desc1, base + ALTERA_SGDMA_NEXT_DESC_POINTER); writel(((unsigned long)virt_to_phys(desc1)), base + ALTERA_SGDMA_NEXT_DESC_POINTER); writel(ALTERA_SGDMA_CONTROL_RUN_MSK | ALTERA_SGDMA_CONTROL_PARK_MSK, base + ALTERA_SGDMA_CONTROL); /* start */ flush_cache_all(); // <- To flush descriptors from the cache. Indeed, it's enough to flush the D-cache. return 0; }# else static int altfb_dma_start(unsigned long start, unsigned long len) - Altera_Forum
Honored Contributor
Oh, sorry. It's racing.
The descriptors must be flushed before we re-start the DMA.
Kazu// writel((unsigned long)desc1, base + ALTERA_SGDMA_NEXT_DESC_POINTER); writel(((unsigned long)virt_to_phys(desc1)), base + ALTERA_SGDMA_NEXT_DESC_POINTER); flush_cache_all(); // <- Must be here. writel(ALTERA_SGDMA_CONTROL_RUN_MSK | ALTERA_SGDMA_CONTROL_PARK_MSK, base + ALTERA_SGDMA_CONTROL); /* start */ // flush_cache_all(); // <- To flush descriptors from the cache. Indeed, it's enough to flush the D-cache. return 0; } - Altera_Forum
Honored Contributor
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
Honored Contributor
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
Honored Contributor
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
Honored Contributor
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
Honored Contributor
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'
and modify the file 'kgdb.c' of the nios arch likehandle_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
. Kazuvoid 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; } } - Altera_Forum
Honored Contributor
--- 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
Honored Contributor
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