標準系統(tǒng)移植指南
本文描述了移植一塊開發(fā)板的通用步驟,和具體芯片相關的詳細移植過程無法在此一一列舉。后續(xù)社區(qū)還會陸續(xù)發(fā)布開發(fā)板移植的實例供開發(fā)者參考。
定義開發(fā)板
本文以移植名為 MyProduct 的開發(fā)板為例講解移植過程,假定 MyProduct 是 MyProductVendor 公司的開發(fā)板,使用 MySoCVendor 公司生產的 MySOC 芯片作為處理器。
定義產品
在 //vendor/MyProductVendor/{product_name} 名稱的目錄下創(chuàng)建一個 config.json 文件,該文件用于描述產品所使用的 SOC 以及所需的子系統(tǒng)。配置如下:
//vendor/MyProductVendor/MyProduct/config.json
{
"product_name": "MyProduct",
"version": "3.0",
"type": "standard",
"target_cpu": "arm",
"ohos_version": "OpenHarmony 1.0",
"device_company": "MyProductVendor",
"board": "MySOC",
"enable_ramdisk": true,
"subsystems": [
{
"subsystem": "ace",
"components": [
{ "component": "ace_engine_lite", "features":[] }
]
},
...
]
}
?
主要的配置內容
已定義的子系統(tǒng)可以在“//build/subsystem_config.json”中找到。當然你也可以定制子系統(tǒng)。
這里建議先拷貝 Hi3516DV300 開發(fā)板的配置文件,刪除掉 hisilicon_products 這個子系統(tǒng)。這個子系統(tǒng)為 Hi3516DV300 SOC 編譯內核,顯然不適合 MySOC。
移植驗證
至此,你可以使用如下命令,啟動你產品的構建了:
./build.sh --product-name MyProduct
構建完成后,可以在 //out/{device_name}/packages/phone/images
目錄下看到構建出來的 OpenHarmony 鏡像文件。
內核移植
這一步需要移植 Linux 內核,讓 Linux 內核可以成功運行起來。
為 SOC 添加內核構建的子系統(tǒng)
修改文件 //build/subsystem_config.json
增加一個子系統(tǒng)。配置如下:
"MySOCVendor_products": {
"project": "hmf/MySOCVendor_products",
"path": "device/MySOCVendor/MySOC/build",
"name": "MySOCVendor_products",
"dir": "device/MySOCVendor"
},
接著需要修改定義產品的配置文件 //vendor/MyProductVendor/MyProduct/config.json,
將剛剛定義的子系統(tǒng)加入到產品中。
編譯內核
源碼中提供了 Linux 4.19 的內核,歸檔在 //kernel/linux-4.19
。本節(jié)以該內核版本為例,講解如何編譯內核。
在子系統(tǒng)的定義中,描述了子系統(tǒng)構建的路徑 path,即 //device/MySOCVendor/MySOC/build
。這一節(jié)會在這個目錄創(chuàng)建構建腳本,告訴構建系統(tǒng)如何構建內核。
建議的目錄結構:
├── build
│ ├── kernel
│ │ ├── linux
│ │ ├──standard_patch_for_4_19.patch // 基于4.19版本內核的補丁
│ ├── BUILD.gn
│ ├── ohos.build
?
BUILD.gn 是 subsystem 構建的唯一入口。
期望的構建結果
文件 | 文件說明 |
---|---|
$root_build_dir/packages/phone/images/uImage | 內核鏡像 |
$root_build_dir/packages/phone/images/uboot | bootloader 鏡像 |
移植驗證
啟動編譯,驗證預期的 kernel 鏡像是否成功生成。
用戶態(tài)啟動引導
1.用戶態(tài)進程啟動引導總覽。
系統(tǒng)上電加載內核后,按照以下流程完成系統(tǒng)各個服務和應用的啟動:
1.內核啟動 init 進程,一般在 bootloader 啟動內核時通過設置內核的 cmdline 來指定 init 的位置;如上圖所示的"init=/init root/dev/xxx"。
2.init 進程啟動后,會掛載 tmpfs,procfs,創(chuàng)建基本的 dev 設備節(jié)點,提供最基本的根文件系統(tǒng)。
3.init 繼續(xù)啟動 ueventd 監(jiān)聽內核熱插拔事件,為這些設備創(chuàng)建 dev 設備節(jié)點;包括 block 設備各個分區(qū)設備都是通過此事件創(chuàng)建。
4.init 進程掛載 block 設備各個分區(qū)(system,vendor),開始掃描各個系統(tǒng)服務的 init 啟動腳本,并拉起各個 SA 服務。
5.samgr 是各個 SA 的服務注冊中心,每個 SA 啟動時,都需要向 samgr 注冊,每個 SA 會分配一個 ID,應用可以通過該 ID 訪問 SA。
6.foundation 是一個特殊的 SA 服務進程,提供了用戶程序管理框架及基礎服務;由該進程負責應用的生命周期管理。
7.由于應用都需要加載 JS 的運行環(huán)境,涉及大量準備工作,因此 appspawn 作為應用的孵化器,在接收到 foundation 里的應用啟動請求時,可以直接孵化出應用進程,減少應用啟動時間。
init。
init 啟動引導組件配置文件包含了所有需要由 init 進程啟動的系統(tǒng)關鍵服務的服務名、可執(zhí)行文件路徑、權限和其他信息。每個系統(tǒng)服務各自安裝其啟動腳本到 /system/etc/init 目錄下。
新芯片平臺移植時,平臺相關的初始化配置需要增加平臺相關的初始化配置文件 /vendor/etc/init/init.{hardware}.cfg;該文件完成平臺相關的初始化設置,如安裝 ko 驅動,設置平臺相關的 /proc 節(jié)點信息。
init 相關進程代碼在 //base/startup/init_lite 目錄下,該進程是系統(tǒng)第一個進程,無其它依賴。
HDF 驅動移植
LCD
HDF 為 LCD 設計了驅動模型。支持一塊新的 LCD,需要編寫一個驅動,在驅動中生成模型的實例,并完成注冊。
這些 LCD 的驅動被放置在 //drivers/hdf_core/framework/model/display/driver/panel
目錄中。
1.創(chuàng)建 Panel 驅動
在驅動的 Init 方法中,需要調用 RegisterPanel 接口注冊模型實例。如:
int32_t XXXInit(struct HdfDeviceObject *object)
{
struct PanelData *panel = CreateYourPanel();
// 注冊
if (RegisterPanel(panel) != HDF_SUCCESS) {
HDF_LOGE("%s: RegisterPanel failed", __func__);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
struct HdfDriverEntry g_xxxxDevEntry = {
.moduleVersion = 1,
.moduleName = "LCD_XXXX",
.Init = XXXInit,
};
HDF_INIT(g_xxxxDevEntry);
?
2.配置加載 panel 驅動產品的所有設備信息被定義在文件 //vendor/MyProductVendor/MyProduct/config/device_info/device_info.hcs
中。修改該文件,在 display 的 host 中,名為 device_lcd 的 device 中增加配置。
注意:moduleName 要與 panel 驅動中的 moduleName 相同。
root {
...
display :: host {
device_lcd :: device {
deviceN :: deviceNode {
policy = 0;
priority = 100;
preload = 2;
moduleName = "LCD_XXXX";
}
}
}
}
?
觸摸屏
本節(jié)描述如何移植觸摸屏驅動。觸摸屏的驅動被放置在 //drivers/hdf_core/framework/model/input/driver/touchscreen
目錄中。移植觸摸屏驅動主要工作是向系統(tǒng)注冊 ChipDevice 模型實例。
1.創(chuàng)建觸摸屏器件驅動
在目錄中創(chuàng)建名為 touch_ic_name.c 的文件。代碼模板如下:注意:請?zhí)鎿Q ic_name 為你所適配芯片的名稱。
#include "hdf_touch.h"
static int32_t HdfXXXXChipInit(struct HdfDeviceObject *device)
{
ChipDevice *tpImpl = CreateXXXXTpImpl();
if(RegisterChipDevice(tpImpl) != HDF_SUCCESS) {
ReleaseXXXXTpImpl(tpImpl);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
struct HdfDriverEntry g_touchXXXXChipEntry = {
.moduleVersion = 1,
.moduleName = "HDF_TOUCH_XXXX",
.Init = HdfXXXXChipInit,
};
HDF_INIT(g_touchXXXXChipEntry);
?
其中 ChipDevice 中要提供若干方法。
2.配置產品,加載器件驅動
產品的所有設備信息被定義在文件 //vendor/MyProductVendor/MyProduct/config/device_info/device_info.hcs
中。修改該文件,在名為 input 的 host 中,名為 device_touch_chip 的 device 中增加配置。注意:moduleName 要與觸摸屏驅動中的 moduleName 相同。
deviceN :: deviceNode {
policy = 0;
priority = 130;
preload = 0;
permission = 0660;
moduleName = "HDF_TOUCH_XXXX";
deviceMatchAttr = "touch_XXXX_configs";
}
?
WLAN
Wi-Fi 驅動分為兩部分,一部分負責管理 WLAN 設備,另一個部分負責處理 WLAN 流量。HDF WLAN 分別為這兩部分做了抽象。目前支持 SDIO 接口的 WLAN 芯片。
圖 1 WLAN 芯片
支持一款芯片的主要工作是實現(xiàn)一個 ChipDriver 驅動。實現(xiàn) HDF_WLAN_CORE 和 NetDevice 提供的接口。主要需要實現(xiàn)的接口有:
接口 | 定義頭文件 | 說明 |
---|---|---|
HdfChipDriverFactory | //drivers/hdf_core/framework/include/wifi/hdf_wlan_chipdriver_manager.h | ChipDriver 的 Factory,用于支持一個芯片多個 Wi-Fi 端口 |
HdfChipDriver | //drivers/hdf_core/framework/include/wifi/wifi_module.h | 每個 WLAN 端口對應一個 HdfChipDriver,用來管理一個特定的 WLAN 端口 |
NetDeviceInterFace | //drivers/hdf_core/framework/include/net/net_device.h | 與協(xié)議棧之間的接口,如發(fā)送數(shù)據(jù)、設置網(wǎng)絡接口狀態(tài)等 |
建議適配按如下步驟操作:
創(chuàng)建 HDF 驅動建議將代碼放置在 //device/MySoCVendor/peripheral/wifi/chip_name/
,文件模板如下:
static int32_t HdfWlanXXXChipDriverInit(struct HdfDeviceObject *device) {
static struct HdfChipDriverFactory factory = CreateChipDriverFactory();
struct HdfChipDriverManager *driverMgr = HdfWlanGetChipDriverMgr();
if (driverMgr->RegChipDriver(&factory) != HDF_SUCCESS) {
HDF_LOGE("%s fail: driverMgr is NULL!", __func__);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
struct HdfDriverEntry g_hdfXXXChipEntry = {
.moduleVersion = 1,
.Init = HdfWlanXXXChipDriverInit,
.Release = HdfWlanXXXChipRelease,
.moduleName = "HDF_WIFI_CHIP_XXX"
};
HDF_INIT(g_hdfXXXChipEntry);
?
在 CreateChipDriverFactory 中,需要創(chuàng)建一個 HdfChipDriverFactory,接口如下:
接口 | 說明 |
---|---|
const char *driverName | 當前 driverName |
int32_t (*InitChip)(struct HdfWlanDevice *device) | 初始化芯片 |
int32_t (*DeinitChip)(struct HdfWlanDevice *device) | 去初始化芯片 |
void (_ReleaseFactory)(struct HdfChipDriverFactory _factory) | 釋放 HdfChipDriverFactory 對象 |
struct HdfChipDriver _(_Build)(struct HdfWlanDevice *device, uint8_t ifIndex) | 創(chuàng)建一個 HdfChipDriver;輸入參數(shù)中,device 是設備信息,ifIndex 是當前創(chuàng)建的接口在這個芯片中的序號 |
void (_Release)(struct HdfChipDriver _chipDriver) | 釋放 chipDriver |
uint8_t (*GetMaxIFCount)(struct HdfChipDriverFactory *factory) | 獲取當前芯片支持的最大接口數(shù) |
HdfChipDriver 需要實現(xiàn)的接口有:
接口 | 說明 |
---|---|
int32_t (*init)(struct HdfChipDriver *chipDriver, NetDevice *netDev) | 初始化當前網(wǎng)絡接口,這里需要向 netDev 提供接口 |
int32_t (*deinit)(struct HdfChipDriver *chipDriver, NetDevice *netDev) | 去初始化當前網(wǎng)絡接口 |
struct HdfMac80211BaseOps *ops | WLAN 基礎能力接口集 |
struct HdfMac80211STAOps *staOps | 支持 STA 模式所需的接口集 |
struct HdfMac80211APOps *apOps | 支持 AP 模式所需要的接口集 |
2.編寫配置文件,描述驅動支持的設備。
在產品配置目錄下創(chuàng)建芯片的配置文件 //vendor/MyProductVendor/MyProduct/config/wifi/wlan_chip_chip_name.hcs。
注意: 路徑中的 vendor_name、product_name、chip_name 請?zhí)鎿Q成實際名稱。
模板如下:
root {
wlan_config {
chip_name :& chipList {
chip_name :: chipInst {
match_attr = "hdf_wlan_chips_chip_name"; /* 這是配置匹配屬性,用于提供驅動的配置根 */
driverName = "driverName"; /* 需要與HdfChipDriverFactory中的driverName相同*/
sdio {
vendorId = 0x0296;
deviceId = [0x5347];
}
}
}
}
}
?
3.編寫配置文件,加載驅動。
產品的所有設備信息被定義在文件 //vendor/MyProductVendor/MyProduct/config/device_info/device_info.hcs
中。修改該文件,在名為 network 的 host 中,名為 device_wlan_chips 的 device 中增加配置。
注意:moduleName 要與觸摸屏驅動中的 moduleName 相同。
deviceN :: deviceNode {
policy = 0;
preload = 2;
moduleName = "HDF_WLAN_CHIPS";
deviceMatchAttr = "hdf_wlan_chips_chip_name";
serviceName = "driverName";
}
?
4.構建驅動
-
創(chuàng)建內核菜單在
//device/MySoCVendor/peripheral
目錄中創(chuàng)建 Kconfig 文件,內容模板如下:
config DRIVERS_WLAN_XXX
bool "Enable XXX WLAN Host driver"
default n
depends on DRIVERS_HDF_WIFI
help
Answer Y to enable XXX Host driver. Support chip xxx
?
接著修改文件 //drivers/hdf_core/adapter/khdf/linux/model/network/wifi/Kconfig
,在文件末尾加入如下代碼將配置菜單加入內核中,如:
source "../../../../../device/MySoCVendor/peripheral/Kconfig"
?
-
創(chuàng)建構建腳本
在//drivers/hdf_core/adapter/khdf/linux/model/network/wifi/Makefile
文件末尾增加配置,模板如下:
HDF_DEVICE_ROOT := $(HDF_DIR_PREFIX)/../device
obj-$(CONFIG_DRIVERS_WLAN_XXX) += $(HDF_DEVICE_ROOT)/MySoCVendor/peripheral/build/standard/
?
當在內核中開啟 DRIVERS_WLAN_XXX 開關時,會調用 //device/MySoCVendor/peripheral/build/standard/
中的 makefile。
為了能讓大家更好的學習鴻蒙 (OpenHarmony) 開發(fā)技術,這邊特意整理了《鴻蒙 (OpenHarmony)開發(fā)學習手冊》,希望對大家有所幫助:
《鴻蒙(Harmony OS)開發(fā)學習手冊》
入門必看:https://docs.qq.com/doc/DUk51cHZJaUpmSlhH
1.應用開發(fā)導讀(ArKTS)
2.……
HarmonyOS概念:https://docs.qq.com/doc/DUk51cHZJaUpmSlhH
1.系統(tǒng)定義
2.技術框架
3.技術特性
4.系統(tǒng)安全
快速入門:https://docs.qq.com/doc/DUk51cHZJaUpmSlhH
1.基本概念
2.構建第一個ArkTS應用
3.……
開發(fā)基礎知識:https://docs.qq.com/doc/DUk51cHZJaUpmSlhH
1.應用基礎知識
2.配置文件
3.應用數(shù)據(jù)管理
4.應用安全管理
5.應用隱私保護
6.三方應用調用管控機制
7.資源分類與訪問
8.學習ArkTS
9…
基于ArkTS 開發(fā):https://docs.qq.com/doc/DUk51cHZJaUpmSlhH
1.Ability開發(fā)
2.UI開發(fā)
3.公共事件與通知
4.窗口管理
5.媒體
6.安全
7.網(wǎng)絡與鏈接
8.電話服務
9.數(shù)據(jù)管理
10.后臺任務(Background Task)管理
11.設備管理
12.設備使用信息統(tǒng)計
13.DFX
14.國際化開發(fā)
15.折疊屏系列
16………
-
系統(tǒng)移植
+關注
關注
0文章
16瀏覽量
4821 -
鴻蒙
+關注
關注
57文章
2321瀏覽量
42749 -
HarmonyOS
+關注
關注
79文章
1967瀏覽量
30035
發(fā)布評論請先 登錄
相關推薦
評論