GKI için çekirdek kodu geliştirme

Genel Çekirdek Görüntüsü (GKI), yukarı akış Linux çekirdeğiyle yakından uyum sağlayarak çekirdek parçalanmasını azaltır. Ancak bazı yamaların yukarı akışta kabul edilememesinin geçerli nedenleri vardır ve karşılanması gereken ürün planları olduğundan bazı yamalar, GKI'nin oluşturulduğu Android Ortak Çekirdeği (ACK) kaynaklarında tutulur.

Geliştiriciler, kod değişikliklerini öncelikle Linux Kernel Mailing List (LKML) aracılığıyla göndermeli ve kod değişikliklerini ACK android-mainline dalına yalnızca yukarı akışın uygun olmadığına dair güçlü bir neden varsa göndermelidir. Geçerli nedenlere ve bunların nasıl ele alınacağına dair örnekler aşağıda listelenmiştir.

  • Yama, LKML'ye gönderildi ancak ü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 yamayla ilgili yorumlar alındığına veya yamanın yukarı akışa gönderileceği tahmini süreye dair kanıt sunun.
    • Yamanın ACK'ye eklenmesi, yukarı akışta onaylanması ve nihai yukarı akış sürümü ACK'ye birleştirildiğinde ACK'den çıkarılması için bir işlem planı belirleyin.
  • Yama, bir satıcı modülü için EXPORT_SYMBOLS_GPL() tanımlıyor ancak bu sembolü kullanan ağaç içi modül olmadığından yukarı akışa gönderilemedi. Bu yamayı işlemek için modülünüzün neden yukarı akışa gönderilemediği ve bu isteği yapmadan önce değerlendirdiğiniz alternatifler hakkında ayrıntılı bilgi verin.

  • Yama, yukarı akış için yeterince genel değil ve ürün yayınlanmadan önce yeniden düzenlemek için yeterli zaman yok. Bu yamayı işlemek için yeniden düzenlenmiş bir yamanın yukarı akışa gönderileceği tahmini süreyi belirtin (yeniden düzenlenmiş bir yamanın inceleme için yukarı akışa gönderileceği bir plan olmadan yama ACK'de kabul edilmez).

  • Yama, yukarı akış tarafından kabul edilemiyor çünkü... <insert reason here>. Bu yamayı işlemek için Android çekirdek ekibiyle iletişime geçin ve yamayı incelemeye gönderilebilecek ve yukarı akışta kabul edilebilecek şekilde yeniden düzenleme seçenekleri konusunda bizimle birlikte çalışın.

Daha birçok olası gerekçe vardır. Hatanızı veya yamanızı gönderirken geçerli bir gerekçe ekleyin. Bazı yinelemeler ve tartışmalar olabilir. ACK'nin, özellikle herkesin yukarı akışta nasıl çalışılacağını öğrendiği ancak bunu yapmak için ürün planlarını rahatlatamadığı GKI'nın ilk aşamalarında bazı yamalar taşıdığını biliyoruz. Yukarı akış gereksinimlerinin zaman içinde daha katı hale gelmesini bekliyoruz.

Yama gereksinimleri

Yama gönderimleri, ister yukarı akışa ister ACK'ye gönderilsin Linux kaynak ağacında açıklanan Linux çekirdeği kodlama standartlarına uygun olmalıdır. scripts/checkpatch.pl Komut dosyası, Gerrit ön gönderme 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 komut dosyasını, gönderme öncesi testle aynı yapılandırmayla çalıştırmak için //build/kernel/static_analysis:checkpatch_presubmit kullanın. Ayrıntılı bilgi için build/kernel/kleaf/docs/checkpatch.md adresini ziyaret edin.

Onay yamaları

ACK'ye gönderilen yamalar, Linux çekirdeği kodlama standartlarına ve katkı yönergelerine uygun olmalıdır. Commit iletisine bir Change-Id etiketi eklemeniz gerekir. Yamayı birden fazla dala (örneğin, android-mainline ve android12-5.4) gönderirseniz yamanın tüm örnekleri için aynı Change-Id etiketini kullanmanız gerekir.

Yama dosyalarını önce LKML'ye göndererek üst akış incelemesi yapın. Yama:

  • Yukarı akışta kabul edilen değişiklikler, android-mainline ile otomatik olarak birleştirilir.
  • Yukarı akışta kabul edilmedi. Yukarı akış gönderimine referans vererek veya LKML'ye neden gönderilmediğini açıklayarak android-mainline adresine gönderin.

Bir yama, yukarı akışta veya android-mainline içinde kabul edildikten sonra uygun LTS tabanlı ACK'ye (ör. Android'e özgü kodu düzelten yamalar için android12-5.4 ve android11-5.4) geri taşınabilir. android-mainline'ya gönderme işlemi, yeni yukarı akış sürüm adaylarıyla test yapılmasına olanak tanır ve yamanın bir sonraki LTS tabanlı ACK'de olmasını sağlar. Bir yukarı akış yaması android12-5.4'ya geri taşındığı durumlar (yama büyük olasılıkla zaten android-mainline'dadır) istisnadır.

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ığına göre sıralanmıştır).

  • UPSTREAM: - "android-mainline"dan seçilen yamalar, makul bir kullanım alanı varsa ACK'ye kabul edilebilir.
  • BACKPORT: - Temiz bir şekilde seçilmeyen ve değiştirilmesi gereken yukarı akış yamaları da makul bir kullanım alanı varsa kabul edilebilir.
  • FROMGIT: - Linux ana hattına gönderilmeye hazırlanırken bir bakımcı dalından 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önderilen ancak henüz bir bakımcı dalına kabul edilmeyen yamaların, gerekçesi yeterince ikna edici olmadığı sürece kabul edilmesi olası değildir. Bu durumda, yamanın yukarı akış Linux'a dahil edilip edilmemesinden bağımsız olarak kabul edileceği varsayılır (dahil edilmeyeceği varsayılır). Android çekirdek ekibiyle görüşmeyi 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ışta yapamıyorsanız ACK'ye doğrudan ağaç dışı yamalar göndermeyi deneyebilirsiniz. Ağaç dışı yamaların gönderilmesi için BT'de yama ve yamaların neden yukarı akışa gönderilemediğini açıklayan bir sorun oluşturmanız gerekir (örnekler için önceki listeye bakın). Ancak kodun yukarı akışa gönderilemediği birkaç durum vardır. Bu durumlar aşağıdaki şekilde ele alınır ve Android'e özel yamalar için katkı yönergelerine uyulması, ayrıca konunun ANDROID: önekiyle etiketlenmesi gerekir.

gki_defconfig dosyasında yapılan değişiklikler

CONFIG mimariye özgü olmadığı sürece gki_defconfig'teki tüm CONFIG değişiklikleri hem arm64 hem de x86 sürümlerine uygulanmalıdır. CONFIG ayarında değişiklik isteğinde bulunmak için BT'de bir sorun oluşturarak değişikliği görüşün. Dondurulduktan sonra çekirdek modülü arayüzünü (KMI) etkileyen CONFIG değişiklikler reddedilir. İş ortaklarının tek bir yapılandırma için çakışan ayarlar talep ettiği durumlarda, ilgili hatalar hakkındaki tartışmalar aracılığıyla çakışmaları gideririz.

Yukarı akışta bulunmayan kod

Zaten Android'e özgü olan kodda yapılan değişiklikler yukarı akışa gönderilemez. Örneğin, bağlayıcı sürücüsü yukarı akışta korunsa da bağlayıcı sürücüsünün öncelik devralma özelliklerinde yapılan değişiklikler Android'e özgü oldukları için yukarı akışa gönderilemez. Hatanızı ve kodun neden yukarı akışa gönderilemediğini açıkça belirtin. Mümkünse yamaları, ACK'de tutulan ağaç dışı kod miktarını en aza indirmek için yukarı akışa gönderilebilen parçalar ve yukarı akışa gönderilemeyen Android'e özgü parçalar halinde ayırın.

Bu kategorideki diğer değişiklikler; KMI gösterim dosyaları, KMI sembol listeleri, gki_defconfig, derleme komut dosyaları veya yapılandırması ya da yukarı akışta bulunmayan diğer komut dosyalarıyla ilgili güncellemelerdir.

Ağaç dışı modüller

Upstream Linux, ağaç dışı modüllerin oluşturulması için desteği aktif olarak engeller. Linux bakımcılarının çekirdek içi kaynak veya ikili uyumluluk konusunda garanti vermemesi ve ağaçta olmayan kodu desteklemek istememesi nedeniyle bu makul bir yaklaşımdır. Ancak GKI, tedarikçi modülleri için ABI garantileri verir ve KMI arayüzlerinin, desteklenen çekirdek ömrü boyunca kararlı olmasını sağlar. Bu nedenle, ACK için kabul edilebilir ancak yukarı akış için kabul edilemez olan, tedarikçi modüllerini desteklemeye yönelik bir değişiklik sınıfı vardır.

Örneğin, dışa aktarmayı kullanan modüllerin kaynak ağacında olmadığı durumlarda EXPORT_SYMBOL_GPL() makroları ekleyen bir yamayı ele alalım. EXPORT_SYMBOL_GPL() yukarı akışını istemeye çalışmanız ve yeni dışa aktarılan sembolü kullanan bir modül sağlamanız gerekirken modülün neden yukarı akışa gönderilmediğine dair geçerli bir gerekçe varsa yamayı ACK'ye gönderebilirsiniz. Modülün neden yukarı akışa gönderilemediğine dair gerekçeyi soruna eklemeniz gerekir. (GPL olmayan varyantı EXPORT_SYMBOL() istemeyin.)

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_SOF=y yapılandırıldığında CONFIG_SND_SOC_TOPOLOGY otomatik olarak seçilir. GKI, ağaç dışı modül derlemeyi desteklemek için gizli yapılandırmaları etkinleştirmeye yönelik bir mekanizma içerir.

Gizli bir yapılandırmayı etkinleştirmek için select ifadesini init/Kconfig.gki içine ekleyin. Böylece, gki_defconfig içinde 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 bağımlılık olarak belirtilmelidir.

Yüklenebilir valiler

Yüklenebilir yöneticileri destekleyen çekirdek çerçevelerinde (ör. cpufreq) varsayılan yöneticinin (ör. cpufreq'nın schedutil yöneticisi) yerine başka bir yönetici kullanabilirsiniz. Yüklenebilir yöneticileri veya sürücüleri desteklemeyen ancak yine de tedarikçiye özel bir uygulama gerektiren çerçeveler (ör. termal çerçeve) için BT'de bir sorun oluşturun ve Android çekirdek ekibine danışın.

Gerekli desteği eklemek için sizinle ve üst düzey bakımcılarla birlikte çalışacağız.

Tedarikçi kancaları

Geçmiş sürümlerde, tedarikçiye özel değişiklikleri doğrudan çekirdeğe ekleyebiliyordunuz. Ürüne özel kodun modüllerde uygulanması gerektiği ve yukarı akışta çekirdeklerde veya ACK'de kabul edilmeyeceği için GKI 2.0'da bu mümkün değildir. GKI, iş ortaklarının kullandığı ve temel çekirdek kodu üzerinde minimum etkiye sahip olan katma değerli özellikleri etkinleştirmek için modüllerin temel çekirdek kodundan çağrılmasına olanak tanıyan satıcı kancalarını kabul eder. Ayrıca, bu özellikleri uygulamak için satıcıya özel verileri depolamaya yönelik satıcı veri alanlarıyla önemli veri yapıları doldurulabilir.

Tedarikçi kancaları, tedarikçi modüllerinin ekleyebileceği izleme noktalarına (izleme etkinlikleri değil) dayalı olarak iki varyantta (normal ve sınırlı) sunulur. Örneğin, görevden çıkışta muhasebe yapmak için yeni bir sched_exit() işlevi eklemek yerine, tedarikçiler do_exit()'ye bir kanca ekleyebilir. Bu kancaya, işleme için bir tedarikçi modülü bağlanabilir. Örnek bir uygulamada aşağıdaki satıcı kancaları bulunur.

  • Normal satıcı kancaları, DECLARE_HOOK() kullanarak trace_name adlı bir izleme noktası işlevi oluşturur. Burada name, izin benzersiz tanımlayıcısıdır. Normal tedarikçi kancası adları geleneksel olarak android_vh ile başlar. Bu nedenle, sched_exit() kancasının adı android_vh_sched_exit olur.
  • CPU çevrimdışı olsa bile eklenen işlevin çağrılması gereken veya atomik olmayan bir bağlam gerektiren zamanlayıcı kancaları gibi durumlarda kısıtlanmış tedarikçi kancaları gerekir. Kısıtlanmış sağlayıcı kancaları ayrılamaz. Bu nedenle, kısıtlanmış bir kancaya bağlanan modüller hiçbir zaman kaldırılamaz. Kısıtlanmış tedarikçi kancası adları android_rvh ile başlar.

Tedarikçi kancası eklemek için BT'de bir sorun kaydı oluşturun ve yamaları gönderin (tüm Android'e özgü yamalarda olduğu gibi, bir sorun olmalı ve gerekçe sunmalısınız). Satıcı kancaları yalnızca ACK'de desteklenir. Bu nedenle, bu yamaları yukarı akış Linux'a göndermeyin.

Yapılara tedarikçi alanları ekleme

ANDROID_VENDOR_DATA() makrolarını kullanarak android_vendor_data alanları ekleyerek tedarikçi verilerini temel 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.

Tedarikçilerin ihtiyaç duyduğu alanlar ile OEM'lerin ihtiyaç duyduğu alanlar arasında olası çakışmaları önlemek için OEM'ler, ANDROID_VENDOR_DATA() makroları kullanılarak tanımlanan alanları hiçbir zaman kullanmamalıdır. Bunun yerine, OEM'ler android_oem_data alanlarını bildirmek için ANDROID_OEM_DATA() kullanmalı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ımlama

DECLARE_HOOK() veya DECLARE_RESTRICTED_HOOK() kullanarak bildirdikten sonra bunları izleme noktası olarak koda ekleyerek çekirdek koduna izleme noktası olarak satıcı kancaları ekleyin. Örneğin, mevcut do_exit() çekirdek işlevine 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şleyici kaydederse kayıtlı işlev çağrılır. İşleyici, tutulan kilitler, RCS durumu ve diğer faktörlerle ilgili bağlamın farkında 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/exit.h dosyasındaki 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>

Tedarikçi kancası için gereken arayüzleri oluşturmak üzere kanca bildirimi içeren başlık dosyasını drivers/android/vendor_hooks.c konumuna ekleyin 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: Kanca bildiriminde kullanılan veri yapılarının, ABI kararlılığını garanti etmek için tam olarak tanımlanması gerekir. Aksi takdirde, opak işaretçilerin referansını 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 include, drivers/android/vendor_hooks.c'nin #ifndef __GENKSYMS__ bölümüne gitmelidir. include/trace/hooks içindeki başlık dosyaları, KMI'yi bozan CRC değişikliklerinden kaçınmak için tür tanımlarını içeren çekirdek başlık dosyasını içermemelidir. Bunun yerine türleri iletin.

Tedarikçi kancalarına ekleme

Tedarikçi kancalarını kullanmak için tedarikçi 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 kodda foo.ko için trace_android_vh_sched_exit() modülü işleyicisi gösterilmektedir.

#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);
    ...
}

Üstbilgi dosyalarındaki tedarikçi kancalarını kullanma

Üst bilgi dosyalarındaki satıcı kancalarını kullanmak için satıcı kancası üst bilgi dosyasını, izleme noktası üst bilgi dosyasının bulunamadığını belirten derleme hatalarını önlemek üzere TRACE_INCLUDE_PATH'yı tanımsız hale getirecek şekilde güncellemeniz gerekebilir. Ö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 derleme hatasını düzeltmek için dahil ettiğiniz satıcı kancası üstbilgi dosyasına eşdeğer düzeltmeyi uygulayın. Daha fazla bilgi için https://r.android.com/3066703 adresini ziyaret edin.

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, izleme noktaları oluşturulduktan sonra TRACE_INCLUDE_PATH öğesinin tanımını kaldırması istenir.

Temel çekirdek özellikleri

Önceki tekniklerin hiçbiri bir modüldeki özelliği uygulamanıza olanak tanımıyorsa özelliği çekirdek çekirdeğinde Android'e özgü bir değişiklik olarak eklemeniz gerekir. Konuşmayı başlatmak için sorun izleyicide (IT) bir sorun oluşturun.

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

  • UAPI üstbilgi dosyaları. Değişiklikler Android'e özgü arayüzlerde yapılmadığı sürece UAPI üstbilgi dosyalarında yapılan değişiklikler yukarı akışta gerçekleşmelidir. Tedarikçi modülleri ile tedarikçi kullanıcı alanı kodu arasındaki arayüzleri tanımlamak için tedarikçiye özel üstbilgi dosyalarını kullanın.
  • sysfs düğümleri. GKI çekirdeğine yeni sysfs düğümleri eklemeyin (bu tür eklemeler yalnızca satıcı modüllerinde geçerlidir). Android çerçevesini oluşturan SoC ve cihazdan bağımsız kitaplıklar ile Java kodu tarafından kullanılan sysfs düğümleri yalnızca uyumlu şekilde değiştirilebilir ve Android'e özgü sysfs düğümleri değilse yukarı akışta değiştirilmelidir. Tedarikçiye özel kullanıcı alanında kullanılacak tedarikçiye özel sysfs düğümleri oluşturabilirsiniz. Varsayılan olarak, kullanıcı alanının sysfs düğümlerine erişimi SELinux kullanılarak reddedilir. Yetkili satıcı yazılımının erişmesine izin vermek için uygun SELinux etiketlerini eklemek satıcının sorumluluğundadır.
  • DebugFS düğümleri. Tedarikçi modülleri, yalnızca hata ayıklama için debugfs içinde düğümler tanımlayabilir (çünkü debugfs, cihazın normal çalışması sırasında monte edilmez).