ARM platform Linux kernel Notes 1

Publisher:梦幻微笑Latest update time:2024-09-03 Source: cnblogs Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Linux memory management

The paging management of embedded processors is a two-level mapping, with memory space and I/O space addressed uniformly, while the x86 processor uses a three-level mapping, with memory space and I/O space addressed independently.

In a 32-bit embedded system, the address range of the storage space is from 0x0000_0000 to 0xFFFF_FFFF, and the memory and I/O share this 4GB address space range.

It mainly includes the following storage spaces:

1) Device space (MT_DEVICE): Secondary paging

2) Internal high-speed SRAM space (MT_CACHECLEAN): first-level segmentation

3) Internal mini cache space (MT_MINICLEAN): first level segmentation

4) Low-end interrupt vector (MT_LOW_VECTORS): two-level paging

5) High-end interrupt vector (MT_HIGH_VECTORS): two-level paging

6) RAM memory space (NT_MEMORY): first level segmentation

7) ROM (flash) space (MT_ROM): first level segmentation

--------------------------------------------- S3C6410 datasheet --- --------------------------------------------------

S3C6410 supports 32-bit physical address domains, and these address domains are divided into two parts, one for storage and the other for peripherals.

The main memory is accessed through the SPINE bus. The address range of the main memory is 0x0000_0000~0x6FFF_FFFF. The main memory is divided into four areas:

Boot image area, internal storage area, static storage area and dynamic storage area.

The address range of the boot image area is from 0x0000_0000 to 0x07FF_FFFF, but there is no actual mapped memory

The starting address of each block of internal memory is fixed.

The address range of the internal ROM is 0x0800_0000~0x0BFF_FFFF, but the actual storage is only 32KB. This area is read-only, and when the internal ROM boot is selected, this area can be mapped to the boot image area.

The address range of the internal SRAM is 0x0C00_0000~0x0FFF_FFFF, but the actual storage is only 4KB. This area can be read and written, and can be mapped to the boot image area when NAND flash boot is selected.

The address range of the static storage area is 0x1000_0000~0x3FFF_FFFF. Through this address area, SROM, SRAM, NOR Flash, synchronous NOR interface devices, and Steppingstone can be accessed.

The address range of the dynamic memory area is 0x4000_0000 to 0x6FFF_FFFF. DMC0 has the right to use the address 0x4000_0000 to 0x4FFF_FFFF, and DMC1 has the right to use the address 0x5000_0000 to 0x6FFF_FFFF.

The peripheral area is accessed through the PERI bus, and its address range is 0x7000_0000~0x7FFF_FFFF. All SFRs in this address range can be accessed. And if data needs to be transferred from NFCON or CFCON, these data need to be transferred through the PERI bus.

--------------------------------------------- I am the dividing line-------------------------------------------------------------

Memory page

ARM processors support page frame sizes of 1KB-4KB.

The default page frame size of ARM processors is 4KB.

The structure of page memory is struct page:


struct page {

unsigned long flags; /* Atomic flags, some possibly

* updated asynchronously */

atomic_t _count; /* Usage count, see below. */

union {

atomic_t _mapcount; /* Count of ptes mapped in mms,

* to show when page is mapped

* & limit reverse map searches.

*/

struct { /* SLUB */

u16 inuse;

u16 objects;

};

};

union {

struct {

unsigned long private; /* Mapping-private opaque data:

* usually used for buffer_heads

* if PagePrivate set; used for

* swp_entry_t if PageSwapCache;

* indicates order in the buddy

* system if PG_buddy is set.

*/

struct address_space *mapping; /* If low bit clear, points to

* inode address_space, or NULL.

* If page mapped as anonymous

* memory, low bit is set, and

* it points to anon_vma object:

* see PAGE_MAPPING_ANON below.

*/

};

#if USE_SPLIT_PTLOCKS

spinlock_t ptl;

#endif

struct kmem_cache *slab; /* SLUB: Pointer to slab */

struct page *first_page; /* Compound tail pages */

};

union {

pgoff_t index; /* Our offset within mapping. */

void *freelist; /* SLUB: freelist req. slab lock */

};

struct list_head lru; /* Pageout list, eg. active_list

* protected by zone->lru_lock !

*/

/*

* On machines where all RAM is mapped into kernel address space,

* we can simply calculate the virtual address. On machines with

* highmem some memory is mapped into kernel virtual memory

* dynamically, so we need a place to store that address.

* Note that this field could be 16 bits on x86... ;)

*

* Architectures with slow multiplication can define

* WANT_PAGE_VIRTUAL in asm/page.h

*/

#if defined(WANT_PAGE_VIRTUAL)

void *virtual; /* Kernel virtual address (NULL if

not kmapped, ie. highmem) */

#endif /* WANT_PAGE_VIRTUAL */

#ifdef CONFIG_WANT_PAGE_DEBUG_FLAGS

unsigned long debug_flags; /* Use atomic bitops on this */

#endif


#ifdef CONFIG_KMEMCHECK

/*

* kmemcheck wants to track the status of each byte in a page; this

* is a pointer to such a status block. NULL if not tracked.

*/

void *shadow;

#endif

};


/*

* A region containing a mapping of a non-memory backed file under NOMMU

* conditions. These are held in a global tree and are pinned by the VMAs that

* map parts of them.

*/

struct vm_region {

struct rb_node vm_rb; /* link in global region tree */

unsigned long vm_flags; /* VMA vm_flags */

unsigned long vm_start; /* start address of region */

unsigned long vm_end; /* region initialised to here */

unsigned long vm_top; /* region allocated to here */

unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */

struct file *vm_file; /* the backing file or NULL */


int vm_usage; /* region usage count (access under nommu_region_sem) */

bool vm_icache_flushed : 1; /* true if the icache has been flushed for

* this region */

};


Memory segment (bank)


A memory bank represents a continuous memory area. A bank generally corresponds to the memory space of a RAM chip connected to a RAM chip select pin of the processor.


Modern processors usually have at least 4 RAM chip select pins. The total starting address and size of the RAM chip connected to each pin in the system can be set through registers.


The data structure corresponding to the memory bank is struct meminfo:


struct meminfo {

int nr_banks;

struct membank bank[NR_BANKS];

};


Memory node


A memory node refers to a memory set consisting of one or more memory banks. If a memory node consists of multiple memory banks, these memory banks can be continuous or discontinuous, that is, memory holes can exist in the node.


In settings


CONFIG_DISCONTIGMEM

/*

If not set, there is only one bank, that is, only one memory node, and the memory addresses are continuous;

The address range between every two RAMs in the processor address addressing is fixed. If the connected RAM is smaller than this maximum addressing range, a memory hole will appear. At this time, if CONFIG_DISCONTIGMEM is not set, all memory banks belong to memory node 0. If CONFIG_DISCONTIGMEM is set, a certain amount of time will be wasted to create struct pages for the hole memory.

The hole has no effect on the system after startup because the hole has been reclaimed by mem_init().

*/


The important data structures corresponding to the memory nodes are struct pglist_data (pg_data_t):


typedef struct pglist_data {

struct zone node_zones[MAX_NR_ZONES];

struct zonelist node_zonelists[MAX_ZONELISTS];

int nr_zones;

#ifdef CONFIG_FLAT_NODE_MEM_MAP /* means !SPARSEMEM */

struct page *node_mem_map;

#ifdef CONFIG_CGROUP_MEM_RES_CTLR

struct page_cgroup *node_page_cgroup;

#endif

#endif

#ifndef CONFIG_NO_BOOTMEM

struct bootmem_data *bdata;

#endif

#ifdef CONFIG_MEMORY_HOTPLUG

/*

* Must be held any time you expect node_start_pfn, node_present_pages

* or node_spanned_pages stay constant. Holding this will also

* guarantee that any pfn_valid() stays that way.

*

* Nests above zone->lock and zone->size_seqlock.

*/

spinlock_t node_size_lock;

#endif

unsigned long node_start_pfn;

unsigned long node_present_pages; /* total number of physical pages */

unsigned long node_spanned_pages; /* total size of physical page

range, including holes */

int node_id;

wait_queue_head_t kswapd_wait;

struct task_struct *kswapd;

int kswapd_max_order;

} pg_data_t;


Memory page zone


Memory page area is a concept defined in memory node. Each memory node can be divided into three memory page areas, namely


1. DMA page area (ZONE_DMA=0): DMA operation is possible


2. Normal page area (ZONE_NORMAL=1): DMA operation is prohibited


3. HighMem page area (ZONE_HIGHMEM=2): high-end memory area


The important data structure corresponding to the memory page area is struct zone (the content is relatively long, so I won’t paste it~,~, you can find it yourself on LXR)



Free area


The free memory area is a memory area consisting of 2^N consecutive pages of free memory in the memory page area, where N is an integer between 0 and MAX_ORDER-1, and the default value of MAX_ORDER is 11.


The corresponding data structure is struct free_area:


struct free_area {

struct list_head free_list[MIGRATE_TYPES];

unsigned long nr_free;

};


Reference address:ARM platform Linux kernel Notes 1

Previous article:ARM platform Linux kernel Notes 2
Next article:s3c6410 bare metal program (2)

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号