هیچ تعریف ثابتی برای فایل سیستم “Android” وجود ندارد و این تعریف بین بین دستگاه های مختلف، متفاوت است. هر فایل سیستمی که هسته سیستم عامل (کرنل) می تواند درایورش را بارگذاری کند، در اندروید قابل استفاده است، در ادامه با انواع فایل سیستم هایی که در اندروید استفاده شده اند، به همرا جزییات دقیقی از آنها آشنا میشویم.
اندروید از چه فایل سیستمی استفاده میکند؟
روی هم رفته، با در نظر گرفتن دستگاه های اندروید رایج، فایل سیستم ext4 رایج ترین فایل سیستم در دستگاه های مدرن است. دستگاه های قدیمی تر ممکن است از فرمت های *ext قدیمی تر مانند ext2، و یا فایل سیستم های دیگر نیزاستفاده کنند. از آنجا که همه چیز در اندروید بر پایه لینوکس ساخته شده، فایل سیستم ext4 انتخاب بسیار معقولی است که با پشتیبانی پایدار از هسته لینوکس و سابقه خوب ساخته شده است. در ادامه می توانید در مورد اینکه چرا این تصمیم گرفته شده را در مقاله آرس تکنیکا (Ars Technica) در زمینه انتخاب ext4 توسط گوگل بخوانید.
برخی از دستگاه ها ی Android نیز از (Flash-Friendly File System (f2fs که توسط سامسونگ ارایه شده، استفاده میکنند. قابل ذکر است، تعدادی از دستگاه های موتورولا، و همچنین نکسوس 9 از f2fs استفاده میکنند. هدف از f2fs ایجاد یک فایل سیستم است که به طور خاص با نیازهای رسانه های ذخیره سازی مبتنی بر فلش سازگار است؛ و در تلاش برای به حداکثر رساندن عملکرد در دستگاه های مبتنی بر تراشه های NAND که از آن برای رسانه ذخیره سازی اصلی خود استفاده میکنند، طراحی شده است.
با این حال، با توجه به اشاره ای که بالا شد، این به این معنا نیست که این ها تنها فایل سیستم هایی هستند که Android قادر به اجرای آنهاست. با توجه به متن باز بودن هسته Android و آزادی تمام کاربران در تغییر آن، اظافه کردن درایور های مختلف برای پشتیبانی از فایل سیستم های دیگر کاملا آزاد است. برای مثال، Android x86 از نصب شدن روی فایل سیستم های NTFS و FAT32 بطور پیش فرض پشتیبانی میکند.
سلسله مراتب فایل ها در اندروید
یک جستجوی ساده در اینترنت در مورد سلسله مراتب فایل سیستم Android اطلاعات زیادی نمیدهد. البته برای کاربران ویندوز، این موضوع دنیای دیگری دارد. برای کاربران لینوکس، این موضوع یک تنوع از سلسله مراتب فایل در سیر تکاملی لینوکس است. در لینوکس / اندروید/ یونیکس (برای سادگی، فقط به اسم لینوکس اشاره میکنم)، سلسله مراتب فایل مانند یک درخت است، که اولین و بالا ترین شاخ درخت “/” – ریشه (root) نام دارد. فایل ها و دایرکتوری ها، در زیر شاخه های “/” قرار گرفته اند. سلسله مراتب فایل لینوکس، بر خلاف ویندوز فاقد مفهوم درایور هاست. در عوض، فایل سیستم ها در یک دایرکتوری بالا آمده (mount شده) برای ایجاد یک درخت یکپارچه است. برای فیل سیستم های مبتنی بررسانه، فایل سیستم نشان دهنده یک پارتیشن برای آن رسانه است. تفاوتی نمی کند که فایل سیستم بر روی دستگاه محلی بطور فیزیکی وجود دارد، یا در یک دستگاه از راه دور (remote) قرار گرفته است. همه چیز در قالب یک سلسله مراتب فایل واحد نمایش داده می شود؛ که با ریشه (root) شروع میشود.
کلمه (path) یا مسیر، به مسیر یک فایل یا دایرکتوری اشاره میکند. مسیر کامل (absolute path) به هر فایل یا دایرکتوری، همیشه با “/” (root) آغاز می شود. به عنوان مثال، ممکن است نرم افزار های مدیریت فیل شما، مسیر به حافظه فلش داخلی را به عنوان “mnt/sdcard/” نشان دهند، و یا اگر دستگاه اندروید شما شامل کارت SD خارجی است، آن را به عنوان “/mnt/extSdCard/” نمایش دهد. ممکن است نام فایلی که در زیر دایرکتوری ریشه به عنوان نام حافظه های داخلی یا خارجی بالا آمده (mount شده) با توجه به سازنده های متفاوت دستگاه ها و توزیع های مختلف (distributions) اندروید، متفاوت باشد؛ اما مفهوم آنها یکسان باقی می ماند. به عنوان مثال، سیانوژن (یکی از ویرایش های معروف اندروید برای کاربران حرفه ای) مانت فلش درایو خارجی به عنوان “/mnt/sdcard/” نمایش میدهد، و حافظه فلش داخلی را به عنوان “/mnt/emmc/” نمایش میدهد. نکته مهم که باید به خاطر داشته باشید این است که هر یک از این دایرکتوری ها نشان دهنده یک نقطه بالا آمدن (mount point) برای یک فایل سیستم است؛ Mount point یک دایرکتوری در فایل سیستم است که در آن اطلاعات اضافی منطقی از یک محل ذخیره سازی در خارج از درایو ریشه سیستم عامل و پارتیشن های متصل به آن، وجود دارد. به عنوان یک کاربر معمولی، یک فایل آندروید فقط نمایش دهنده فایل سیستمی است که شما به آن دسترسی دارید. این فایل سیستم ها تنها بخشی از کل سلسله مراتب فایل در اندروید میباشند.
برای دیدن سلسله مراتب کامل فایل در آندروید، شما نیاز به دسترسی روت (root access) دارید. در این مورد، “root” به یک حساب کاربری ویژه که دسترسی مدیریتی کامل بر سیستم دارد، اشاره میکند. وقتی که شما یک دستگاه آندروید را اصطلاحا روت کنید، شما در واقع به حساب کاربری root دسترسی پیدا کرده اید. یک دلیل مهم برای نداشتن دسترسی root به طور خودکار وجود دارد – یک اشتباه کوچک می تواند یک دردسر بزرگ ایجاد کند. با این حال، برای کسانی که درزمینه دستورات لینوکس و مدیریت سیستم عامل لینوکس تجربه دارند، دسترسی root راهی را به زیرساخت های اندروید برایشان باز می کند.
سیستم فایل در Android
همانطور که در قسمت مربوط به مقایسه هسته اندروید و هسته لینوکس گفته شد، آندروید از هسته لینوکس استفاده می کند. تمامی عملیات مربوط به فایل و دایرکتوری (پرونده ها و پوشه ها) اجرا شده توسط برنامه ها از یک لایه انتزاعی کرنل به نام سیستم فایل مجازی (VFS) می گذرد. تمامی فایل سیستم ها، که تعداد آنها بسیار زیاد است، به نوعی پیاده سازی VFS هستند. هر فایل سیستم دارای یک کرنل ماژول جداگانه است که عملیات VFS پشتیبانی شده توسط آن را ثبت میکند. با جداسازی اجرا از مفاهیم انتزاعی، اضافه کردن یک فایل سیستم جدید تنها نوشتن یک کرنل ماژول دیگر خواهد بود. این ماژول ها یا بخشی از کرنل هستند و یا به صورت پویا به هنگام نیاز بارگذاری می شوند. هسته آندروید دارای زیر مجموعه ای از مجموعه گسترده فایل سیستم ها، از فایل سیستم ژورنال (JFS) برای AIX (نسخه آی بی ام یونیکس) گرفته تا فایل سیستم آمیگا، می باشد. جزئیات عملیات انجام شده از دید کاربر پنهان است، زیرا کرنل تمامی کارها را در هنگام بارگذاری یک فایل سیستم به عهده می گیرد.
فایل پیکربندی هسته تعیین کننده ی این است که چه ماژول هایی از فایل سیستم، کامپایل شده، و اینکه آیا آنها را در داخل هسته ساخته شده اند، و یا به صورت پویا (dynamic) بارگذاری شده اند. در نتیجه، هسته آندروید فقط شامل ماژول هایی از سیستم فایل است که مربوط به فعالیت خود می باشد. در واقع، به طور معمول هیچ توزیع لینوکسی که هر ماژول از File System را کامپایل کند، وجود ندارد. همینطور برخی از سیستم های فایل هستند که به معماری سخت افزاری وابسته نیستند. در حالی که سیستم فایل های پشتیبانی شده در دستگاه های مختلف آندروید متفاوت هستند، File System های مربوط به حافظه های فلش که رایج هستند، به شرح زیر است:
exFAT – به معنای جدول تخصیص فایل، سیستم فایل اختصاصی مایکروسافت برای حافظه های فلش است. با توجه به الزامات صدور مجوز، این فایل سیستم بخشی از کرنل استاندارد لینوکس نیست. با این حال، برخی از تولید کننده ها پشتیبانی اندرویدی این فایل سیستم را نیز عرضه می کنند.
F2FS – سامسونگ Flash-Friendly File System را به عنوان یک پروژه متن باز برای لینوکس در سال 2012 معرفی کرد.
JFFS2 – نسخه دوم فایل سیستم Journal Flash که از نسخه Ice Cream Sandwich به بعد فایل سیستم فلش پیش فرض برای کرنلهای AOSP (پروژه متن باز اندروید) است. JFFS2 جایگزینی برای JFFS اصلی است.
YAFFS2 – فایل سیستم Yet Another Flash File System نسخه 2، فایل سیستم پیش فرض فلش برای توزیع های AOSP که نسخه اصلی توزیع پروژه اندروید توسط گوگل است (َAndroid Open Source Project)، برای نسخه هایی با کرنل لینوکس 2.6.32 بود. YAFFS2 در نسخه های جدیدترتوسط کرنل پشتیبانی نمی شود و درsource tree برای آخرین نسخه های کرنل اندروید وجود ندارد. (source tree کرنل اندروید در سایت kernel.org قابل مشاهده است) با این حال، بعضی از سازندگان دستگاه تلفن همراه اندروید خاص، ممکن است به حمایت از YAFFS2 ادامه دهند.
علاوه بر فایل سیستم حافظه فلش، دستگاه های آندروید معمولا از فایل سیستم های مبتنی بر رسانه که در زیر مشاهده میکنید، پشتیبانی می کند:
EXT2 / EXT3 / EXT4 – این فایل سیستم ها سیستم فایل استاندارد لینوکس هستند و EXT4 نسخه کنونی است. از سال 2010، EXT4 اغلب به جای YAFFS2 یا JFFS2 به عنوان فایل سیستم برای حافظه فلش داخلی در دستگاه های آندروید استفاده می شود.
MSDOS – درایور MSDOS از فایل سیستم های FAT12، FAT16 و FAT32 پشتیبانی می کند.
VFAT – VFAT در واقع یک سیستم فایل نیست، بلکه در ادامه سیستم های FAT12، FAT16، FAT32 ایجاد گردیده و از این دسته می باشد. بنابراین، ماژول کرنل VFAT همواره در کنار ماژول MSDOS دیده می شود. کارت های SD خارجی معمولا با استفاده از VFAT فرمت می شوند.
فایل سیستم های فوق فایل سیستم های مبتنی بر رسانه هستند. VFS همچنین از شبه فایل سیستم ها نیز، که مبتنی رسانه نیستند، پشتیبانی می کند. کرنل لینوکس از تعدادی از شبه فایل سیستم ها پشتیبانی می کند، که از آن میان دسته ای که در دستگاه های آندرویدی مهم هستند عبارتند از:
cgroup – در cgroup (گروه کنترل) یک شبه فایل سیستم برای دسترسی و تعریف پارامتر ها ی مختلف مریوط به کرنل ایجاد می کند. در حالی که cgroup یک شبه فایل سیستم است، تعدادی گروه مختلف کنترل فرآیند (control group) وجود دارد. اگر دستگاه Adroid شما از گروه کنترل فرآیند پشتیبانی میکند، شما یک لیست از این گروه ها را در فایل “proc/cgroups/” خواهید یافت. آندروید از cgroups برای حساب های کاربری (َacct) و کنترل سی پی یو (cpuctl) استفاده می کند.
rootfs – این فایل سیستم به عنوان mount pint برای فایل سیستم root (“/”) کار میکند. یعنی اطلاعات مربوط به بالا آمدن شاخه روت مثل اطلاعات منطقی از محل ذخیره سازی روت را نگه داری میکند.
procfs – فایل سیستم procfs به طور معمول در دایرکتوری proc/ نصب شده است، و نشان دهنده تعدادی از ساختمان داده های مربوط به کرنل است. عملیات روی این فایل ها با استفاده از داده های جاری در کرنل انجام میگیرد. دایرکتوری های عددی نشان دهنده ی شناسه ی عملیات ها یا process ID ها (در واقع، شناسه ی پردازش مربوط به thread group leader) برای هر task در حال اجرا هستند. فایل proc/filesystems/ یک لیست از فایل سیستم هایی که تعریف شده اند نشان میدهد. فایل سیستم هایی که در دنبال اسم خود عبارت NODEV را دارا هستند، شبه فایل سیستم (Pseudo File System) هستند، و به هیچ دستگاهی مربوط نمی شوند. دایرکتوری /proc/sys/ شامل پارامترهای کرنلی میباشد، که برخی از آنها قابل تنظیم اند.
sysfs یک مدل سیستمی مربوط به دستگاه است که معمولا ساختاری شی گرا دارد که نشان دهنده دستگاه هایی است که توسط هسته از طریق فایل sysfs شناسایی شده اند، و به طور معمول در دایرکتوری sys/ بالا آمده (mount) است. هنگامی که هسته، یک دستگاه جدید را کشف میکند، یک شی در دایرکتوری /sys/devices/ میسازد. کرنل با استفاده از یک سوکت شبکه برای برقراری ارتباط با udevd daemon برای اطلاعات دستگاه جدید استفاده میکند، و یک ور.دی در دایرکتوری /dev/ میسازد.
udev یک درگاه مدیریت کننده عمومی دستگاه ها برای کرنل است. و به عنوان یک daemon در لینوکس اجرا می شود و از طریق سوکت netlink به uevent هایی که از طرف هسته فرستاده شده، گوش فرا میدهد؛ و هنگام اضافه و یا حذف یک دستگاه جدید، با خبر میشود.
دایرکتوری /sys/fs/ شامل ساختارهای شی گرا برای فایل سیستم های مبتنی بر رسانه است. دایرکتوری /sys/module/ شامل اشیایی برای هر ماژول لود شده ی کرنل است.
tmpfs – فایل سیستم tmpfs اغلب در دایرکتوری dev/ بالا آمده (mount) است. از آنجا که یک شبه فایل سیستم است، هر گونه اطلاعات در دایرکتوری dev/ در زمانی که دستگاه reboot می شود، از بین میرود.
در حالی که به نظر می رسد فایل سیستم های بسیاری وجود دارند، اینها فقط جزء کوچکی اند. برای کسانی که دسترسی root ندارند، این فایل سیستم ها و دایرکتوری ها از نظرشان پنهان است؛ از آنجایی که اجازه دسترسی به آنها را ندارند. اکثر گوشی های رایج اندروید یک گزینه “USB debugging” در منوی مربوط به تنظیمات توسعه دهندگان در قسمت تنظیمات دستگاه قرار میدهند. هنگامی که این گزینه فعال باشد؛ گوشی اجازه اتصال به دستگاه از روی یک کامپیوتر را با استفاده از Android Debugging Bridge یا ADB را میدهد. اما در حالی که همان سطح اختیارات کاربر معمولی را فراهم می کند، اجازه دسترسی به بسیاری از دایرکتوری ها و بسیاری از دستورات رایج لینوکس را میدهد. این گزینه معمولا در اکثر دستگاه های اندروید یافت میشود، و برای مقاصد برنامه نویسی و تست نرم افزار روی دستگاه فیزیکی استفاده میشود. شما همچنین می توانید از برنامه های شبیه ساز ترمینال استفاده کنید که روی خود دستگاه، به شما دسترسی console را بطور شبیه سازی شده میدهند.
سلسله مراتب فایل در اندروید
همانطور که در بالا ذکر شد، سلسله مراتب فایل آندروید یک نسخه اصلاح شده از سلسله مراتب فایل در لینوکس است. در ساختار سلسله مراتب فایل در نسخه های مختلف لینوکس و نسخه های ارائه شده توسط سازندگان مختلف تقاوتهای جزئی وجود دارد. تأکید می شود که این تفاوتها بسیار اندک می باشد. موارد زیر خلاصه ای است از سطوح بالای ساختار دایرکتوری مدل AOSP نسخه Jelly Bean.
acct – این دایرکتوری mount point برای control group مربوط به acct را فراهم می کند که برای حساب های کاربری مورد استفاده قرار میگیرد.
mount point – cache برای پارتیشن dev/block/mtdblock2/ است. (نام پارتیشن ممکن است در دستگاه های مختلف مربوط به سازنده های مختلف، متفاوت باشد). اندازه کش محدود به اندازه این پارتیشن می باشد.
د – یک پیوند نمادین به sys/kernel/debug/.
mount point – data برای dev/block/mtdblock1/.
default.prop – این فایل به طور پیش فرض ویژگی های مختلفی را تعریف میکند.
mount point -dev برای یک فایل سیستم tmpfs تعریف می کند، که تعریف کننده ی دستگاه های موجود برای برنامه های کاربردی است. دایرکتوری dev/cpuctl/ برای گروه کنترل cpuctl یک mount point است. (با استفاده از شبه فایل سیستم cgroup) .
etc – یک پیوند نمادین به system/etc/.
init – یک برنامه باینری که فایل init.rc را پردازش میکند. فایل init.rc فایل های دیگر init.*.rc را وارد میکند. در هنگام بوت شدن Android، کرنل برنامه init را اجرا میکند، و در پایان اجرای init، فرایند بوت اتفاق می افتد. خواندن فایل init.rc از آنجایی که همه ی اطلاعات پیکربندی برای دستگاه اندروید را شامل میشود، مهم است. از آنجا که اندروید از etc/systemctl.conf/ پشتیبانی نمی کند، به روز رسانی پارامترهای /proc/sys/kernel بخشی از وظیفه ی فایل init.rc می باشد. مگر اینکه شما یک درک خیلی خوب از فعالیت های داخلی هسته لینوکس دارید، شما نباید این پارامترها را تغییر دهید. همینطور این موضوع را باید در مورد پارامتر های موجود در dev/cpuctl/ نیز، رعایت کنید.
mnt – علاوه بر mount های حافظه های داخلی و خارجی و کارت های SD، این دایرکتوری به عنوان یک mount pont برای دیگر فایل سیستم ها عمل می کند. در دایرکتوری mnt/asec/ یک mount point برای یک فایل سیستم tmpfs است، و این، بخشی از امنیت اندروید است. دایرکتوری mnt/obb/ یک mount point برای فایل سیستم tmpfs است؛ و فایل های توسعه برنامه های کاربردی که حجمشان بیش از 50MB است را ذخیره میکند. دایرکتوری mnt/secure/ جزء دیگری از بخش امنیت آندروید است. همچنین شما می توانید mount point هایی مربوط یه یک، یا تعدادی دستگاه USB را ببینید.
mount point – proc برای فایل سیستم procfs را فراهم می کند که دسترسی به ساختمان داده های هسته دارد. برنامه ها، مانند ps، lsof و vmstat، استفاده از proc/ به عنوان منبع برای اطلاعات خود استفاده میکنند.
root – دایرکتوری home برای حساب کاربری root.
sbin – در حالی که بسیار کوچکتر از دایرکتوری sbin/ در یک توزیع لینوکس استاندارد است، اما شامل فایل های باینری برای تعدادی از daemon های مهم است.
sdcard – یک پیوند نمادین به mnt/sdcard/.
sys – یک mount point برای شبه فایل سیستم sysfs است، که بازتابی (reflection) از ساختار شی گرای دستگاه برای کرنل است. اطلاعات بسیار زیادی در این شاخه وجود دارد، اما نیاز به درک درستی از مدل دستگاه برای کرنل، دارد. به طور خلاصه، دایرکتوری ها نشان دهنده اشیاء هسته، و فایل ها صفاتی برای آن اشیاء می باشند.
system – این پوشه نقطه بارگذاری ()dev/block/mtdblock است. در این دایرکتوری دایرکتوری های دیگری است که به طور معمول تحت پوشه root در لینوکس استاندارد دیده می شود. این دایرکتوری شامل bin، etc، lib، usr، و xbin می باشد.
ueventd.goldfish.rc ueventd.rc – این فایل ها قوانین پیکربندی برای دایرکتوری dev/ را تعریف میکند.
vendor – یک پیوند نمادین به system/vendor/.
حال با توجه به اینکه در مورد جزییات فایل سیستم اندروید و اجزای آن اطلاعات بیشتری داریم، میبینیم که کرنل اندروید شباهت بسیار زیادی نسبت به دیگر توزیع های لینوکس دارد، پس اگر درک بالایی از طرز کار کرنل لینوکس استاندارد دارید، میتوانید با کمی تغییرات، کرنل سیستم عامل دستگاه اندروید خود را در زمینه دستکاری فایل سیستم ها تغییر دهید، برای مثال میتوانید با در اختتیار داشتن سورس کد درایور فایل سیستم خاص مد نظر شما، آن را برای اندروید کامپایل کنید و روی کرنل نصب کنید و پشتیبانی از آن فایل سیستم خاص را روی دستگاه خود ایجاد کنید.
البته در نظر داشته باشید که تمام اینها مستلزم داشتن دسترسی root روی دستگاه اندروید مورد نظر شماست.
با تشکر از دکتر مهدی باطنی برای ارایه توضیحات و اطلاعات بسیار عالی در زمینه فایل سیستم ها و اصول ذخیره و بازیابی اطلاعات.