Biên dịch & Xác minh

Bạn có thể sử dụng Trình biên dịch cây thiết bị (DTC) để biên dịch các tệp Nguồn cây thiết bị. Tuy nhiên, trước khi áp dụng lớp phủ DT trên DT chính mục tiêu, bạn cũng nên xác minh kết quả bằng cách mô phỏng hành vi của DTO.

Biên dịch với DTC

Khi sử dụng dtc để biên dịch .dts , bạn phải thêm tùy chọn -@ để thêm nút __symbols__ vào kết quả .dtbo . Nút __symbols__ chứa danh sách tất cả các nút được đánh dấu bằng nhãn mà thư viện DTO có thể sử dụng để tham khảo.

Lệnh mẫu để xây dựng DT .dts chính:

dtc -@ -O dtb -o my_main_dt.dtb my_main_dt.dts

Lệnh mẫu để xây dựng lớp phủ DT .dts :

dtc -@ -O dtb -o my_overlay_dt.dtbo my_overlay_dt.dts

Xác minh kết quả DTO trên máy chủ

Việc xác minh có thể giúp bạn xác định các lỗi có thể xảy ra khi đặt DT lớp phủ trên DT chính. Trước khi cập nhật mục tiêu, bạn có thể xác minh kết quả của việc phủ DT trên máy chủ bằng cách mô phỏng hành vi của DTO bằng cách sử dụng /include/ trong .dts .

Hình 1. Sử dụng cú pháp /include/ để mô phỏng DTO trên máy chủ
  1. Tạo một bản sao của lớp phủ .dts . Trong bản sao, hãy xóa tiêu đề dòng đầu tiên. Ví dụ:
    /dts-v1/;
    /plugin/;
    
    Lưu tệp dưới dạng my_overlay_dt_wo_header.dts (hoặc bất kỳ tên tệp nào bạn muốn).
  2. Tạo một bản sao của .dts chính. Trong bản sao, sau dòng cuối cùng, hãy thêm cú pháp include cho tệp bạn đã tạo ở bước 1. Ví dụ:
    /include/ "my_overlay_dt_wo_header.dts"
    
    Lưu tệp dưới dạng my_main_dt_with_include.dts (hoặc bất kỳ tên tệp nào bạn muốn).
  3. Sử dụng dtc để biên dịch my_main_dt_with_include.dts để lấy DT đã hợp nhất, kết quả này sẽ cho kết quả tương tự như DTO. Ví dụ:
    dtc -@ -O dtb -o my_merged_dt.dtb my_main_dt_with_include.dts
    
  4. Sử dụng dtc để kết xuất my_merged_dt.dto .
    dtc -O dts -o my_merged_dt.dts my_merged_dt.dtb
    

Xác minh DTO trong Android 9

Android 9 yêu cầu phân vùng Lớp phủ Blob cây thiết bị (DTBO). Để thêm nút hoặc thực hiện các thay đổi đối với thuộc tính trong SoC DT, bộ tải khởi động phải tự động phủ một DT cụ thể của thiết bị lên trên SoC DT.

Cho biết lớp phủ được áp dụng

Để cho phép Bộ kiểm tra nhà cung cấp (VTS) đánh giá tính chính xác của ứng dụng lớp phủ, nhà cung cấp phải thêm tham số dòng lệnh kernel mới androidboot.dtbo_idx cho biết lớp phủ được chọn từ phân vùng DTBO. Trong Android 12 sử dụng kernel phiên bản 5.10 trở lên, tham số này sẽ chuyển qua bootconfig. Ví dụ: tham số androidboot.dtbo_idx=x,y,z báo cáo x , yz là các chỉ mục dựa trên 0 của Lớp phủ cây thiết bị (DTO) từ phân vùng DTBO được bộ tải khởi động áp dụng (theo thứ tự đó) cho cơ sở Cây thiết bị (DT).

Lớp phủ có thể áp dụng cho các nút từ cây thiết bị chính hoặc thêm các nút mới nhưng không thể tham chiếu đến nút đã thêm trong lớp phủ trước đó. Hạn chế này là cần thiết vì ứng dụng lớp phủ không hợp nhất bảng ký hiệu lớp phủ với bảng ký hiệu DT chính (không hợp nhất sẽ tránh xung đột về tên ký hiệu và sự phức tạp của sự phụ thuộc giữa các lớp phủ).

Ví dụ: Lớp phủ không hợp lệ

Trong ví dụ này, overlay_2.dts đề cập đến nút e , được thêm bởi overlay_1.dts . Sau khi overlay_1 được áp dụng cho DT chính, nếu cố gắng áp dụng overlay_2 cho DT kết quả, ứng dụng lớp phủ sẽ thất bại với lỗi ký hiệu e không có trong bảng ký hiệu cho DT cơ sở.

main.dts lớp phủ_1.dts lớp phủ_2.dts
[main.dts]

/dts-v1/;

/ {
  a: a {};
  b: b {};
  c: c {};
};
[overlay_1.dts]

/dts-v1/;
/plugin/;

&b { ref1 =  <&a>;
    e: e {
        prop = <0x0a>;
        phandle = <0x04>;
    };
};
[overlay_2.dts]

/dts-v1/;
/plugin/;

/* invalid! */
&e {
    prop = <0x0b>;
};

Ví dụ: Lớp phủ hợp lệ

Trong ví dụ này, overlay_2.dts chỉ đề cập đến nút b từ DTS chính. Khi overlay_1 được áp dụng cho DT cơ sở, sau đó là ứng dụng overlay_2 , giá trị của thuộc tính prop trong nút e (do overlay_1.dts đặt) sẽ bị ghi đè bởi giá trị do overlay_2.dts đặt.

main.dts lớp phủ_1.dts lớp phủ_2.dts
[final.dts]

/dts-v1/;

/ {
  a: a {};
  b: b {};
  c: c {};
};
[overlay_1.dts]

/dts-v1/;
/plugin/;


&b { ref1 =  <&a>;
     e {
          prop = <0x0c>;
      };
};
[overlay_2.dts]

/dts-v1/;
/plugin/;

/* valid */
&b { ref1 =  <&c>;
     e {
          prop = <0x0d>;
      };
};

Triển khai phân vùng DTBO

Để triển khai phân vùng DTBO cần thiết, hãy đảm bảo bộ nạp khởi động có thể thực hiện các thao tác sau:

  1. Xác định bảng đang chạy và chọn (các) lớp phủ tương ứng sẽ được áp dụng.
  2. Nối tham số androidboot.dtbo_idx vào dòng lệnh kernel.
    • Tham số phải chỉ ra các chỉ số dựa trên 0 của DTO từ hình ảnh phân vùng DTBO mà nó áp dụng cho DT cơ sở (theo cùng thứ tự).
    • Các chỉ số phải tham chiếu đến vị trí của lớp phủ trong phân vùng DTBO.

Để biết chi tiết về cấu trúc của phân vùng DTBO, hãy tham khảo Lớp phủ cây thiết bị trên source.android.com.

Xác thực phân vùng DTBO

Bạn có thể sử dụng VTS để xác minh những điều sau:

  • Sự tồn tại của tham số dòng lệnh kernel androidboot.dtbo_idx (bằng cách kiểm tra xem Init có tự động thiết lập thuộc tính hệ thống ro.boot.dtbo_idx tương ứng hay không).
  • Tính hợp lệ của thuộc tính hệ thống ro.boot.dtbo_idx (bằng cách kiểm tra xem thuộc tính đó có chỉ định ít nhất một chỉ mục hình ảnh DTBO hợp lệ hay không).
  • Tính hợp lệ của phân vùng DTBO (cũng xác minh các lớp phủ trong phân vùng DTBO được áp dụng cho DT cơ sở).
  • Các nút bổ sung hoặc các thay đổi thuộc tính trong DT kết quả được trình bày cho nhân Linux.

Ví dụ: trong các lớp phủ và DT cuối cùng sau đây, việc thêm androidboot.dtbo_idx=5,3 vào dòng lệnh kernel sẽ vượt qua quá trình xác thực nhưng việc thêm androidboot.dtbo_idx=3,5 vào dòng lệnh kernel sẽ không vượt qua quá trình xác thực.

Lớp phủ DT ở chỉ số 3 Lớp phủ DT ở chỉ số 5
[overlay_1.dts]

/dts-v1/;
/plugin/;

&c { prop = <0xfe>; };
[overlay_2.dts]

/dts-v1/;
/plugin/;

&c { prop = <0xff>; };
ĐT cuối cùng
/dts-v1/;
/ {

	a {
		phandle = <0x1>;
	};

	b {
		phandle = <0x2>;
	};

	c {
		phandle = <0x3>;
		prop = <0xfe>;
	};

	__symbols__ {
		a = "/a";
		b = "/b";
		c = "/c";
	};
};