www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 嵌入式 > 嵌入式軟件

Android平臺(tái)是基于Linxu內(nèi)核搭建的,Linux內(nèi)核的優(yōu)勢(shì)在于大內(nèi)存管理、進(jìn)程管理、基于權(quán)限的安全模型、統(tǒng)一的驅(qū)動(dòng)模型、共享庫(kù)支持、代碼開(kāi)源等。

Android平臺(tái)在設(shè)計(jì)過(guò)程中,針對(duì)移動(dòng)終端資源有限的特點(diǎn),對(duì)Linux進(jìn)行了一定程度的裁剪:砍掉了原生的窗口系統(tǒng)、去除了對(duì)GNU Libc的支持(引入了更高效、針對(duì)優(yōu)化過(guò)的Bionic)、裁剪掉了一些標(biāo)準(zhǔn)Linux工具的部分特性等。

另外Android針對(duì)移動(dòng)終端的特點(diǎn)還對(duì)Linux內(nèi)核在鬧鐘(Alarm)、Low Memory Killer、Ashmem、內(nèi)核調(diào)試(Kernel Debugger)、進(jìn)程間通信(Binder)、日志(Logger)、電源管理(Power Management)等方面做了大量的優(yōu)化。

其中Low Memory Killer相對(duì)于Linux標(biāo)準(zhǔn)OOM(Out Of Memory)機(jī)制更加靈活,它可以根據(jù)需要?dú)⑺肋M(jìn)程來(lái)釋放需要的內(nèi)存。Low Memory Killer的實(shí)現(xiàn)主要位于auroramsmmsm drivers/staging/android/lowmemorykiller.c文件中。

Ashmem為進(jìn)程間提供大塊共享內(nèi)存,同時(shí)為內(nèi)核提供回收和管理這個(gè)內(nèi)存的機(jī)制。 Ashmem的實(shí)現(xiàn)位于systemcorelibcutilsashmem-dev.c文件中。

下面重點(diǎn)介紹進(jìn)程間通信和電源管理的內(nèi)容。

1.進(jìn)程間通信

在多進(jìn)程環(huán)境下,應(yīng)用程序和后臺(tái)服務(wù)間通常會(huì)運(yùn)行在不同的進(jìn)程中,彼此有著獨(dú)立的地址空間,但是因?yàn)樾枰嗷f(xié)作,彼此間又必須進(jìn)行通信和數(shù)據(jù)共享,而傳統(tǒng)的進(jìn)程間通信(IPC,Internet Process Connection)卻有著進(jìn)程過(guò)載和安全漏洞等方面的風(fēng)險(xiǎn)。在Android中,引入了Binder的進(jìn)程間通信機(jī)制,Binder的好處在于在驅(qū)動(dòng)層面就對(duì)進(jìn)程間通信提供了支持、通過(guò)SMD共享內(nèi)存機(jī)制提高了進(jìn)程間通信的性能、采用線程池的方式來(lái)處理進(jìn)程請(qǐng)求、針對(duì)系統(tǒng)中的對(duì)象引入了引用計(jì)數(shù)機(jī)制和跨進(jìn)程的對(duì)象引用映射機(jī)制、在進(jìn)程間的同步調(diào)用。圖1顯示了Android的進(jìn)程間通信過(guò)程。


圖1 Android的進(jìn)程間通信過(guò)程

為了進(jìn)行進(jìn)程間通信,Binder采用AIDL(Android Interface Definition Lanaguage)來(lái)描述進(jìn)程間的接口。
在實(shí)際的實(shí)現(xiàn)中,Binder是作為一個(gè)特殊的字符型設(shè)備來(lái)存在的,其實(shí)現(xiàn)遵循Linux設(shè)備驅(qū)動(dòng)模型,相關(guān)的主要代碼位于auroramsmmsmdriversstagingandroid binder.c文件中。

在Binder驅(qū)動(dòng)中,binder_thread_write()函數(shù)通過(guò)binder_transaction()函數(shù)來(lái)發(fā)送請(qǐng)求或返回結(jié)果,而binder_thread_read()函數(shù)用于讀取結(jié)果,Binder主要通過(guò)binder_ioctl()函數(shù)與用戶(hù)空間的進(jìn)程交換數(shù)據(jù)。

Binder的私有數(shù)據(jù)結(jié)構(gòu)binder_proc則被用來(lái)記錄當(dāng)前進(jìn)程、進(jìn)程ID、內(nèi)存映射信息、Binder的統(tǒng)計(jì)信息和線程信息等。

如果收到請(qǐng)求,binder_transaction()函數(shù)會(huì)通過(guò)對(duì)象的句柄找到對(duì)象所在的進(jìn)程,如果句柄為空就認(rèn)為對(duì)象是 context_mgr,把請(qǐng)求發(fā)給context_mgr所在的進(jìn)程。所有的Binder對(duì)象會(huì)全部放到一個(gè)RB樹(shù)中。最后context_mgr把請(qǐng)求放到目標(biāo)進(jìn)程的事件隊(duì)列中,等待目標(biāo)進(jìn)程讀取。數(shù)據(jù)的解析工作放在binder_parse()中實(shí)現(xiàn)。

下面是Binder驅(qū)動(dòng)中最重要的binder_ioctl()函數(shù)的實(shí)現(xiàn):

代碼1-1 binder_ioctl()函數(shù)的實(shí)現(xiàn)

static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
int ret;
struct binder_proc *proc=filp->private_data;
struct binder_thread *thread;
unsigned int size=_IOC_SIZE(cmd);
void __user *ubuf=(void __user *)arg;
/*printk(KERN_INFO "binder_ioctl: %d:%d %x %lxn", proc->pid, current->pid, cmd, arg);*/
ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
if (ret)
return ret;
mutex_lock(&binder_lock);
thread=binder_get_thread(proc); //獲取一個(gè)Binder線程
if (thread==NULL) {
ret=-ENOMEM;
goto err;
}
switch (cmd) {
case BINDER_WRITE_READ: {
struct binder_write_read bwr;
if (size!=sizeof(struct binder_write_read)) {
ret=-EINVAL;
goto err;
}
if (copy_from_user(&bwr, ubuf, sizeof(bwr))) { //從用戶(hù)空間緩沖復(fù)制數(shù)據(jù)
ret=-EFAULT;
goto err;
}
if (binder_debug_mask & BINDER_DEBUG_READ_WRITE)
printk(KERN_INFO "binder: %d:%d write %ld at %08lx, read %ld at %08lxn",
proc->pid, thread->pid, bwr.write_size, bwr.write_buffer, bwr.read_size, bwr.read_buffer);
if (bwr.write_size > 0) {
ret=binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed); //傳遞數(shù)據(jù)
if (ret < 0) {
bwr.read_consumed=0;
if (copy_to_user(ubuf, &bwr, sizeof(bwr))) //將數(shù)據(jù)寫(xiě)回用戶(hù)空間
ret=-EFAULT;
goto err;
}
}
if (bwr.read_size>0) {
ret=binder_thread_read(proc, thread, (void __user *)bwr.read_buffer, bwr.read_size, &bwr.read_consumed, filp->f_flags & O_NONBLOCK); //讀取數(shù)據(jù)
if (!list_empty(&proc->todo))
wake_up_interruptible(&proc->wait); //喚醒掛起的線程
if (ret<0) {
if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
ret = -EFAULT;
goto err;
}
}
if (binder_debug_mask & BINDER_DEBUG_READ_WRITE)
printk(KERN_INFO "binder: %d:%d wrote %ld of %ld, read return %ld of %ldn",
proc->pid, thread->pid, bwr.write_consumed, bwr.write_size, bwr.read_consumed, bwr.read_size);
if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {
ret=-EFAULT;
goto err;
}
break;
}
case BINDER_SET_MAX_THREADS: 設(shè)置最大線程數(shù)
if (copy_from_user(&proc->max_threads, ubuf, sizeof(proc->max_threads))) {
ret=-EINVAL;
goto err;
}
break;
case BINDER_SET_CONTEXT_MGR: //設(shè)為上下文管理器
if (binder_context_mgr_node!=NULL) {
printk(KERN_ERR "binder: BINDER_SET_CONTEXT_MGR already setn");
ret=-EBUSY;
goto err;
}
if (binder_context_mgr_uid!=-1) {
if (binder_context_mgr_uid!=current->cred->euid) {
printk(KERN_ERR "binder:BINDER_SET_"
"CONTEXT_MGR bad uid %d!= %dn",
current->cred->euid,
binder_context_mgr_uid);
ret=-EPERM;
goto err;
}
} else
binder_context_mgr_uid=current->cred->euid;
binder_context_mgr_node=binder_new_node(proc, NULL, NULL);//新的RB樹(shù)節(jié)點(diǎn)
if (binder_context_mgr_node==NULL) {
ret=-ENOMEM;
goto err;
}
binder_context_mgr_node->local_weak_refs++;
binder_context_mgr_node->local_strong_refs++;
binder_context_mgr_node->has_strong_ref = 1;
binder_context_mgr_node->has_weak_ref = 1;
break;
case BINDER_THREAD_EXIT: //銷(xiāo)毀消除
if (binder_debug_mask & BINDER_DEBUG_THREADS)
printk(KERN_INFO "binder: %d:%d exitn",
proc->pid, thread->pid);
binder_free_thread(proc, thread); //釋放線程
thread=NULL;
break;
case BINDER_VERSION: //獲取Binder版本信息
if (size!=sizeof(struct binder_version)) {
ret=-EINVAL;
goto err;
}
if (put_user(BINDER_CURRENT_PROTOCOL_VERSION, &((struct binder_version *)ubuf)->protocol_version)) {
ret=-EINVAL;
goto err;
}
break;
default:
ret=-EINVAL;
goto err;
}
ret=0;
err:
if (thread)
thread->looper&=~BINDER_LOOPER_STATE_NEED_RETURN;
mutex_unlock(&binder_lock);
wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
if (ret && ret !=-ERESTARTSYS)
printk(KERN_INFO "binder: %d:%d ioctl %x %lx returned %dn", proc->pid, current->pid, cmd, arg, ret);
return ret;
}

2.電源管理

在目前的移動(dòng)終端中,系統(tǒng)承載的功能越來(lái)越多,同時(shí)為了獲得更好的用戶(hù)體驗(yàn),GUI的設(shè)計(jì)越來(lái)越華麗,但這都不可避免地增加了系統(tǒng)的功耗,導(dǎo)致目前的智能移動(dòng)終端普遍待機(jī)時(shí)間較短。在目前電池技術(shù)尚無(wú)法有大的突破情況下,電源管理顯得尤為重要,需要在滿(mǎn)足用戶(hù)需求的前提下,盡可能地減少功耗。電源管理策略是一個(gè)系統(tǒng)工程,應(yīng)用程序、內(nèi)核框架、設(shè)備驅(qū)動(dòng)、硬件設(shè)備都涉及其中。

對(duì)半導(dǎo)體器件而言,功耗分為靜態(tài)功耗、動(dòng)態(tài)功耗。靜態(tài)功耗主要是指待機(jī)狀態(tài)下的泄漏電流,動(dòng)態(tài)功耗才是電源管理要解決的主要問(wèn)題。

Android的電源管理機(jī)制是建立在標(biāo)準(zhǔn)的Linux電源管理機(jī)制ACPI (Advanced Configuration and Power Interface)之上的,同時(shí)針對(duì)移動(dòng)終端的特點(diǎn)采取了更積極的電源管理策略,支持休眠模式、動(dòng)態(tài)電壓和調(diào)頻調(diào)節(jié)、電源管理質(zhì)量服務(wù)(PM QoS)、喚醒鎖等。

休眠模式、動(dòng)態(tài)電壓和調(diào)頻調(diào)節(jié)等策略這里就不再多做介紹了。下面簡(jiǎn)要介紹PM QoS和喚醒鎖的實(shí)現(xiàn)。

1)PM QoS

在初始化階段,Android定義的PM QoS參數(shù)有3個(gè):cpu_dma_latency(CPU DMA延遲)、network_latency(網(wǎng)絡(luò)延遲)、 network_throughput(網(wǎng)絡(luò)吞吐量)。供驅(qū)動(dòng)、子系統(tǒng)、用戶(hù)空間應(yīng)用等注冊(cè)PM QoS請(qǐng)求。默認(rèn)的參數(shù)級(jí)別有延遲、超時(shí)(Aurora中暫時(shí)不用)、吞吐量等。

在Aurora(auroramsmmsmkernelpm_qos_params.c)中, PM QoS有4個(gè)參數(shù):PM_QOS_CPU_DMA_LATENCY、PM_QOS_NETWORK_LATENCY、PM_QOS_NETWORK_ THROUGHPUT和PM_QOS_SYSTEM_BUS_FREQ等,分別針對(duì)CPU DMA延遲、網(wǎng)絡(luò)延遲、網(wǎng)絡(luò)吞吐量、系統(tǒng)總線頻率等性能指標(biāo)。參數(shù)集的實(shí)現(xiàn)在pm_qos_power_init()函數(shù)中進(jìn)行,使用pm_qos_init()函數(shù)在內(nèi)核里可以增加新的參數(shù)。在系統(tǒng)中,PM QoS主要用來(lái)管理CPU空閑管理、WiFi應(yīng)用等。

在內(nèi)核空間,通過(guò)pm_qos_add_requirement()函數(shù)可以注冊(cè)PM QoS請(qǐng)求;通過(guò)pm_qos_update_requirement()函數(shù)可以更新已注冊(cè)的PM QoS請(qǐng)求;通過(guò)pm_qos_remove_requirement()函數(shù)可以刪除已注冊(cè)的PM QoS請(qǐng)求。圖2顯示了注冊(cè)PM QoS請(qǐng)求的過(guò)程。


圖2 注冊(cè)PM QoS請(qǐng)求的過(guò)程

在用戶(hù)空間,僅進(jìn)程可以注冊(cè)PM QoS請(qǐng)求,為了注冊(cè)PM QoS請(qǐng)求,進(jìn)程必須打開(kāi)/dev/[cpu_dma_latency, network_latency, network_throughput]設(shè)備,默認(rèn)的PM QoS請(qǐng)求名為“process_<PID>”。其中PID值在系統(tǒng)調(diào)用中獲得。

2)喚醒鎖

通過(guò)支持多種類(lèi)型的喚醒鎖(wake locks),Android支持組件在電源管理方面的請(qǐng)求。需要注意的是,在使用喚醒鎖時(shí)需要相當(dāng)小心。圖3顯示了創(chuàng)建喚醒鎖的過(guò)程。


圖3 創(chuàng)建喚醒鎖的過(guò)程

在實(shí)際的開(kāi)發(fā)過(guò)程中,為了測(cè)試各應(yīng)用電量消耗的情況,電量分析軟件powerTop不可或缺,它可以分析出每個(gè)具體的應(yīng)用對(duì)電量的消耗情況。

Android電源管理的實(shí)現(xiàn)主要位于auroramsmmsmkernelpower目錄下,主要的文件包括earlysuspend.c、consoleearlysuspend.c、fbearlysuspend.c、wakelock.c、userwakelock.c等。

在Java層,Android封裝了一個(gè)PowerManager類(lèi)來(lái)進(jìn)行電源的管理。

3.驅(qū)動(dòng)

驅(qū)動(dòng)的實(shí)現(xiàn)與硬件平臺(tái)密切相關(guān),由于在Linux Kernel 2.6中引入了Linux設(shè)備驅(qū)動(dòng)模型,Linux的驅(qū)動(dòng)開(kāi)發(fā)變得十分簡(jiǎn)單。在auroramsmmsmdrivers目錄中,Qualcomm提供了非常多的硬件驅(qū)動(dòng),如BT、i2C、USB、FM、音頻、視頻等。下面簡(jiǎn)要介紹部分驅(qū)動(dòng)的情況。

●顯示驅(qū)動(dòng)(Display Driver):常用基于Linux的幀緩沖( Buffer)驅(qū)動(dòng)。
●照相機(jī)驅(qū)動(dòng)(Camera):常用基于Linux的V4L2驅(qū)動(dòng)。
●音頻驅(qū)動(dòng):常用基于ALSA(高級(jí)Linux音頻架構(gòu),Advanced Linux Sound Architecture)驅(qū)動(dòng)。
●WIFI驅(qū)動(dòng):基于IEEE 802.11標(biāo)準(zhǔn)的驅(qū)動(dòng)程序。Aurora支持的WIFI標(biāo)準(zhǔn)為802.11 bgn。對(duì)WAPI的支持則需要硬件平臺(tái)廠商的支持。
●Binder IPC驅(qū)動(dòng):Android的一個(gè)特殊的驅(qū)動(dòng)程序,具有單獨(dú)的設(shè)備節(jié)點(diǎn),實(shí)現(xiàn)進(jìn)程間通信的功能。



本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

CPU親和度通過(guò)限制進(jìn)程或線程可以運(yùn)行的CPU核心集合,使得它們只能在指定的CPU核心上執(zhí)行。這可以減少CPU緩存的失效次數(shù),提高緩存命中率,從而提升系統(tǒng)性能。

關(guān)鍵字: Linux 嵌入式

在Linux系統(tǒng)性能優(yōu)化中,內(nèi)存管理與網(wǎng)絡(luò)連接處理是兩大核心領(lǐng)域。vm.swappiness與net.core.somaxconn作為關(guān)鍵內(nèi)核參數(shù),直接影響系統(tǒng)在高負(fù)載場(chǎng)景下的穩(wěn)定性與響應(yīng)速度。本文通過(guò)實(shí)戰(zhàn)案例解析這兩個(gè)...

關(guān)鍵字: Linux 內(nèi)存管理

對(duì)于LLM,我使用b谷歌Gemini的免費(fèi)層,所以唯一的成本是n8n托管。在使用了n8n Cloud的免費(fèi)積分后,我決定將其托管在Railway上(5美元/月)。然而,由于n8n是開(kāi)源的,您可以在自己的服務(wù)器上托管它,而...

關(guān)鍵字: 人工智能 n8n Linux

其他電腦(比如安卓手機(jī)/平板電腦)的屏幕壞了,你可能想在安排維修之前緊急訪問(wèn)一些東西。你可以使用android的USB OTG功能(是的,幾乎每個(gè)android都支持這個(gè)功能,你可以將鼠標(biāo)和鍵盤(pán)連接到它)。

關(guān)鍵字: USB 鼠標(biāo) Android 樹(shù)莓派

在Linux系統(tǒng)管理中,權(quán)限控制是安全運(yùn)維的核心。本文通過(guò)解析/etc/sudoers文件配置與組策略的深度應(yīng)用,結(jié)合某金融企業(yè)生產(chǎn)環(huán)境案例(成功攔截98.7%的非法提權(quán)嘗試),揭示精細(xì)化權(quán)限管理的關(guān)鍵技術(shù)點(diǎn),包括命令別...

關(guān)鍵字: Linux 用戶(hù)權(quán)限 sudoers文件

Linux內(nèi)核中的信號(hào)量(Semaphore)是一種用于資源管理的同步原語(yǔ),它允許多個(gè)進(jìn)程或線程對(duì)共享資源進(jìn)行訪問(wèn)控制。信號(hào)量的主要作用是限制對(duì)共享資源的并發(fā)訪問(wèn)數(shù)量,從而防止系統(tǒng)過(guò)載和數(shù)據(jù)不一致的問(wèn)題。

關(guān)鍵字: Linux 嵌入式

在云計(jì)算與容器化技術(shù)蓬勃發(fā)展的今天,Linux網(wǎng)絡(luò)命名空間(Network Namespace)已成為構(gòu)建輕量級(jí)虛擬網(wǎng)絡(luò)的核心組件。某頭部互聯(lián)網(wǎng)企業(yè)通過(guò)命名空間技術(shù)將測(cè)試環(huán)境資源消耗降低75%,故障隔離效率提升90%。本...

關(guān)鍵字: Linux 云計(jì)算

在Linux內(nèi)核4.18+和主流發(fā)行版(RHEL 8/Ubuntu 20.04+)全面轉(zhuǎn)向nftables的背景下,某電商平臺(tái)通過(guò)遷移將防火墻規(guī)則處理效率提升40%,延遲降低65%。本文基于真實(shí)生產(chǎn)環(huán)境案例,詳解從ipt...

關(guān)鍵字: nftables Linux

在Linux設(shè)備驅(qū)動(dòng)開(kāi)發(fā)中,等待隊(duì)列(Wait Queue)是實(shí)現(xiàn)進(jìn)程睡眠與喚醒的核心機(jī)制,它允許進(jìn)程在資源不可用時(shí)主動(dòng)放棄CPU,進(jìn)入可中斷睡眠狀態(tài),待資源就緒后再被喚醒。本文通過(guò)C語(yǔ)言模型解析等待隊(duì)列的實(shí)現(xiàn)原理,結(jié)合...

關(guān)鍵字: 驅(qū)動(dòng)開(kāi)發(fā) C語(yǔ)言 Linux

在Unix/Linux進(jìn)程間通信中,管道(pipe)因其簡(jiǎn)單高效被廣泛使用,但默認(rèn)的半雙工特性和無(wú)同步機(jī)制容易導(dǎo)致數(shù)據(jù)競(jìng)爭(zhēng)。本文通過(guò)父子進(jìn)程雙向通信案例,深入分析互斥鎖與狀態(tài)機(jī)在管道同步中的應(yīng)用,實(shí)現(xiàn)100%可靠的數(shù)據(jù)傳...

關(guān)鍵字: 管道通信 父子進(jìn)程 Linux
關(guān)閉