GKI için Çekirdek Kodu Geliştirin

Koleksiyonlar ile düzeninizi koruyun İçeriği tercihlerinize göre kaydedin ve kategorilere ayırın.

Genel Çekirdek Görüntüsü (GKI), yukarı akış Linux çekirdeği ile yakından hizalanarak çekirdek parçalanmasını azaltır. Bununla birlikte, bazı yamaların yukarı akışa kabul edilememesinin geçerli nedenleri vardır ve uyulması gereken ürün programları vardır, bu nedenle bazı yamalar, GKI'nin oluşturulduğu Android Ortak Çekirdek (ACK) kaynaklarında tutulur.

Geliştiriciler, ilk seçenek olarak Linux Çekirdeği Posta Listesini (LKML) kullanarak kod değişikliklerini yukarı akışa göndermeli ve kod değişikliklerini yalnızca yukarı akışın uygun olmamasının güçlü bir nedeni olduğunda ACK android-mainline şubesine göndermelidir. Geçerli neden örnekleri ve bunların nasıl ele alınacağı aşağıda listelenmiştir.

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

    • Yamanın LKML'ye gönderildiğine ve yama için alınan yorumlara ya da yamanın yukarı akışa gönderileceği tahmini süreye dair kanıt sağlayın.
    • Yamayı ACK'ye yerleştirmek, yukarı yönde onaylatmak ve ardından son yukarı akış sürümü ACK ile birleştirildiğinde ACK'den çıkarmak için bir eylem planına karar verin.
  • Düzeltme eki, bir satıcı modülü için EXPORT_SYMBOLS_GPL() 'yi tanımlar, ancak bu sembolü tüketen hiçbir ağaç içi modül olmadığı için akış yukarı gönderilememiştir. Bu yamayı halletmek için, modülünüzün neden yukarı akışa gönderilemediğine ilişkin ayrıntıları ve bu istekte bulunmadan önce düşündüğünüz alternatifleri sağlayın.

  • Yama yukarı akış için yeterince genel değil ve bir ürün piyasaya sürülmeden önce onu yeniden düzenlemek için zaman yok. Bu yamayı işlemek için, yeniden düzenlenmiş bir yamanın yukarı akışa gönderileceği tahmini bir süre sağlayın (yama, gözden geçirilmek üzere yeniden düzenlenmiş bir yamayı yukarı akışa gönderme planı olmadan ACK'de kabul edilmeyecektir).

  • Düzeltme eki yukarı akış tarafından kabul edilemez çünkü... <nedeni buraya girin> . Bu yamayı halletmek için, Android çekirdek ekibine ulaşın ve yamayı incelemeye gönderilip yukarı yönde kabul edilebilecek şekilde yeniden düzenleme seçenekleri üzerinde bizimle birlikte çalışın.

Daha birçok potansiyel gerekçe var. Hatanızı veya yamanızı gönderdiğinizde, geçerli bir gerekçe ekleyin ve biraz yineleme ve tartışma bekleyin. ACK'nın özellikle GKI'nın ilk aşamalarında bazı yamalar taşıyacağının farkındayız; bu sırada herkes yukarı akışta çalışmayı öğreniyor ancak bunu yapmak için ürün programlarını gevşetemiyor. Yukarı akış gereksinimlerinin zaman içinde daha sıkı hale gelmesini bekleyin.

Yama gereksinimleri

Yamalar, ister yukarı yönde ister ACK'ya gönderilsinler, Linux kaynak ağacında açıklanan Linux çekirdeği kodlama standartlarına uygun olmalıdır. scripts/checkpatch.pl komut dosyası, Gerrit'in gönderme öncesi testinin bir parçası olarak çalıştırılır, bu nedenle başarılı olduğundan emin olmak için önceden çalıştırın. Checkpatch betiğini, gönderme öncesi testle aynı yapılandırmayla çalıştırmak için, repo kontrolünden build/static_analysis/checkpatch_presubmit.sh kullanın.

ACK yamaları

ACK'ye gönderilen yamalar, Linux çekirdek kodlama standartlarına ve katkı yönergelerine uygun olmalıdır. Kayıt mesajına bir Change-Id etiketi eklemelisiniz; yamayı birden fazla şubeye (örneğin, android-mainline ve android12-5.4 ) gönderirseniz, yamanın tüm örnekleri için aynı Change-Id Id'yi kullanmanız gerekir.

Yukarı akış incelemesi için yamaları önce LKML'ye gönderin. Yama şuysa:

  • Akış yukarı kabul edildi, otomatik olarak android-mainline ile birleştirildi.
  • Akış yukarı kabul edilmedi, yukarı akış gönderimine bir referansla veya neden LKML'ye gönderilmediğine dair bir açıklama ile android-mainline gönderin.

Bir yama yukarı akışta veya android-mainline kabul edildikten sonra, uygun LTS tabanlı ACK'ye (Android'e özgü kodu düzelten yamalar için android12-5.4 ve android11-5.4 gibi) geri aktarılabilir. android-mainline göndermek, yeni yukarı akış sürüm adaylarıyla test yapılmasını sağlar ve yamanın bir sonraki LTS tabanlı ACK'de olduğunu garanti eder. İstisnalar, bir yukarı akış yamasının android12-5.4 geri aktarıldığı durumları içerir (çünkü yama muhtemelen zaten android-mainline içindedir).

Yukarı akış yamaları

Katkı yönergelerinde belirtildiği gibi, ACK çekirdeklerine yönelik yukarı akış yamaları aşağıdaki gruplara ayrılır (kabul edilme olasılığı sırasına göre listelenmiştir).

  • UPSTREAM: - Makul bir kullanım durumu varsa, 'android-mainline'dan dikkatle seçilen yamalar muhtemelen ACK'ye kabul edilecektir.
  • BACKPORT: - Makul bir kullanım durumu varsa, temiz bir şekilde özenle seçmeyen ve değişiklik gerektiren yukarı akışlı yamalar da muhtemelen kabul edilecektir.
  • FROMGIT: - Linux ana hattına gönderilmek üzere hazırlanırken bir bakıcı şubesinden titizlikle seçilen yamalar, yaklaşan bir son tarih varsa kabul edilebilir. Bunlar hem içerik hem de program açısından gerekçelendirilmelidir.
  • FROMLIST: - LKML'ye gönderilmiş ancak henüz bir bakımcı şubesine kabul edilmemiş yamalar, yamanın Linux'un yukarı akışında yer alsın ya da almasın kabul edilmesini gerektirecek kadar ikna edici olmadıkça, kabul edilmesi olası değildir (biz varsayıyoruz) olmayacak). Android çekirdek ekibiyle tartışmayı kolaylaştırmak için FROMLIST yamalarıyla ilişkili bir sorun olmalıdır.

Android'e özel yamalar

Gerekli değişiklikleri yukarı akışa indiremezseniz, ağaç dışı yamaları doğrudan ACK'ye göndermeyi deneyebilirsiniz. Ağaç dışı yamaları göndermek, BT'de yamaya atıfta bulunan bir sorun oluşturmanızı ve yamanın neden yukarı akışa gönderilemediğine ilişkin gerekçeyi oluşturmanızı gerektirir (örnekler için önceki listeye bakın). Ancak, kodun yukarı akışa gönderilemediği birkaç durum vardır. Bu durumlar aşağıda ele alınmıştır ve Android'e özel yamalar için katkı yönergelerine uyulmalı ve konuda ANDROID: öneki ile etiketlenmelidir.

gki_defconfig'deki değişiklikler

CONFIG mimariye özgü olmadığı sürece, gki_defconfig'deki tüm CONFIG değişiklikleri hem gki_defconfig hem de x86 sürümlerine uygulanmalıdır. Bir CONFIG ayarında değişiklik talep etmek için BT'de değişikliği tartışmak üzere bir sorun oluşturun. Dondurulduktan sonra Çekirdek Modülü Arayüzünü (KMI) etkileyen herhangi bir CONFIG değişikliği reddedilir. Ortakların tek bir yapılandırma için çakışan ayarlar talep ettiği durumlarda, çakışmaları ilgili hatalar üzerinde görüşerek çözeriz.

Yukarı akışta olmayan kod

Halihazırda Android'e özgü olan kod değişiklikleri yukarı akışa gönderilemez. Örneğin, ciltleyici sürücüsü yukarı akışta tutulsa bile, ciltleyici sürücüsünün öncelikli devralma özelliklerinde yapılan değişiklikler yukarı akışa gönderilemez çünkü bunlar Android'e özgüdür. Hatanızda açık olun ve kodun neden yukarı yönde gönderilemediğini düzeltin. Mümkünse, ACK'da tutulan ağaç dışı kod miktarını en aza indirmek için yamaları yukarı akışa gönderilebilecek parçalara ve yukarı akışa gönderilemeyen Android'e özgü parçalara ayırın.

Bu kategorideki diğer değişiklikler, KMI temsil dosyalarına, KMI sembol listelerine, gki_defconfig , derleme betiklerine veya yapılandırmasına veya yukarı akışta olmayan diğer betiklere yapılan güncellemelerdir.

Ağaç dışı modüller

Upstream Linux, ağaç dışı modüller oluşturma desteğini aktif olarak caydırır. Bu, Linux geliştiricilerinin çekirdek içi kaynak veya ikili uyumluluk konusunda garanti vermediği ve ağaçta olmayan kodu desteklemek istemediği göz önüne alındığında makul bir konumdur. Ancak GKI , satıcı modülleri için ABI garantileri vererek, KMI arabirimlerinin bir çekirdeğin desteklenen ömrü boyunca kararlı olmasını sağlar. Bu nedenle, satıcı modüllerini desteklemek için ACK için kabul edilebilir ancak yukarı akış için kabul edilemeyen bir değişiklik sınıfı vardır.

Örneğin, dışa aktarmayı kullanan modüllerin kaynak ağaçta olmadığı durumlarda EXPORT_SYMBOL_GPL() makroları ekleyen bir yama düşünün. EXPORT_SYMBOL_GPL() yukarı akış talebinde bulunmanız ve yeni dışa aktarılan sembolü kullanan bir modül sağlamanız gerekse de, modülün neden yukarı akışa gönderilmediğine dair geçerli bir gerekçe varsa, bunun yerine yamayı ACK'ye gönderebilirsiniz. Sorunda modülün neden yukarı akışa alınamadığının gerekçesini eklemeniz gerekir. (GPL olmayan varyantı talep etmeyin, EXPORT_SYMBOL() .)

Gizli yapılandırmalar

Bazı ağaç içi modüller, gki_defconfig içinde belirtilemeyen gizli yapılandırmaları otomatik olarak seçer. Örneğin, CONFIG_SND_SOC_TOPOLOGY CONFIG_SND_SOC_SOF=y yapılandırıldığında CONFIG_SND_SOC_TOPOLOGY otomatik olarak seçilir. Ağaç dışı modül oluşturmaya uyum sağlamak için GKI, gizli yapılandırmaları etkinleştirmek için bir mekanizma içerir.

Gizli bir yapılandırmayı etkinleştirmek için init/Kconfig.gki bir select deyimi ekleyin, böylece gki_defconfig etkinleştirilen CONFIG_GKI_HACKS_TO_FIX çekirdek yapılandırmasına göre otomatik olarak seçilir. Bu mekanizmayı yalnızca gizli yapılandırmalar için kullanın; yapılandırma gizli değilse, gki_defconfig içinde açıkça veya bir bağımlılık olarak belirtilmelidir.

Yüklenebilir valiler

Yüklenebilir düzenleyicileri destekleyen çekirdek çerçeveleri ( cpufreq gibi) için, varsayılan düzenleyiciyi ( cpufreq 's schedutil gibi) geçersiz kılabilirsiniz. Yüklenebilir düzenleyicileri veya sürücüleri desteklemeyen ancak yine de bir satıcıya özel uygulama, BT'de bir sorun oluşturun ve Android çekirdek ekibine danışın.

Gerekli desteği eklemek için sizinle ve yukarı akış bakımcılarıyla birlikte çalışacağız.

Satıcı kancaları

Geçmiş sürümlerde, satıcıya özgü değişiklikleri doğrudan çekirdek çekirdeğe ekleyebilirsiniz. Bu, GKI 2.0 ile mümkün değildir çünkü ürüne özel kodun modüllerde uygulanması gerekir ve yukarı akıştaki çekirdek çekirdeklerde veya ACK'de kabul edilmez. İş ortaklarının temel çekirdek kodu üzerinde minimum etkiyle güvendiği katma değerli özellikleri etkinleştirmek için GKI, modüllerin çekirdek çekirdek kodundan çağrılmasına izin veren tedarikçi firma kancalarını kabul eder. Ek olarak, anahtar veri yapıları, bu özellikleri uygulamak için satıcıya özgü verileri depolamak için kullanılabilen satıcı veri alanlarıyla doldurulabilir.

Satıcı kancaları, satıcı modüllerinin ekleyebileceği izleme noktalarına (izleme olaylarına değil) dayalı iki varyantta (normal ve kısıtlı) gelir. Örneğin, görev çıkışında bir hesaplama yapmak için yeni bir sched_exit() işlevi eklemek yerine satıcılar do_exit() 'te bir satıcı modülünün işleme için ekleyebileceği bir kanca ekleyebilir. Örnek bir uygulama, aşağıdaki satıcı kancalarını içerir.

  • Normal satıcı kancaları, trace_ name bir izleme noktası işlevi oluşturmak için DECLARE_HOOK() 'u kullanır; burada name , izleme için benzersiz tanımlayıcıdır. Geleneksel olarak, normal satıcı kancası adları android_vh ile başlar, bu nedenle sched_exit() kancasının adı android_vh_sched_exit olur.
  • CPU çevrimdışı olsa veya atomik olmayan bir bağlam gerektirse bile ekli işlevin çağrılması gereken zamanlayıcı kancaları gibi durumlar için kısıtlı satıcı kancaları gerekir. Kısıtlanmış satıcı kancaları ayrılamaz, dolayısıyla kısıtlı bir kancaya bağlanan modüller hiçbir zaman kaldırılamaz. Yalnızca bir eke izin verilir, bu nedenle diğer ekleme girişimleri -EBUSY ile başarısız olur. Kısıtlanmış satıcı kanca adları android_rvh ile başlar.

Satıcı kancası eklemek için BT'ye bir sorun bildirin ve yamalar gönderin (Android'e özgü tüm yamalarda olduğu gibi, bir sorun olmalı ve gerekçe göstermelisiniz). Satıcı kancaları için destek yalnızca ACK içindedir, bu nedenle bu yamaları yukarı akış Linux'a göndermeyin.

Yapılara satıcı alanları ekleyin

ANDROID_VENDOR_DATA() makrolarını kullanarak android_vendor_data alanları ekleyerek satıcı verilerini önemli veri yapılarıyla ilişkilendirebilirsiniz. Örneğin, katma değerli özellikleri desteklemek için aşağıdaki kod örneğinde gösterildiği gibi alanları yapılara ekleyin.

Satıcıların ihtiyaç duyduğu alanlar ile OEM'lerin ihtiyaç duyduğu alanlar arasındaki potansiyel çakışmaları önlemek için OEM'ler, ANDROID_VENDOR_DATA() makroları kullanılarak bildirilen alanları asla kullanmamalıdır. Bunun yerine, OEM'lerin android_oem_data alanlarını bildirmek için ANDROID_OEM_DATA() kullanması gerekir.

#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 */
}

Satıcı kancalarını tanımlayın

Satıcı kancalarını, DECLARE_HOOK() veya DECLARE_RESTRICTED_HOOK() kullanarak bildirerek ve ardından bunları bir izleme noktası olarak koda ekleyerek izleme noktaları olarak çekirdek koduna ekleyin. Örneğin, mevcut do_exit() çekirdek işlevine trace_android_vh_sched_exit( trace_android_vh_sched_exit() eklemek için:

#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 bir şeyin eklenip eklenmediğini kontrol eder. Ancak bir satıcı modülü, register_trace_android_vh_sched_exit() kullanarak bir işleyiciyi kaydederse kayıtlı işlev çağrılır. İşleyici, tutulan kilitler, RCS durumu ve diğer faktörlerle ilgili bağlamdan haberdar olmalıdır. Kanca, include/trace/hooks dizinindeki bir başlık dosyasında tanımlanmalıdır.

Örneğin, aşağıdaki kod, include/trace/hooks/sched.h dosyasında trace_android_vh_sched_exit() için olası bir bildirim verir.

/* 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>

Satıcı kancası için gereken arabirimleri başlatmak için, kanca bildirimi içeren başlık dosyasını drivers/android/vendor_hooks.c ve sembolleri dışa aktarın. Örneğin, aşağıdaki kod android_vh_sched_exit() kancasının bildirimini tamamlar.

#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 : ABI kararlılığını garanti etmek için kanca bildiriminde kullanılan veri yapılarının tam olarak tanımlanması gerekir. Aksi takdirde, opak işaretçilerin başvurusunu kaldırmak veya yapıyı boyutlandırılmış bağlamlarda kullanmak güvenli değildir. Bu tür veri yapılarının tam tanımını sağlayan içerme, drivers/android/vendor_hooks.c #ifndef __GENKSYMS__ bölümüne girmelidir. KMI'yi bozan CRC değişikliklerinden kaçınmak için include/trace/hooks içindeki başlık dosyaları, tip tanımlarıyla birlikte çekirdek başlık dosyasını içermemelidir. Bunun yerine türleri bildirin.

Satıcı kancalarına iliştirin

Satıcı kancalarını kullanmak için, satıcı modülünün kanca için bir işleyici kaydetmesi gerekir (genellikle modül başlatma 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);
    ...
}

Çekirdek çekirdek özellikleri

Önceki tekniklerin hiçbiri bir modülden bir özelliği uygulamanıza olanak vermiyorsa, o zaman özelliği çekirdek çekirdeğe Android'e özgü değişiklik olarak eklemelisiniz. Konuşmayı başlatmak için sorun izleyicide (IT) bir sorun oluşturun.

Kullanıcı uygulama programlama arabirimi (UAPI)

  • UAPI başlık dosyaları. UAPI başlık dosyalarındaki değişiklikler, Android'e özgü arayüzlerde yapılmadığı sürece yukarı akışta yapılmalıdır. Satıcı modülleri ve satıcı kullanıcı alanı kodu arasındaki arayüzleri tanımlamak için satıcıya özel başlık dosyalarını kullanın.
  • sysfs düğümleri. GKI çekirdeğine yeni sysfs düğümleri eklemeyin (bu tür eklemeler yalnızca tedarikçi firma modüllerinde geçerlidir). SoC ve cihazdan bağımsız kitaplıklar tarafından kullanılan sysfs düğümleri ve Android çerçevesini oluşturan Java kodu, yalnızca uyumlu yollarla değiştirilebilir ve Android'e özgü sysfs düğümleri değillerse akış yukarı değiştirilmelidir. Satıcı kullanıcı alanı tarafından kullanılacak satıcıya özel sysfs düğümleri oluşturabilirsiniz. Varsayılan olarak, SELinux kullanılarak kullanıcı alanı tarafından sysfs düğümlerine erişim reddedilir. Yetkili satıcı yazılımı tarafından erişime izin vermek için uygun SELinux etiketlerini eklemek satıcıya bağlıdır.
  • DebugFS düğümleri. Satıcı modülleri, hata ayıklamalarda yalnızca hata debugfs için düğümler tanımlayabilir (çünkü hata debugfs , cihazın normal çalışması sırasında bağlanmaz).