GKI için çekirdek kodu geliştirme

Genel Kernel Görüntüsü (GKI), birbirine yakın hizalayarak çekirdek parçasını azaltmaktadır çekirdeğiyle test edebilirsiniz. Ancak, bu durumun geçerli nedenleri bazı yamalar yayın yolunda kabul edilemez ve yerine getirilmelidir, böylece bazı yamalar Android Ortak Çekirdeği'nde (ACK) tutulur. temel kaynaklardır.

Geliştiriciler, kod değişikliklerini yukarı akışta Linux Kernel Postalama'yı kullanarak göndermelidir. LKML'yi ilk seçenek olarak listeleyin ve kod değişikliklerini ACK'ye gönderin android-mainline, yalnızca yukarı akışın iyi olmamasının güçlü bir nedeni olduğunda dal uygulanabilir. Geçerli neden örnekleri ve bunların nasıl ele alınacağına dair örnekler aşağıda verilmiştir.

  • Yama LKML'ye gönderildi ancak bir ürün için zamanında kabul edilmedi kullanabilirsiniz. Bu yamayı işlemek için:

    • Yamanın LKML'ye gönderildiğine dair kanıt ve yorumlar sunma ya da yamanın uygulanması için gereken tahmini iki örnektir.
    • Yamayı ACK'ye uygulamak ve onaylanmasını sağlamak için nasıl bir yol izleyeceğinize karar verin Sonra bu videoyu ACK'den çıkarırsınız. ACK ile birleştirilir.
  • Yama, tedarikçi modülü için EXPORT_SYMBOLS_GPL() öğesini tanımlıyor ancak çalıştırılamadı ağaç içi modüller içermediğinden yukarı akışla anlamına gelir. Bu yamayı işlemek için modülünüzün neden ve videoyu yapmadan önce üzerinde düşüneceğiniz alternatifler isteğinde bulunabilirsiniz.

  • Yama, yayın öncesi için yeterince genel değil ve bunu yapmak için zaman yok yeniden düzenlemenizi sağlamak. Bu yamayı işlemek için yeniden düzenlenen bir yamanın yukarı akışa ( yama, yeniden düzenleme gönderme planı olmadan ACK'de kabul edilmez inceleme için yukarı akışa yama uygulayın).

  • Yama, yayın öncesi tarafından kabul edilemiyor çünkü... <neden girin burada> bulabilirsiniz. Bu yamayı işlemek için Android çekirdek ekibine ulaşın ve gönderilebilmesi için yamayı yeniden düzenleme seçenekleri konusunda bizimle birlikte çalışın. ve kabul edilen yayın akışı ekleyin.

Daha pek çok olası gerekçe vardır. Hatanızı veya geçerli bir gerekçe ekleyin ve açıklamanın tekrarlanmasını bekleyin. ACK'nin, özellikle çocukların herkes yukarı akış üzerine çalışmayı öğrenirken bir yandan da GKI’nın aşamalarında ürün programlarını nasıl kullanacağınızı öğrenin. Lansman gereksinimlerinin gün geçtikçe artması bekleniyor zamanla sertleşir.

Yama gereksinimleri

Yamalar, Linux kaynak ağacı, gönderilip gönderilmediğine bakılır. scripts/checkpatch.pl komut dosyası, Gerrit ön gönderme testinin bir parçası olarak çalıştırıldığı için emin olun. checkpatch komut dosyasını gönderim öncesi testi için //build/kernel/static_analysis:checkpatch_presubmit kullanın. Ayrıntılar için bkz. build/kernel/kleaf/docs/checkpatch.md adresini ziyaret edin.

ACK yamaları

ACK'ya gönderilen yamalar Linux çekirdek kodlama standartlarına uygun olmalıdır. katkıda bulunma kurallarına uymalıdır. Change-Id eklemeniz gerekir etiket, yamayı birden fazla dala gönderirseniz ( örneğin, android-mainline ve android12-5.4) aynı değeri kullanmanız gerekir. Yamanın tüm örnekleri için Change-Id.

Yayın öncesi incelemesi için öncelikle LKML'ye yama gönderin. Yama:

  • Yukarı akış kabul edilir, otomatik olarak android-mainline altında birleştirilir.
  • Yukarı akış kabul edilmedi, android-mainline için bir bir yayın öncesi gönderime veya bunun neden olmadığına dair bir açıklamaya LKML'ye gönderildi.

Yama, yukarı akışla veya android-mainline ürününde kabul edildikten sonra LTS tabanlı uygun ACK'ye (ör. android12-5.4 ve android11-5.4 (Android'e özgü kodu düzelten yamalar için) Gönderildiği yer: android-mainline, yeni yukarı akış sürüm adaylarıyla test yapılmasını sağlar ve yamanın bir sonraki LTS tabanlı ACK'de yer alacağını garanti eder. İstisnalar arasında Burada bir yukarı akış yamasının android12-5.4 öğesine geri bağlandığından (yama, muhtemelen android-mainline içindedir).

Yukarı akış yamaları

Katkıda belirtildiği gibi yönergeler ACK çekirdeklerine yönelik yukarı akış yamaları aşağıdaki gruplara ayrılır (listelenen öncelik sırasına göre ).

  • UPSTREAM: - "android-mainline"dan alınan yamalar büyük olasılıkla kabul edilir.
  • BACKPORT: - Yukarı akıştan gelen, düzgün şekilde çalışmayan ve değişikliklerinin kabul edilmesi için makul bir kullanım olması dava açın.
  • FROMGIT: - Hazırlık aşamasında bakım dalından alınan yamalar Linux ana hattına gönderim için yakın bir tarihte, belirlemelisiniz. Bunların hem içerik hem de program açısından gerekçelendirilmesi gerekir.
  • FROMLIST: - LKML'ye gönderilmiş ancak gönderilmemiş yamalar kabul edilmeleri henüz olası değildir. Gerekçe, yamanın kabul edileceği kadar ikna edici olmalıdır veya yukarı akış Linux'a ulaşıp ulaşmayacağını (bunların sona ermeyeceğini varsayıyoruz). Orada Tartışmayı kolaylaştırmak için FROMLIST yamalarıyla ilişkili bir sorun olmalıdır daha fazla bilgi edineceksiniz.

Android'e özel yamalar

Yukarı akışla gerekli değişiklikleri sağlayamazsanız aşağıdakileri göndermeyi deneyebilirsiniz: ağaç dışı yamaları doğrudan ACK'ye gönderir. Ağaç dışı yama göndermek için şunlar gerekir: BT departmanında, çözümün neden gerektiğiyle ilgili olarak yama yayın yolunda gönderilemez (örnekler için önceki listeye bakın). Ancak kodun yukarı akışla gönderilemediği birkaç durum vardır. Bu destek kayıtları aşağıdaki gibidir ve katkıya uygun olmalıdır: kuralları özel yamalar ve ANDROID: önekiyle konu.

gki_defconfig değişiklikleri

gki_defconfig için yapılan tüm CONFIG değişiklikleri hem kol64 hem de kol 64'e uygulanmalıdır CONFIG, mimariye özgü değilse x86 sürümleri. Değişiklik talep etmek için CONFIG ayarına geçirmek için, BT'de değişikliği tartışmak üzere bir sorun oluşturun. Herhangi biri Çekirdek Modülü Arabirimi'ni (KMI) etkileyen CONFIG değişikliği dondurulmuş reddedildi. İş ortaklarının, çakışan yapılandırmanın farklı yolları varsa, çakışmaları şurada tartışarak çözeriz: gözden geçirin.

Yukarı akışta olmayan kod

Android'e özgü olan kod değişiklikleri, yukarı akışla gönderilemez. Örneğin, bağlayıcı sürücüsü yukarı akışla korunuyor olsa da, bağlayıcı sürücünün öncelikli devralma özelliklerine Android'e özgüdür. Hatanızda açık olun ve kodu yukarı akış için gönderilemez. Mümkünse bantları daha kolay İleri akış ve Android'e özel, gönderilemeyen parçalar gönderilebilir. ağaç dışı kod miktarını en aza indirmek için yukarı akıştan yararlanın.

Bu kategoride yer alan diğer değişiklikler, KMI temsil dosyalarında, KMI'da yapılan güncellemelerdir. simge listeleri, gki_defconfig, derleme komut dosyaları veya yapılandırma ya da diğer komut dosyaları dönüşüm hunisinin alt kısmında yer alır.

Ağaç dışı modüller

Upstream Linux, ağaç dışı modüller oluşturma desteği sunmaz. Linux geliştiricilerinin garanti vermediği için bu makul bir konumdur çekirdek içi kaynak veya ikili program uyumluluğu hakkında bilgi edinip kodu desteklemek istemiyorum her şeyi düşünmelisiniz. Ancak GKI, aşağıdakiler için ABI garantilerini verir: KMI arayüzlerinin desteklenen tüm cihaz sürümleri için kararlı olmasını sağlayarak süresi vardır. Bu nedenle, tedarikçileri desteklemek için modüllerin yer aldığı yönergelerdir.

Örneğin, EXPORT_SYMBOL_GPL() dışa aktarma işlemini kullanan modüller kaynak ağacında değildir. Deneme süresinde EXPORT_SYMBOL_GPL() yukarı akış isteğinde bulunmak ve modülün neden yüklendiğine ilişkin geçerli bir gerekçe varsa, yayın öncesi gönderilmiyorsa bunun yerine yamayı ACK'ye gönderebilirsiniz. Siz neden aynı zamanda modüle geçilemediğinin gerekçesini de . (GPL olmayan EXPORT_SYMBOL() varyantını istemeyin.)

Gizli yapılandırmalar

Bazı ağaç içi modüller, belirtilemeyen gizli yapılandırmaları otomatik olarak seçer gki_defconfig içinde. Örneğin, CONFIG_SND_SOC_TOPOLOGY seçildi. CONFIG_SND_SOC_SOF=y yapılandırıldığında otomatik olarak oluşturulur. Uymak için GKI, gizli yapılandırmaları etkinleştiren bir mekanizmaya sahiptir.

Gizli bir yapılandırmayı etkinleştirmek için init/Kconfig.gki bölümüne bir select ifadesi ekleyerek yapılandırmanın CONFIG_GKI_HACKS_TO_FIX çekirdek yapılandırmasına göre otomatik olarak seçilir. gki_defconfig ürününde etkindir. Bu mekanizmayı yalnızca gizli yapılandırmalar için kullanın; yapılandırma gizli değilse gki_defconfig içinde de belirtilmelidir bir bağımlılık olarak düşünebilirsiniz.

Yüklenebilir yöneticiler

Yüklenebilir yöneticileri destekleyen çekirdek çerçeveleri (ör. cpufreq) için varsayılan yöneticiyi (cpufreq schedutil yöneticisi gibi) geçersiz kılabilir. Örneğin, yüklenebilir yöneticileri desteklemeyen çerçeveler (ör. termal çerçeve) gerekir, ancak yine de tedarikçi firmaya özgü bir uygulama gerektirirse, konusunda uzmanlaşın ve Android çekirdek ekibine danışın.

Gerekli desteği sağlamak için sizinle ve yukarı akış sorumlularıyla birlikte çalışacağız.

Tedarikçi firma kancaları

Önceki sürümlerde tedarikçiye özel değişiklikleri doğrudan çekirdeğine kadar uzanır. Ürüne özel kodun zorunlu olması gerektiğinden bu işlem GKI 2.0'da mümkün değildir. veya daha fazla satış yapılmasını sağlamak için değil, modüller halinde ACK olarak. İş ortaklarının kullandığı katma değerli özellikleri minimum etkiyle etkinleştirmek için GKI, çekirdek çekirdek kodunda modüllerin çağrılmasına olanak tanıyan tedarikçi kancalarını kabul eder. temel çekirdek kodundan türetilir. Ayrıca, temel veri yapıları uygulamak üzere tedarikçi firmaya özel verileri depolamak için kullanılabilen tedarikçi firma verisi alanları özellikler.

Tedarikçi firma kancaları şu ölçütlere göre iki varyantta (normal ve kısıtlı) sunulur: tedarikçi modüllerinin eklenebileceği izleme noktaları (izleme etkinlikleri değil) Örneğin, yerine yeni bir sched_exit() işlevi eklemek yerine çıkış, tedarikçiler do_exit()'da tedarikçi modülünün eklenebileceği bir kanca ekleyebilir gerekir. Örnek bir uygulama aşağıdaki satıcı kancalarını içerir.

  • Normal satıcı kancaları, izleme noktası işlevi oluşturmak için DECLARE_HOOK() kullanır şu adla: trace_name name, izler. Kural olarak, normal tedarikçi kancası adları android_vh ile başlar. Bu nedenle sched_exit() kancasının adı android_vh_sched_exit olur.
  • Kısıtlanmış tedarikçi kancaları, ekli işlev, CPU çevrimdışı olsa veya çevrimdışı olsa bile çağrılmalıdır. atom olmayan bir bağlama sahip olmak. Kısıtlanmış tedarikçi kancaları ayrılamaz. Bu nedenle modüller kancaya eklenenler hiçbir zaman kaldırılamaz. Kısıtlı satıcı kancası adları android_rvh ile başlar.

Tedarikçi firma kancası eklemek için BT departmanında bir sorun oluşturun ve yama gönderin (tüm Android'e özel yamalar; bir sorun olması ve gerekçe). Tedarikçi firma kancaları için destek yalnızca ACK'de olduğundan bunları göndermeyin. yamaları da ekleyebilirsiniz.

Yapılara tedarikçi alanları ekleme

Tedarikçi firma verilerini anahtar veri yapılarıyla ilişkilendirebilirsiniz. Bunun için ANDROID_VENDOR_DATA() makrolarını kullanan android_vendor_data alanları. Örneğin, Örneğin, katma değerli özellikleri desteklemek için yapılara aşağıda gösterildiği gibi alanlar ekleyin aşağıda verilen kod örneğine bakalım.

Tedarikçi firmaların ihtiyaç duyduğu alanlar ile alanlar arasında olası çakışmaları önlemek için OEM'lerin, hiçbir zaman ANDROID_VENDOR_DATA() makro. OEM'ler bunun yerine ANDROID_OEM_DATA() kullanmalıdır android_oem_data alanı tanımlamalıdır.

#include <linux/android_vendor.h>
...
struct important_kernel_data {
  [all the standard fields];
  /* Create vendor data for use by hook implementations. The
   * size of vendor data is based on vendor input. Vendor data
   * can be defined as single u64 fields like the following that
   * declares a single u64 field named "android_vendor_data1" :
   */
  ANDROID_VENDOR_DATA(1);

  /*
   * ...or an array can be declared. The following is equivalent to
   * u64 android_vendor_data2[20]:
   */
  ANDROID_VENDOR_DATA_ARRAY(2, 20);

  /*
   * SoC vendors must not use fields declared for OEMs and
   * OEMs must not use fields declared for SoC vendors.
   */
  ANDROID_OEM_DATA(1);

  /* no further fields */
}

Tedarikçi kancalarını tanımlayın

Tedarikçi firma kancalarını çekirdek koduna izleme noktaları olarak eklemek için bunları DECLARE_HOOK() veya DECLARE_RESTRICTED_HOOK() ve ardından bunları koda şu şekilde ekliyor: izin verir. Örneğin, trace_android_vh_sched_exit() öğesini mevcut do_exit() çekirdek işlevi:

#include <trace/hooks/exit.h>
void do_exit(long code)
{
    struct task_struct *tsk = current;
    ...
    trace_android_vh_sched_exit(tsk);
    ...
}

trace_android_vh_sched_exit() işlevi, başlangıçta yalnızca kontrol ekli. Ancak bir tedarikçi modülü, register_trace_android_vh_sched_exit() ise kayıtlı işlev çağrılır. İlgili içeriği oluşturmak için kullanılan işleyici, tutulan kilitler, RCS durumu ve diğer faktörlerle ilgilidir. Kanca, include/trace/hooks dizini.

Örneğin, aşağıdaki kod, include/trace/hooks/exit.h dosyasındaki trace_android_vh_sched_exit().

/* SPDX-License-Identifier: GPL-2.0 */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM sched
#define TRACE_INCLUDE_PATH trace/hooks

#if !defined(_TRACE_HOOK_SCHED_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_HOOK_SCHED_H
#include <trace/hooks/vendor_hooks.h>
/*
 * Following tracepoints are not exported in tracefs and provide a
 * mechanism for vendor modules to hook and extend functionality
 */

struct task_struct;

DECLARE_HOOK(android_vh_sched_exit,
             TP_PROTO(struct task_struct *p),
             TP_ARGS(p));

#endif /* _TRACE_HOOK_SCHED_H */

/* This part must be outside protection */
#include <trace/define_trace.h>

Tedarikçi firma kancası için gerekli arayüzleri örneklendirmek amacıyla başlık dosyasını ekleyin. drivers/android/vendor_hooks.c öğesine kanca beyanını ekleyerek anlamına gelir. Örneğin, aşağıdaki kod android_vh_sched_exit() kancası.

#ifndef __GENKSYMS__
/* struct task_struct */
#include <linux/sched.h>
#endif

#define CREATE_TRACE_POINTS
#include <trace/hooks/vendor_hooks.h>
#include <trace/hooks/exit.h>
/*
 * Export tracepoints that act as a bare tracehook (i.e. have no trace
 * event associated with them) to allow external modules to probe
 * them.
 */
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sched_exit);

NOT: Kanca bildirimi içinde kullanılan veri yapılarının belirlemek için tam olarak tanımlanmıştır. Aksi takdirde opak işaretçileri kaldırın veya boyutlu bağlamlarda struct'ı kullanın. Dahil etme Bu örnek, veri yapılarının tam tanımını verir ve drivers/android/vendor_hooks.c dokümanının #ifndef __GENKSYMS__ bölümü. Üst bilgi include/trace/hooks içindeki dosyalar, KMI'yi bozan CRC değişikliklerini önlemek için tür tanımlarını kullanın. Bunun yerine yönlendir açıklayacağım.

Tedarikçi firma kancalarına bağlama

Tedarikçi firma kancalarını kullanmak istiyorsanız tedarikçi modülünün kanca için bir işleyici kaydetmesi gerekir (genellikle modülün başlatılması sırasında yapılır). Örneğin, aşağıdaki kod trace_android_vh_sched_exit() için foo.ko modül işleyicisini gösterir.

#include <trace/hooks/sched.h>
...
static void foo_sched_exit_handler(void *data, struct task_struct *p)
{
    foo_do_exit_accounting(p);
}
...
static int foo_probe(..)
{
    ...
    rc = register_trace_android_vh_sched_exit(foo_sched_exit_handler, NULL);
    ...
}

Başlık dosyalarındaki satıcı kancalarını kullanma

Başlık dosyalarındaki satıcı kancalarını kullanmak için tedarikçi kancasını güncellemeniz gerekebilir. gösteren yapı hatalarını önlemek için TRACE_INCLUDE_PATH izleme noktası başlık dosyası bulunamadı. Örneğin,

In file included from .../common/init/main.c:111:
In file included from .../common/include/trace/events/initcall.h:74:
.../common/include/trace/define_trace.h:95:10: fatal error: 'trace/hooks/initcall.h' file not found
   95 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.../common/include/trace/define_trace.h:90:32: note: expanded from macro 'TRACE_INCLUDE'
   90 | # define TRACE_INCLUDE(system) __TRACE_INCLUDE(system)
      |                                ^~~~~~~~~~~~~~~~~~~~~~~
.../common/include/trace/define_trace.h:87:34: note: expanded from macro '__TRACE_INCLUDE'
   87 | # define __TRACE_INCLUDE(system) __stringify(TRACE_INCLUDE_PATH/system.h)
      |                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.../common/include/linux/stringify.h:10:27: note: expanded from macro '__stringify'
   10 | #define __stringify(x...)       __stringify_1(x)
      |                                 ^~~~~~~~~~~~~~~~
.../common/include/linux/stringify.h:9:29: note: expanded from macro '__stringify_1'
    9 | #define __stringify_1(x...)     #x
      |                                 ^~
<scratch space>:14:1: note: expanded from here
   14 | "trace/hooks/initcall.h"
      | ^~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.

Bu tür bir yapı hatasını düzeltmek için tedarikçi kancasına eşdeğer düzeltmeyi uygulayın. başlık dosyasına göz atabilirsiniz. Daha fazla bilgi için https://r.android.com/3066703 adresine gidin.

diff --git a/include/trace/hooks/mm.h b/include/trace/hooks/mm.h
index bc6de7e53d66..039926f7701d 100644
--- a/include/trace/hooks/mm.h
+++ b/include/trace/hooks/mm.h
@@ -2,7 +2,10 @@
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM mm

+#ifdef CREATE_TRACE_POINTS
 #define TRACE_INCLUDE_PATH trace/hooks
+#define UNDEF_TRACE_INCLUDE_PATH
+#endif

UNDEF_TRACE_INCLUDE_PATH tanımlandığında include/trace/define_trace.h şunları sağlar: İzleme noktalarını oluşturduktan sonra TRACE_INCLUDE_PATH tanımlamasını kaldırın.

Temel çekirdek özellikleri

Önceki tekniklerin hiçbiri modüldeki bir özelliği uygulamanıza olanak vermiyorsa, özelliği, temel uygulamanıza Android'e özgü bir değişiklik olarak eklemeniz gerekir. kernel'e gidin. Görüşmeyi başlatmak için Sorun İzleyici'de (BT) bir sorun oluşturun.

Kullanıcı uygulaması programlama arayüzü (UAPI)

  • UAPI başlığı dosyaları. Şu değişiklikler var: UAPI başlığı dosyaları değişiklikler Android'e özgü arayüzlerde olmadığı sürece yukarı akış şeklinde gerçekleşmelidir. Arayüzleri tanımlamak için tedarikçi firmaya özel başlık dosyaları kullanın arasında bir kontrol listesi hazırlayabilirsiniz.
  • sysfs düğümleri GKI çekirdeğine yeni sysfs düğümleri eklemeyin (bu tür eklemeler yalnızca tedarikçi modüllerinde geçerlidir. SoC- ve SoC tarafından kullanılan sysfs düğümleri cihazdan bağımsız kitaplıklar ve Android çerçevesini oluşturan Java kodu yalnızca uyumlu şekillerde değiştirilebilir ve Android'e özel sysfs düğümleri değildir. Şunları oluşturabilirsiniz: Tedarikçi firma kullanıcı alanı tarafından kullanılacak satıcıya özgü sysfs düğümleri. Varsayılan olarak SELinux kullanılırken, sysfs düğümlerine kullanıcı alanı tarafından erişim reddedildi. Size yetkili tarafından erişime izin vermek üzere uygun SELinux etiketlerini tedarikçi yazılımıdır.
  • DebugFS düğümleri. Tedarikçi firma modülleri şunun için debugfs ürününde düğüm tanımlayabilir: hatası ayıklamayı destekler (debugfs öğesinin normal çalışması sırasında cihazda) olduğunu varsayalım.