Biên dịch và xác minh

Bạn có thể 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ị (DTS). Tuy nhiên, trước khi áp dụng cây thiết bị (DT) lớp phủ 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 lớp phủ cây thiết bị (DTO).

Biên dịch bằng DTC

Khi sử dụng dtc để biên dịch .dts, bạn phải thêm lựa chọn -@ để thêm một nút __symbols__ vào .dtbo kết quả. 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ể dùng cho các tham chiếu.

Lệnh mẫu để tạo DT chính .dts:

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

Lệnh mẫu để tạo DT lớp phủ .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ủ lưu trữ

Quy trình xác minh có thể giúp bạn xác định những lỗi có thể xảy ra khi đặt DT lớp phủ lê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 lên máy chủ lưu trữ bằng cách mô phỏng hành vi của DTO bằng /include/ trong .dts.

Hình 1. Sử dụng cú pháp /include/ để mô phỏng DTO trên máy chủ lưu trữ.

  1. Tạo bản sao của lớp phủ .dts. Trong bản sao, hãy xoá 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 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 mà 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 để nhận DT đã hợp nhất. Đây phải là kết quả giống 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 một phân vùng lớp phủ blob cây thiết bị (DTBO). Để thêm các nút hoặc thực hiện thay đổi đối với các thuộc tính trong DT SoC, trình tải khởi động phải tự động phủ một DT dành riêng cho thiết bị lên DT SoC.

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

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

Lớp phủ có thể áp dụng cho các nút từ DT chính hoặc thêm các nút mới, nhưng không thể tham chiếu đến một nút được 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 (việc không hợp nhất sẽ tránh được xung đột về tên ký hiệu và sự phức tạp của các phần 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 , do overlay_1.dts thêm vào. Sau khi overlay_1 được áp dụng cho DT chính, nếu bạn cố gắng áp dụng overlay_2 cho DT kết quả, thì ứng dụng lớp phủ sẽ gặp lỗi do biểu tượng e không có trong bảng biểu tượng cho DT cơ sở.

main.dts overlay_1.dts overlay_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 trong 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ằng giá trị do overlay_2.dts đặt.

main.dts overlay_1.dts overlay_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 bắt buộc, hãy đảm bảo rằng trình tải khởi động có thể thực hiện những thao tác sau:

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

Để biết thông tin chi tiết về cấu trúc của phân vùng DTBO, hãy tham khảo bài viết Lớp phủ cây thiết bị.

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 của nhân 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 để đảm bảo rằng thuộc tính này chỉ định ít nhất một chỉ mục hình ảnh DTBO hợp lệ).
  • 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 hoặc thay đổi về thuộc tính khác trong DT kết quả sẽ đượ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 của kernel sẽ vượt qua quy trình xác thực, nhưng việc thêm androidboot.dtbo_idx=3,5 vào dòng lệnh của kernel sẽ không vượt qua quy trình xác thực.

Lớp phủ DT tại chỉ mục 3 Lớp phủ DT ở chỉ mục 5
[overlay_1.dts]

/dts-v1/;
/plugin/;

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

/dts-v1/;
/plugin/;

&c { prop = <0xff>; };
Chung kết DT

/dts-v1/;
/ {

	a {
		phandle = <0x1>;
	};

	b {
		phandle = <0x2>;
	};

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

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