Re-read kernel storage management (1): related global variables

Source: Internet
Author: User

Happy shrimp http://blog.csdn.net/lights_joy/lights@hb165.com this article applies to ADI bf561 DSPuclinux-2008r1-rc8 (transplanted to vdsp5) Visual DSP ++ 5.0 welcome reprint, but please keep the author information

1.1 Related global variables 1.1.1 _ ramstart, _ ramend, _ rambaseThe three global variables are defined in head. in the s file:/** set up the usable of Ram stuff. size of Ram is determined then * an initial stack set up at the end. */. align 4 _ rambase :. long 0 _ ramstart :. long 0 _ ramend :. to use them in the C file, long 0 makes a statement in the include/ASM/bfin-global.h: extern unsigned long _ ramstart, _ ramend, _ rambase; then they are initialized in the setup_arch function: _ ramend = config_mem_size * 1024*1024; _ ramstart = (unsigned long) _ bss_stop; _ rambase = (Unsigned long) _ stext; here _ bss_stop is defined in the LDF file: bsz_sdram zero_init {... Input_section_align (4 ). = (. + 3)/4*4; ___ bss_stop = .; _ end =. ;}> mem_sdram while bsz_sdram is the last segment in the kernel, SO _ ramstart points to the first available byte after the kernel. _ Stext is also a variable defined in the LDF file :. text {input_section_align (4 ). = (. + 3)/4*4; _ text = .; _ text = .; _ stext = .; ....... Input_section_align (4 ). = (. + 3)/4*4; _ etext =.;}> mem_sdram_text and. text is the first segment in the kernel, SO _ rambase points to the starting position of the kernel. Pay attention to the definition of _ ramend. Although a fixed value is assigned to it here, you can change it by setting the startup parameter in the Bootstrap program, if the Bootstrap program uses mem = 32 m, the following code will be triggered in the parse_linline_early function: If (! Memcmp (to, "mem =", 4) {to + = 4; memsize = memparse (to, & to); If (memsize) _ ramend = memsize ;} else if (! Memcmp (to, "max_mem =", 8 )){.... To change the value. 1.1.2 memory_start and memory_endThese two global variables are almost all used at the same time. They are defined in arch/Blackfin/kernel/setup. in C: Unsigned long memory_start, memory_end, physical_mem_end; initialize them in the setup_arch function: memory_start = page_align (_ ramstart);/* to align the pointer to the (next) page boundary */# define page_align (ADDR) + PAGE_SIZE-1) & page_mask) that is, memory_start points to the end of the kernel, but the page is aligned (4 K) up ). /* By now the stack is part of the init task */memory_end = _ ramend-dma_uncached_region; # If defined (config_dma_uncached_2m) # define dma_uncached_region (2*1024*1024) # Elif defined (config_dma_uncached_1m) # define dma_uncached_region (1024*1024) # else # define dma_uncached_region (0) # endif indicates that memory_end points to the highest available physical memory. When MTD is not enabled, run the following code: # If (defined (config_bfin_icache) & anomaly_05000263) /* due to a hardware anomaly we need to limit the size of usable * instruction memory to Max 60 MB, 56 If hunt_for_zero is on * 05000263-hardware loop was upted when taking an icplb exception */# If (defined (config_debug_hunt_for_zero) if (memory_end> = 56*1024*1024) memory_end = 56*1024*1024; # else if (memory_end> = 60*1024*1024) memory_end = 60*1024*1024; # endif/* config_debug_hunt_for_zero */printk (kern_notice "Warning: limiting memory to % limb due to hardware anomaly 05000263/N ", memory_end> 20); # endif/* anomaly_05000263 */due to anomaly_05000263, memory_end is limited to 60 m, that is, 0x03c0 0000. # If! Defined (config_mtd_uclinux) memory_end-= size_4k;/* in case there is no valid cplb behind memory_end make sure we don't get to close */# endif, the value of memory_end is 0x03bf f000. And will not change. When MTD is enabled, memory_end points to the location of the physical memory minus the ramdisk size. 1.1.3 nr_kernel_pages and nr_all_pagesThe two values are defined in mm/page_alloc.c: Unsigned long _ meminitdata nr_kernel_pages; unsigned long _ meminitdata nr_all_pages; they are assigned initial values in the free_area_init_core initialization function: static void _ meminit free_area_init_core (struct pglist_data * pgdat, unsigned long * zones_size, unsigned long * zholes_size ){... For (j = 0; j <max_nr_zones; j ++) {struct zone * zone = pgdat-> node_zones + J; unsigned long size, realsize, memmap_pages; // size = realsize = the number of page tables of SDRAM. For m sdram, the value is x3fff size = zone_spanned_pages_in_node (NID, J, zones_size); realsize = size-limit (NID, J, zholes_size);/** adjust realsize so that it accounts for how much memory * is used by this zone for memmap. this affe CTS the watermark * and per-CPU initialisations */memmap_pages = (size * sizeof (struct page)> page_shift; If (realsize> = memmap_pages) {realsize-= memmap_pages; printk (kern_debug "% s zone: % lu pages used for memmap/N", zone_names [J], memmap_pages);} else printk (kern_warning "% s zone: % lu pages exceeds realsize % lu/N ", zone_names [J], memmap_pages, realsize);/* account for reserved pages * /// The value of dma_reserve can be imported from the bootstrap, where it is 0 if (j = 0 & realsize> dma_reserve) {realsize-= dma_reserve; printk (kern_debug "% s zone: % lu pages reserved/N", zone_names [0], dma_reserve);} // is_highmem_idx is always if (! Is_highmem_idx (j) nr_kernel_pages + = realsize; nr_all_pages + = realsize ;....} From the code above, both values indicate the number of available pages, and the memory range is from 0 to 60 m, excluding the pages occupied by the page array. If MTD is not enabled for 64 msdram (the actual limit is 60 m), the value is 0x3b6a. 1.1.4 mem_mapThe global variable is defined in mm/nommu. in C: struct page * mem_map; each 4 K page in the kernel corresponds to a struct page, and mem_map is the header pointer pointing to this page array. Its Initialization is completed by alloc_node_mem_map: static void _ init_refok alloc_node_mem_map (struct pglist_data * pgdat ){... /* IA64 gets its own node_mem_map, before this, without bootmem */If (! Pgdat-> node_mem_map) {unsigned long size, start, end; struct page * map; /** the zone's endpoints aren't required to be max_order * aligned but the node_mem_map endpoints must be in order * For the buddy allocator to function correctly. */START = pgdat-> node_start_pfn &~ (Max_order_nr_pages-1); End = pgdat-> node_start_pfn + pgdat-> node_spanned_pages; end = align (end, max_order_nr_pages); size = (end-start) * sizeof (struct page); map = alloc_remap (pgdat-> node_id, size); If (! Map) map = alloc_bootmem_node (pgdat, size); pgdat-> node_mem_map = map + (pgdat-> node_start_pfn-Start);}/** with no discontig, the global mem_map is just set as node 0's */If (pgdat = node_data (0) {mem_map = node_data (0)-> node_mem_map ;}} the value of this function is the same as that of node_mem_map in pglist_data. Here, pgdat points to the globally unique pglist_data: extern struct pglist_data contig_page_data; the value of pgdat-> node_start_pfn is 0. The pgdat-> node_spanned_pages value is the number of pages (4 K) in the entire SDRAM. 1.1.5 contig_page_dataThe kernel supports the so-called NUMA structure, which divides the storage space of the entire system into several discontinuous nodes. Each node is described using a pglist_data file and then placed in a linked list, however, in the bf561 system kernel, a macro named node_data is defined in include/Linux/mmzone. in H, extern struct pglist_data contig_page_data; # define node_data (NID) (& contig_page_data) can be seen from this definition that there is actually only one pglist_data in the kernel. Contig_page_data. 1.1.6 vm_total_pagesThe value is defined in mm/vmscan. in C: Long vm_total_pages;/* the total number of pages which the VM controls */It indicates the number of available pages of the memory. Its Initialization is void _ meminit build_all_zonelists (void ){... Vm_total_pages = nr_free_pagecache_pages (); printk ("built % I zonelists. total pages: % LD/N ", num_online_nodes (), vm_total_pages);} the function is complete. For 64 M memory (the actual limit is 60 m), the value is 0x3b6a.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.