Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I'm pretty confused on how linux manages I/O shared memory to communicate with devices that use it.

If I understood it correctly linux kernel starts mapped at 0x100000 (to avoid the first megabyte legacy ram data and to be stored in contiguous memory locations) and then after entering protected mode:

  • on 32 bit systems there's a mapping like this

http://i.stack.imgur.com/zEkq2.jpg

The ZONE_NORMAL should be below 896 MB, so the mapping between the kernel linear 1GB and the physical 896 MB is always possible. Let's just ignore the ZONE_DMA for now (I read that this is just for legacy systems since PCI can now use DMA transfers everywhere in memory)

  • on 64 bit systems the kernel linear address space should start from PAGE_OFFSET= 0xffff810000000000 and forth

In both cases, if an address in the kernel space is greater than PAGE_OFFSET, should refer to a ioremap mapping (to be resolved through pagination), if it's lower than PAGE_OFFSET it could be resolved with a simple NEW_ADDRESS = OLD_ADDRESS - PAGE_OFFSET. Is this correct?

Bonus question: when the kernel is up and running and the tidying up has been done, does it still physically reside from 0x100000 and forth (within the first GB) ? Even on 64bit systems?

share|improve this question

2 Answers 2

up vote 1 down vote accepted

On PCs, hardware memory mapped IO ranges are assigned by the BIOS to physical memory addresses between 3GiB and 4 GiB. When a driver requests access to the memory, the kernel maps it somewhere in the kernel virtual address space.

Neither of your other two questions seem to have anything to do with shared memory, but:

In both cases, if an address in the kernel space is greater than PAGE_OFFSET, should refer to a ioremap mapping (to be resolved through pagination), if it's lower than PAGE_OFFSET it could be resolved with a simple NEW_ADDRESS = OLD_ADDRESS - PAGE_OFFSET. Is this correct?

Mentally, yes. The hardware uses the page tables in either case.

share|improve this answer

Think Your Question looks like , how ioremap works..

vaddr = ioremap(paddr_io_mapped_device , size);

vaddr is returned virtual address in the kernel space. Kernel creates the page table entries for the virtual address range (vaddr , size) and maps it to the physical address paddr_io_shared_device. So, if you access the virtual address range it will be as good as accessing the physical address inside the io_mapped deivce.

Importantly , the returned vaddr is not cachable. Every time you read/write the address range , it will be read/write from the io_mapped device and not from the cache.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.