# MySQL多實例 ## 介紹 **應用場景**: **資金緊張公司** 若公司資金緊張,公司業務訪問量不太大,但又希望不同業務的資料庫服務各自能夠儘量獨立地提供服務而互相不受影響,或者,還有需要主從複製等技術提供備份或讀寫分離服務的需求,那麼,多實例就再好不過了。 **用戶併發訪問量不大的業務* ...
一、前言
ARMv8-M 支持 MPU,FreeRTOS 也添加了對這些 MPU 的應用代碼。這裡用來記錄 FreeRTOS 對 MPU 應用方式的探究結果。
二、ArmV8-M MPU 介紹
ARMv8-M MPU 支持每個安全狀態(non-secure 和 secure)0-8個區域的配置。
MPU 的主要特性如下:
- 區域最小大小為32位元組,最大為4GB,但必須為32位元組的整數倍
- 所有的區域必須以32位元組對齊
- 每個區域對兩個處理器模式(privileged 和 unprivileged)擁有獨立的讀/寫許可權
- eXecure Never(XN)屬性可以用來分割代碼段和數據段
三、FreeRTOS 對 MPU 的應用
FreeRTOS 對 MPU 的配置主要體現在2個方面:
- 配置 MPU Region,隔離 code / data
- 提供 unpriviliged task 調用 priviliged api 的機制
MPU Region 劃
以 8個 MPU Region 為例,FreeRTOS 對 MPU 的使用情況如下:
在該配置下,要求同一個 section 的 code / data 放在連續的地址空間;
若實際硬體上有多塊不連續的 flash 或 sram,則需要控制鏈接文件讓相同 section 的數據位於連續空間;
若實在無法滿足上述約束,則需要改造 FreeRTOS 的 MPU 配置(可能需要減少用戶自定義 Region 數量)。
系統調用方式
在 MPU 開啟後,kernel api 處於 privileged section, unprivilege task 會被MPU屏蔽而無權直接訪問;
FreeRTOS 提供了 wrapper 層,用於間接調用 kernel api,其命名為 MPU_xxx(xxx 是 kernel api 名稱)。
為了確保相容性,減少用戶調用的複雜性,FreeRTOS 還通過 mpu_wrapper.h 將 xxx 映射為 MPU_xxx。
系統調用目前有2個版本,分為 mpu_v1 和 mpu_v2。
1、MPU V1
mpu_v1 的工作流程如下:
可以看到,task 需要先調用 wrapper 層的介面 MPU_xxx,再由 wrapper 層調用 kernel api;
在 mpu_wrapper 中,會對 task 的許可權做檢查:
- privileged task : task 有權訪問 kernel privileged function,mpu_wrapper 直接調用 kernel api;
- unprivileged task : task 無權直接訪問 kernel privileged function,mpu_wrapper 需要先通過 svc 臨時提升任務許可權,然後調用 kernel api,最後在 mpu_wrapper 返回前恢複原始任務許可權;
2、MPU V2
mpu_v2 的工作流程如下:
與 mpu_v1 相比,mpu_v2 有如下改動:
- 添加了轉換層(mpu_wrapper_v2),用於隱藏內核對象句柄(FreeRTOS的內核對象句柄是內核對象的指針);
- unprivileged task 調用 kernel api 時,會將棧切換到專用的 system call stack;
根據討論,這麼做的主要目的是為了防止泄露信息給 unprivileged task.
四、MPU 對 FreeRTOS 的其他影響
pxTopOfStack 的變化
pxTopOfStack 是 TCB 中的首個成員,主要用於任務切換時記錄棧的位置。
-
在未開啟 MPU 時,pxTopOfStack 直接指向任務棧,cpu 上下文信息存儲在任務棧上;
-
在開啟 MPU 後,pxTopOfStack 指向 TCB 中的 ulContent 區域,cpu 上下文信息存儲在 ulContent 中,而任務的棧指針則存儲在 ulContent 中。