做爰高潮a片〈毛片〉,尤物av天堂一区二区在线观看,一本久久A久久精品VR综合,添女人荫蒂全部过程av

最新文章專(zhuān)題視頻專(zhuān)題問(wèn)答1問(wèn)答10問(wèn)答100問(wèn)答1000問(wèn)答2000關(guān)鍵字專(zhuān)題1關(guān)鍵字專(zhuān)題50關(guān)鍵字專(zhuān)題500關(guān)鍵字專(zhuān)題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專(zhuān)題關(guān)鍵字專(zhuān)題tag2tag3文章專(zhuān)題文章專(zhuān)題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專(zhuān)題3
問(wèn)答文章1 問(wèn)答文章501 問(wèn)答文章1001 問(wèn)答文章1501 問(wèn)答文章2001 問(wèn)答文章2501 問(wèn)答文章3001 問(wèn)答文章3501 問(wèn)答文章4001 問(wèn)答文章4501 問(wèn)答文章5001 問(wèn)答文章5501 問(wèn)答文章6001 問(wèn)答文章6501 問(wèn)答文章7001 問(wèn)答文章7501 問(wèn)答文章8001 問(wèn)答文章8501 問(wèn)答文章9001 問(wèn)答文章9501
當(dāng)前位置: 首頁(yè) - 科技 - 知識(shí)百科 - 正文

關(guān)于高端內(nèi)存的權(quán)威解釋

來(lái)源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-09 08:13:41
文檔

關(guān)于高端內(nèi)存的權(quán)威解釋

關(guān)于高端內(nèi)存的權(quán)威解釋:注:本文是我見(jiàn)到的所有 關(guān)于 高端內(nèi)存 解釋 的最詳細(xì)、最清晰的 解釋 ,其他帖子寥寥數(shù)語(yǔ)寫(xiě)的都是垃圾,保存下來(lái)只為方便后來(lái)人和我自己,感謝原文作者! 原文地址:http://bbs.chinaunix.net/thread-1938084-1-1.html 注:本文提及的物理地址空間
推薦度:
導(dǎo)讀關(guān)于高端內(nèi)存的權(quán)威解釋:注:本文是我見(jiàn)到的所有 關(guān)于 高端內(nèi)存 解釋 的最詳細(xì)、最清晰的 解釋 ,其他帖子寥寥數(shù)語(yǔ)寫(xiě)的都是垃圾,保存下來(lái)只為方便后來(lái)人和我自己,感謝原文作者! 原文地址:http://bbs.chinaunix.net/thread-1938084-1-1.html 注:本文提及的物理地址空間

注:本文是我見(jiàn)到的所有 關(guān)于 高端內(nèi)存 解釋 的最詳細(xì)、最清晰的 解釋 ,其他帖子寥寥數(shù)語(yǔ)寫(xiě)的都是垃圾,保存下來(lái)只為方便后來(lái)人和我自己,感謝原文作者! 原文地址:http://bbs.chinaunix.net/thread-1938084-1-1.html 注:本文提及的物理地址空間可以理解

注:本文是我見(jiàn)到的所有關(guān)于高端內(nèi)存解釋的最詳細(xì)、最清晰的解釋?zhuān)渌恿攘葦?shù)語(yǔ)寫(xiě)的都是垃圾,保存下來(lái)只為方便后來(lái)人和我自己,感謝原文作者!

原文地址:http://bbs.chinaunix.net/thread-1938084-1-1.html



注:本文提及的物理地址空間可以理解為就是物理內(nèi)存,但是在某些情況下,把他們理解為物理內(nèi)存是不對(duì)的。

本文討論的環(huán)境是NON-PAE的i386平臺(tái),內(nèi)核版本2.6.31-14

一.什么是高端內(nèi)存

linux中內(nèi)核使用3G-4G的線性地址空間,也就是說(shuō)總共只有1G的地址空間可以用來(lái)映射物理地址空間。但是,如果內(nèi)存大于1G的情況下呢?是不是超過(guò)1G的內(nèi)存就無(wú)法使用了呢?為此內(nèi)核引入了一個(gè)高端內(nèi)存的概念,把1G的線性地址空間劃分為兩部分:小于896M物理地址空間的稱(chēng)之為低端內(nèi)存,這部分內(nèi)存的物理地址和3G開(kāi)始的線性地址是一一對(duì)應(yīng)映射的,也就是說(shuō)內(nèi)核使用的線性地址空間3G--(3G+896M)和物理地址空間0-896M一一對(duì)應(yīng);剩下的128M的線性空間用來(lái)映射剩下的大于896M的物理地址空間,這也就是我們通常說(shuō)的高端內(nèi)存區(qū)。

所謂的建立高端內(nèi)存的映射就是能用一個(gè)線性地址來(lái)訪問(wèn)高端內(nèi)存的頁(yè)。如何理解這句話(huà)呢?在開(kāi)啟分頁(yè)后,我們要訪問(wèn)一個(gè)物理內(nèi)存地址,需要經(jīng)過(guò)MMU的轉(zhuǎn)換,也就是一個(gè)32位地址vaddr的高10位用來(lái)查找該vaddr所在頁(yè)目錄項(xiàng),用12-21位來(lái)查找頁(yè)表項(xiàng),再用0-11位偏移和頁(yè)的起始物理地址相加得到paddr,再把該paddr放到前端總線上,那么我們就可以訪問(wèn)該vaddr對(duì)應(yīng)的物理內(nèi)存了。在低端內(nèi)存中,每一個(gè)物理內(nèi)存頁(yè)在系統(tǒng)初始化的時(shí)候都已經(jīng)存在這樣一個(gè)映射了。而高端內(nèi)存還不存在這樣一個(gè)映射(頁(yè)目錄項(xiàng),頁(yè)表都是空的),所以我們必須要在系統(tǒng)初始化完后,提供一系列的函數(shù)來(lái)實(shí)現(xiàn)這個(gè)功能,這就是所謂的高端內(nèi)存的映射。那么我們?yōu)槭裁床辉傧到y(tǒng)初始化的時(shí)候把所有的內(nèi)存映射都建立好呢?主要原因是,內(nèi)核線性地址空間不足以容納所有的物理地址空間(1G的內(nèi)核線性地址空間和最多可達(dá)4G的物理地址空間),所以才需要預(yù)留一部分(128M)的線性地址空間來(lái)動(dòng)態(tài)的映射所有的物理地址空間,于是就產(chǎn)生了所謂的高端內(nèi)存映射。

二.內(nèi)核如何管理高端內(nèi)存


上面的圖展示了內(nèi)核如何使用3G-4G的線性地址空間,首先解釋下什么是high_memory

在arch/x86/mm/init_32.c里面由如下代碼:

#ifdef CONFIG_HIGHMEM

highstart_pfn = highend_pfn = max_pfn;

if (max_pfn > max_low_pfn)

highstart_pfn = max_low_pfn;

e820_register_active_regions(0, 0, highend_pfn);

sparse_memory_present_with_active_regions(0);

printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",

pages_to_mb(highend_pfn - highstart_pfn));

num_physpages = highend_pfn;

high_memory = (void *) __va(highstart_pfn * PAGE_SIZE-1)+1;

#else

e820_register_active_regions(0, 0, max_low_pfn);

sparse_memory_present_with_active_regions(0);

num_physpages = max_low_pfn;

high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1)+1;

#endif

high_memory是“具體物理內(nèi)存的上限對(duì)應(yīng)的虛擬地址”,可以這么理解:當(dāng)內(nèi)存內(nèi)存小于896M時(shí),那么high_memory = (void *)__va(max_low_pfn * PAGE_SIZE),max_low_pfn就是在內(nèi)存中最后的一個(gè)頁(yè)幀號(hào),所以high_memory=0xc0000000+物理內(nèi)存大小;當(dāng)內(nèi)存大于896M時(shí),那么highstart_pfn= max_low_pfn,此時(shí)max_low_pfn就不是物理內(nèi)存的最后一個(gè)頁(yè)幀號(hào)了,而是內(nèi)存為896M時(shí)的最后一個(gè)頁(yè)幀號(hào),那么high_memory=0xc0000000+896M.總之high_memory是不能超過(guò)0xc0000000+896M.

由于我們討論的是物理內(nèi)存大于896M的情況,所以high_memory實(shí)際上就是0xc0000000+896M,從high_memory開(kāi)始的128M(4G-high_memory)就是用作用來(lái)映射剩下的大于896M的內(nèi)存的,當(dāng)然這128M還可以用來(lái)映射設(shè)備的內(nèi)存(MMIO)。

從上圖我們看到有VMALLOC_START,VMALLOC_END,PKMAP_BASE,FIX_ADDRESS_START等宏術(shù)語(yǔ),其實(shí)這些術(shù)語(yǔ)劃分了這128M的線性空間,一共分為三個(gè)區(qū)域:VMALLOC區(qū)域(本文不涉及這部分內(nèi)容,關(guān)注本博客的其他文章),永久映射區(qū)(permanetkernelmappings), 臨時(shí)映射區(qū)(temporary kernelmappings).這三個(gè)區(qū)域都可以用來(lái)映射高端內(nèi)存,本文重點(diǎn)闡述下后兩個(gè)區(qū)域是如何映射高端內(nèi)存的。

三.永久映射區(qū)(permanet kernel mappings)

1.介紹幾個(gè)定義:

PKMAP_BASE:永久映射區(qū)的起始線性地址。

pkmap_page_table:永久映射區(qū)對(duì)應(yīng)的頁(yè)表。

LAST_PKMAP:pkmap_page_table里面包含的entry的數(shù)量=1024

pkmap_count[LAST_PKMAP]數(shù)組:每一個(gè)元素的值對(duì)應(yīng)一個(gè)entry的引用計(jì)數(shù)。關(guān)于引用計(jì)數(shù)的值,有以下幾種情況:

0:說(shuō)明這個(gè)entry可用。

1:entry不可用,雖然這個(gè)entry沒(méi)有被用來(lái)映射任何內(nèi)存,但是他仍然存在TLBentry沒(méi)有被flush,

所以還是不可用。

N:有N-1個(gè)對(duì)象正在使用這個(gè)頁(yè)面

首先,要知道這個(gè)區(qū)域的大小是4M,也就是說(shuō)128M的線性地址空間里面,只有4M的線性地址空間是用來(lái)作永久映射區(qū)的。至于到底是哪4M,是由PKMAP_BASE決定的,這個(gè)變量表示用來(lái)作永久內(nèi)存映射的4M區(qū)間的起始線性地址。

在NON-PAE的i386上,頁(yè)目錄里面的每一項(xiàng)都指向一個(gè)4M的空間,所以永久映射區(qū)只需要一個(gè)頁(yè)目錄項(xiàng)就可以了。而一個(gè)頁(yè)目錄項(xiàng)指向一張頁(yè)表,那么永久映射區(qū)正好就可以用一張頁(yè)表來(lái)表示了,于是我們就用pkmap_page_table來(lái)指向這張頁(yè)表。

pgd = swapper_pg_dir + pgd_index(vaddr);

pud = pud_offset(pgd, vaddr);//pud==pgd

pmd = pmd_offset(pud, vaddr);//pmd==pud==pgd

pte = pte_offset_kernel(pmd, vaddr);

pkmap_page_table = pte;

2.具體代碼分析(2.6.31)

void *kmap(struct page *page)

{

might_sleep();

if (!PageHighMem(page))

return page_address(page);

return kmap_high(page);

}

kmap()函數(shù)就是用來(lái)建立永久映射的函數(shù):由于調(diào)用kmap函數(shù)有可能會(huì)導(dǎo)致進(jìn)程阻塞,所以它不能在中斷處理函數(shù)等不可被阻塞的上下文下被調(diào)用,might_sleep()的作用就是當(dāng)該函數(shù)在不可阻塞的上下文下被調(diào)用是,打印棧信息。接下來(lái)判斷該需要建立永久映射的頁(yè)是否確實(shí)屬于高端內(nèi)存,因?yàn)槲覀冎赖投藘?nèi)存的每個(gè)頁(yè)都已經(jīng)存在和線性地址的映射了,所以,就不需要再建立了,page_address()函數(shù)返回該page對(duì)應(yīng)的線性地址。(關(guān)于page_address()函數(shù),參考本博客的專(zhuān)門(mén)文章有解釋?zhuān)W詈笳{(diào)用kmap_high(page),可見(jiàn)kmap_high()才真正執(zhí)行建立永久映射的操作。

/**

* kmap_high - map a highmem page into memory

* @page: &struct page to map

*

* Returns the page's virtual memory address.

*

* We cannot call this from interrupts, as it may block.

*/

void *kmap_high(struct page *page)

{

unsigned long vaddr;

/*

* For highmem pages, we can't trust "virtual" until

* after we have the lock.

*/

lock_kmap();

vaddr = (unsigned long)page_address(page);

if (!vaddr)

vaddr = map_new_virtual(page);

pkmap_count[PKMAP_NR(vaddr)]++;

BUG_ON(pkmap_count[PKMAP_NR(vaddr)] < 2);

unlock_kmap();

return (void*) vaddr;

}

kmap_high函數(shù)分析:首先獲得對(duì)pkmap_page_table操作的鎖,然后再調(diào)用page_address()來(lái)返回該page是否已經(jīng)被映射,我們看到前面在kmap()里面已經(jīng)判斷過(guò)了,為什么這里還要再次判斷呢?因?yàn)樵佾@的鎖的時(shí)候,有可能鎖被其他CPU拿走了,而恰巧其他CPU拿了這個(gè)鎖之后,也是執(zhí)行這段code,而且映射的也是同一個(gè)page,那么當(dāng)它把鎖釋放掉的時(shí)候,其實(shí)就表示該page的映射已經(jīng)被建立了,我們這里就沒(méi)有必要再去執(zhí)行這段code了,所以就有必要在獲得鎖后再判斷下。

如果發(fā)現(xiàn)vaddr不為空,那么就是剛才說(shuō)的,已經(jīng)被其他cpu上執(zhí)行的任務(wù)給建立了,這里只需要把表示該頁(yè)引用計(jì)數(shù)的pkmap_count[]再加一就可以了。同時(shí)調(diào)用BUG_ON來(lái)確保該引用計(jì)數(shù)確實(shí)是不小于2的,否則就是有問(wèn)題的了。然后返回vaddr,整個(gè)建立就完成了。

如果發(fā)現(xiàn)vaddr為空呢?調(diào)用map_new_virtual()函數(shù),到此我們看到,其實(shí)真正進(jìn)行建立映射的代碼在這個(gè)函數(shù)里面

static inline unsigned long map_new_virtual(struct page *page)

{

unsigned long vaddr;

int count;

start:

count = LAST_PKMAP;//LAST_PKMAP=1024

/* Find an empty entry */

for (;;) {

last_pkmap_nr = (last_pkmap_nr + 1) & LAST_PKMAP_MASK;

if (!last_pkmap_nr) {

flush_all_zero_pkmaps();

count = LAST_PKMAP;

}

if (!pkmap_count[last_pkmap_nr])

break; /* Found a usable entry */

if (--count)

continue;

/*

* Sleep for somebody else to unmap their entries

*/

{

DECLARE_WAITQUEUE(wait, current);

__set_current_state(TASK_UNINTERRUPTIBLE);

add_wait_queue(&pkmap_map_wait, &wait);

unlock_kmap();

schedule();

remove_wait_queue(&pkmap_map_wait, &wait);

lock_kmap();

/* Somebody else might have mapped it while we slept */

if (page_address(page))

return (unsigned long)page_address(page);

/* Re-start */

goto start;

}

}

vaddr = PKMAP_ADDR(last_pkmap_nr);

set_pte_at(&init_mm, vaddr,

&(pkmap_page_table[last_pkmap_nr]), mk_pte(page, kmap_prot));

pkmap_count[last_pkmap_nr] = 1;

set_page_address(page, (void *)vaddr);

return vaddr;

}

last_pkmap_nr:記錄上次被分配的頁(yè)表項(xiàng)在pkmap_page_table里的位置,初始值為0,所以第一次分配的時(shí)候last_pkmap_nr等于1。

接下來(lái)判斷什么時(shí)候last_pkmap_nr等于0,等于0就表示1023(LAST_PKMAP(1024)-1)個(gè)頁(yè)表項(xiàng)已經(jīng)被分配了,這時(shí)候就需要調(diào)用flush_all_zero_pkmaps()函數(shù),把所有pkmap_count[]計(jì)數(shù)為1的頁(yè)表項(xiàng)在TLB里面的entry給flush掉,并重置為0,這就表示該頁(yè)表項(xiàng)又可以用了,可能會(huì)有疑惑為什么不在把pkmap_count置為1的時(shí)候也就是解除映射的同時(shí)把TLB也flush呢?個(gè)人感覺(jué)有可能是為了效率的問(wèn)題吧,畢竟等到不夠的時(shí)候再刷新,效率要好點(diǎn)吧。

再判斷pkmap_count[last_pkmap_nr]是否為0,0的話(huà)就表示這個(gè)頁(yè)表項(xiàng)是可用的,那么就跳出循環(huán)了到下面了。

PKMAP_ADDR(last_pkmap_nr)返回這個(gè)頁(yè)表項(xiàng)對(duì)應(yīng)的線性地址vaddr.

#definePKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))

set_pte_at(mm,addr, ptep, pte)函數(shù)在NON-PAE i386上的實(shí)現(xiàn)其實(shí)很簡(jiǎn)單,其實(shí)就等同于下面的代碼:

staticinline void native_set_pte(pte_t *ptep , pte_t pte)

{

*ptep = pte;

}

我們已經(jīng)知道頁(yè)表的線性起始地址存放在pkmap_page_table里面,那么相應(yīng)的可用的頁(yè)表項(xiàng)的地址就是&pkmap_page_table[last_pkmap_nr],得到了頁(yè)表項(xiàng)的地址,只要把相應(yīng)的pte填寫(xiě)進(jìn)去,那么整個(gè)映射不就完成了嗎?

pte由兩部分組成:高20位表示物理地址,低12位表示頁(yè)的描述信息。

怎么通過(guò)page查找對(duì)應(yīng)的物理地址呢(參考page_address()一文)?其實(shí)很簡(jiǎn)單,用(page- mem_map) 再移PAGE_SHIFT位就可以了。

低12位的頁(yè)描述信息是固定的:kmap_prot=(_PAGE_PRESENT| _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL).

下面的代碼就是做了這些事情:

mk_pte(page,kmap_prot));

#definemk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))

#definepage_to_pfn __page_to_pfn

#define__page_to_pfn(page) ((unsigned long)((page) - mem_map) + \

ARCH_PFN_OFFSET)

staticinline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)

{

return __pte(((phys_addr_t)page_nr <

massage_pgprot(pgprot));

}

接下來(lái)把pkmap_count[last_pkmap_nr]置為1,1不是表示不可用嗎,既然映射已經(jīng)建立好了,應(yīng)該賦值為2呀,其實(shí)這個(gè)操作是在他的上層函數(shù)kmap_high里面完成的(pkmap_count[PKMAP_NR(vaddr)]++).

到此為止,整個(gè)映射就完成了,再把page和對(duì)應(yīng)的線性地址加入到page_address_htable哈希鏈表里面就可以了(參考page_address一文)。

我們繼續(xù)看所有的頁(yè)表項(xiàng)都已經(jīng)用了的情況下,也就是1024個(gè)頁(yè)表項(xiàng)全已經(jīng)映射了內(nèi)存了,如何處理。此時(shí)count==0,于是就進(jìn)入了下面的代碼:

/*

* Sleepfor somebody else to unmap their entries

*/

{

DECLARE_WAITQUEUE(wait, current);

__set_current_state(TASK_UNINTERRUPTIBLE);

add_wait_queue(&pkmap_map_wait, &wait);

unlock_kmap();

schedule();

remove_wait_queue(&pkmap_map_wait, &wait);

lock_kmap();

/* Somebody else might have mapped it while we slept */

if (page_address(page))

return (unsignedlong)page_address(page);

/* Re-start */

goto start;

}

這段代碼其實(shí)很簡(jiǎn)單,就是把當(dāng)前任務(wù)加入到等待隊(duì)列pkmap_map_wait,當(dāng)有其他任務(wù)喚醒這個(gè)隊(duì)列時(shí),再繼續(xù)gotostart,重新整個(gè)過(guò)程。這里就是上面說(shuō)的調(diào)用kmap函數(shù)有可能阻塞的原因。

那么什么時(shí)候會(huì)喚醒pkmap_map_wait隊(duì)列呢?當(dāng)調(diào)用kunmap_high函數(shù),來(lái)釋放掉一個(gè)映射的時(shí)候。

kunmap_high函數(shù)其實(shí)頁(yè)很簡(jiǎn)單,就是把要釋放的頁(yè)表項(xiàng)的計(jì)數(shù)減1,如果等于1的時(shí)候,表示有可用的頁(yè)表項(xiàng)了,再喚醒pkmap_map_wait隊(duì)列

/**

*kunmap_high - map a highmem page into memory

* @page:&struct page to unmap

*

* IfARCH_NEEDS_KMAP_HIGH_GET is not defined then this may be called

* onlyfrom user context.

*/

voidkunmap_high(struct page *page)

{

unsigned long vaddr;

unsigned long nr;

unsigned long flags;

int need_wakeup;

lock_kmap_any(flags);

vaddr = (unsigned long)page_address(page);

BUG_ON(!vaddr);

nr = PKMAP_NR(vaddr);

/*

* A count must never go down to zero

* without a TLB flush!

*/

need_wakeup = 0;

switch (--pkmap_count[nr]) {//減一

case 0:

BUG();

case 1:

/*

* Avoidan unnecessary wake_up() function call.

* Thecommon case is pkmap_count[] == 1, but

* nowaiters.

* Thetasks queued in the wait-queue are guarded

* by boththe lock in the wait-queue-head and by

* thekmap_lock. As the kmap_lock is held here,

* no needfor the wait-queue-head's lock. Simply

* test ifthe queue is empty.

*/

need_wakeup =waitqueue_active(&pkmap_map_wait);

}

unlock_kmap_any(flags);

/* do wake-up, if needed, race-free outside ofthe spin lock */

if (need_wakeup)

wake_up(&pkmap_map_wait);

}

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

關(guān)于高端內(nèi)存的權(quán)威解釋

關(guān)于高端內(nèi)存的權(quán)威解釋:注:本文是我見(jiàn)到的所有 關(guān)于 高端內(nèi)存 解釋 的最詳細(xì)、最清晰的 解釋 ,其他帖子寥寥數(shù)語(yǔ)寫(xiě)的都是垃圾,保存下來(lái)只為方便后來(lái)人和我自己,感謝原文作者! 原文地址:http://bbs.chinaunix.net/thread-1938084-1-1.html 注:本文提及的物理地址空間
推薦度:
標(biāo)簽: 內(nèi)存 所有 是我
  • 熱門(mén)焦點(diǎn)

最新推薦

猜你喜歡

熱門(mén)推薦

專(zhuān)題
Top
主站蜘蛛池模板: 仪陇县| 博罗县| 乐平市| 柘城县| 关岭| 姜堰市| 新乡市| 偃师市| 邵阳县| 钟山县| 江山市| 仪征市| 黑龙江省| 东山县| 东宁县| 五大连池市| 茌平县| 山东省| 黑龙江省| 隆化县| 东乌珠穆沁旗| 日土县| 云安县| 马鞍山市| 镇江市| 凤翔县| 新丰县| 怀远县| 嘉兴市| 丁青县| 石首市| 普陀区| 巧家县| 焦作市| 咸阳市| 海门市| 冀州市| 康马县| 平度市| 安新县| 得荣县|