چطور یک توزیع لینوکس بسازیم؟

ساخت توزیع لینوکس از جمله کارهاییه که معمولا وقتی کسی وارد دنیای لینوکس میشه دوست داره تجربه‌ش کنه. چرا؟ چون فکر می‌کنه افراد قبلی که این کار رو کردند، آدمهای خفنی بودن (که تفکر غلطی هم نیست) و فکر می‌کنند اگر دست کم یک توزیع بسازن آدم خفنی میشن (که تفکر غلطیه).

حالا آیا واقعا آدم خفنی می‌شیم اگر یک توزیع بسازیم؟ خیر. اما به ما در جهت پیشرفت و خفن شدن کمک می‌کنه. می‌پرسید چطوری؟ در جریان ساخت توزیع لینوکس شما با زیر و بم این سیستم‌عامل آشنا می‌شید و می‌فهمید ابزارهای مختلف چطور کار می‌کنند. این روش، یکی از بهترین روشهای یادگیری لینوکس و حتی سیستم‌عامله.

فکر کنم پیش‌تر به قدر کافی در مورد این که چند راه برای ساخت توزیع داریم حرف زدم. در این پست منتها قصد اینه که یک دبیان یا اوبونتویی که از پیش روی سیستم خودمون (یا ماشین مجازی) نصب شده رو به یک  ISO زنده تبدیل کنیم.

نصب و پیکربندی دبیان یا اوبونتو

در قدم اول، شما نیاز دارید که دبیان یا اوبونتو رو روی سیستم خودتون یا ماشین مجازی نصب کنید. توصیه شخصی من اینه که در دیسک یا پارتیشن جدایی نصب کنید. چرا؟ چون ما محدودیت‌هایی در ISO داریم. عموم ISO هایی که از توزیع‌های مختلف لینوکس ساخته میشن، استانداردشون iso9660 عه که یک محدودیت ۴ گیگابایتی داره. پس باید حواسمون به این موضوع هم باشه.

بعد از نصب (نصب دبیان و اوبونتو خیلی ساده‌ست : نکست نکست نکست …)، نیازه که این بسته‌ها حتما نصب بشن:

~:$ sudo apt install git mtools xorriso squashfs-tools

این بسته‌ها شامل یک سری ابزار دم دستی برای مدیریت فایل‌سیستم و … هستند. حجم زیادی هم ندارند. البته، git که معرف حضور هست برای چی استفاده میشه و خب ما قراره باهاش یه سری چیزا رو از گیت‌هاب/گیت‌لب دریافت کنیم.

هم‌چنین، بعد از نصب بسته‌های بالا، مطمئن بشید که rsync هم در سیستم نصب شده. این بسته معمولا در توزیع‌های لینوکسی نصبه، اما اگر نبود هم خطری نداره. می‌تونید نصبش کنید.

شخصی‌سازی

خب در بحث شخصی سازی ما سناریوهای مختلفی داریم. در حال حاضر، قصد ورود به بخش‌هایی مثل تغییر لوگو و … ندارم. اما مثلا شخصی سازی میزکار کجاست؟!

شما اگر دستور زیر رو اجرا کنید:

~:$ ls -a ~

یک سری فایل و فولدر می‌بینید که با نقطه شروع شدند. این‌ها اسمشون «نقطه‌پرونده» یا «دات‌فایل»ـه. معمولا پیکربندی‌ها اینجان. این پیکربندی‌ها، تنظیمات پوسته، میزکار و … رو شامل می‌شن.

خب، حالا که در مورد این‌ها می‌دونیم با خیال راحت شخصی‌سازیمون رو انجام می‌دیم. بعدش با این دستور، پیکربندی‌هامون رو آماده انتقال به کاربران دیگر می‌کنیم :

~:$ sudo cp -r ~/.config /etc/skel
~:$ sudo cp -r ~/.local /etc/skel
~:$ sudo cp ~/.bashrc /etc/skel
~:$ sudo cp ~/.profile /etc/skel 
~:$

حواستون باشه که یک سری تنظیماتی مثل gnome-keyring در پوشه local هست که باید حذف کنید بعد انتقال.

حالا این skel چیه که انقدر مهمه؟ skel کوتاه‌شده skeleton عه. در واقع اسکلت کاربرا رو اینجا نگه می‌داریم. بعد از این که با useradd یا adduser یک کاربر جدید ایجاد کنیم، محتویات این پوشه رو برمیداره می‌بره میذاره در پوشه خانگی اون کاربر.

به عبارتی فرض کنید که یک سری الگو و نقشه از دکوراسیون خونه داریم، وقتی کسی از ما یه واحد می‌خره همون الگو رو می‌بریم در واحدش پیاده‌سازی می‌کنیم.

باقی شخصی‌سازی‌ها هم بیشتر به نصب نرم‌افزار و … مربوط میشن. گرچه در مورد لوگو و … توضیح زیادی ندادم اما یک تقلبی به شما می‌رسونم. اگر از دبیان استفاده می‌کنید، دنبال desktop-base بگردید و اونجا خرابکاری کنید 😁 البته راه‌های تغییر ظاهر سیستم‌های لینوکسی به اندازه راه‌های رسیدن به خداست، با کمی جست و جو و پرسشگری می‌تونید به نتیجه‌های بسیار خوبی برسید.

اسکریپت ساخت دیسک زنده

مدتها پیش در جریان ساخت کاپریس لینوکس (لینک) برای تهیه ایزوی نهایی، یک اسکریپتی نوشتم. این اسکریپت بعدها در ساخت سیستم‌عامل سانا (لینک) هم استفاده شد. در واقع، این اسکریپت تلاشی برای زنده کردن ابزارهایی مثل remastersys و relinux بود که در دوران قدیم (حوالی سال ۴۲) برای ساخت ایزوی زنده از یک سیستم لینوکسی استفاده می‌شد.

این اسکریپت رو به این شکل از گیتهاب دریافت می‌کنیم :

~:$ git clone https://github.com/Caprice-Linux/live_image custom_live

که به این شکل، پوشه‌ای به اسم custom_live برای شما ساخته میشه که حاوی اسکریپت و متعلقاتش (مثل تنظیمات گراب و syslinux) میشه. الان، ما آماده‌ایم که دیسک زنده بسازیم!

ساخت دیسک زنده

حالا، ما مقدمات ساخت دیسک رو داریم و وقتشه که دیسک رو بسازیم. ابتدا، این دستورات رو اجرا می‌کنیم :

~:$ cd custom_live
~/custom_live:$ mkdir chroot

با دستور اول وارد پوشه custom_live می‌شیم و با دستور دوم یک فولدر خالی به اسم chroot ایجاد می‌کنیم. حالا وقتشه که از rsync عزیزمون استفاده کنیم برای انتقال سیستم نصب شده به این فولدر:

~/custom_live:$ rsync -av --one-file-system \ 
--exclude=/home/* \ 
--exclude=/root/* \ 
--exclude=/tmp/* \ 
--exclude=/sys/* \ 
--exclude=/dev/* \ 
--exclude=/proc/* \ 
--exclude=/var/mail/* \ 
--exclude=/var/spool/* \ 
--exclude=/var/tmp/* \ 
--exclude=/media/* \ 
--exclude=/etc/mtab \ 
--exclude=/etc/fstab \ 
--exclude=/etc/hosts \ 
--exclude=${pwd}/chroot / chroot

خب حالا وقتشه که با یک دستور جدید به اسم chroot آشنا شیم. این دستور، کارش ارسال یک سیگنال از پردازنده‌ست که دایرکتوری ریشه رو به دایرکتوری مورد نظر ما تغییر بده. البته شرایط خاصی هم داره، مثلا این که سیستم‌عامل هر دو جا، یکی باشه. معماری یکی باشه و قص علی هذا.

با دستور chroot دایرکتوری root رو به chroot ای که ساختیم تغییر می‌دیم:

~/custom_live:$ sudo chroot chroot/

و حالا باید یک سری تغییراتی هم اینجا اعمال کنیم. این تغییرات شامل چیان؟ اول از همه دسترسی به اینترنت رو باید به قولی «یارو» کنیم. چطوری یارو کنیم؟ به این شکل :

# rm /etc/resolv.conf
# echo "nameserver 4.2.2.4" > /etc/resolv.conf

بعد از این، لازمه که اسم میزبان رو تغییر بدیم :

# echo "custom" > /etc/hostname

بعدش هم دسترسی ریشه رو یارو کنیم:

# passwd

حالا لازمه یه سری بسته نصب کنیم. البته در حقیقت، چون ما از سیستم نصب‌شده استفاده کردیم، نیازی نیست تعداد زیادی بسته نصب کنیم و فقط یکیش کافیه :

# apt update
# apt install live-boot

بسته live-boot ماژول‌های مورد نیاز کرنل برای بوت شدن به صورت زنده رو هم بهش اضافه می‌کنه. در واقع به کرنل میگه که «من ازت میخوام به صورت زنده هم بتونی بوت بشی».

بعد از اضافه کردن این بسته، نوبتی هم باشه نوبت اینه که کَش apt رو پاک کنیم و یک کاربر به سیستم اضافه کنیم. به این شکل:

# apt clean
# adduser live

بعد از این که کاربر رو اضافه کردیم، لازمه که لاگین اتوماتیک رو به lightdm و یا gdm (بسته به میزکار، توزیع مبدا و … ممکنه این قضیه فرق کنه) اضافه کنیم. از اونجا که این مطلب یه آموزش عمومیه، این قسمت رو بر عهده شما میذارم.

پس از این، لازمه دسترسی sudo هم به کاربر لایو بدیم :

# echo "live      ALL=(ALL)       NOPASSWD: ALL" > /etc/sudoers.d/live

تذکر مهم: این روش به شدت ناامنه و فقط برای دیسک زنده پاسخگوعه. اگر قراره دیسکتون قابل نصب باشه، حتما در تنظیمات نصاب لحاظ کنید که به صورت NOPASSWD کاربر رو نسازه. البته، نصاب‌های مطرح معمولا این موارد رو با سوال و جواب لحاظ می‌کنند.

خب، کافیه که الان با تایپ exit و فشردن کلید اینتر از محیط chroot خارج شیم. یه سری پیکربندی ریز مونده که باید انجام بدیم. این پیکربندی‌های ریز در دبیان و اوبونتو متفاوتن ولی تفاوت اونقدری بزرگ نیست. در ادامه با هم می‌بینیم که چه تفاوتیه.

خب، همونطور که می‌دونید سیستم‌عامل برای بوت شدنش نیازمند کرنله. کرنل سیستم‌عامل و یک ‌initial ram disk برای بوت شدن دیسک زنده نیازه. حالا اینا رو از کجا بیاریم؟ ساده‌ست. از chroot مون میاریم.

در دبیان

خب در دبیان این قضیه راحته. به این شکل فایلا رو کپی می‌کنیم :

~/custom_live:$ cp chroot/boot/vmlinuz-* isotmp/live/vmlinuz
~/custom_live:$ cp chroot/boot/initrd.img-* isotmp/live/initrd.img

در اوبونتو :

در اوبونتو، اون initrd.img کمی اذیت می‌کنه. در واقع بخش اول عین دبیانه ولی بخش دوم اینطوریه :

~/custom_live:$ sudo cp chroot/boot/initrd.img-* isotmp/live/initrd.img
~/custom_live:$ sudo chown $USER:$USER isotmp/live/initrd.img

خب حالا مرحله آخر رسیده. مرحله آخر جاییه که میذاریم ISOمون پخته بشه …

ساخت ISO نهایی

خب لحظه موعود رسید. وقتشه که این همه کاری که کردیم رو ببریم در قالب یک ایزو. برای این کار فقط کافیه که اسکریپت build_image.sh رو به این شکل اجرا کنید:

~/custom_live:$ ./build_image.sh CustomLive.iso isotmp CUSTOMLIVE chroot

و بعد چند دقیقه ایزوی شما آماده‌ست. ایزویی که ساختید رو میتونید حالا با استفاده از qemu یا ویرچوال‌باکس و … تست کنید.

جمع‌بندی

همونطوری که دیدید، این کار گرچه از شما یه متخصص خفن نمی‌سازه، به شما یک دید بسیار بسیار خوب از کلیت قضیه ساخت توزیع میده. شاید باورتون نشه ولی خیلی از توزیع‌های مطرح امروزی مثل مینت، المنتری و …؛ از همین جاها شروع کردند و این راه شروع خوبی برای یادگیری لینوکس و سیستم‌عامله.

امیدوارم مطلب، مطلب مفیدی بوده باشه. دوست دارم بدونم وقتی شما با استفاده از این مطلب توزیع خودتون رو می‌سازید، چه خلاقیت‌هایی به خرج می‌دید.

Share

اتصال به پایگاه داده SQLite در جاوا

مدتی میشه که شروع کردم به یادگیری زبان جاوا چرا که این زبان، علیرغم این که زبان قشنگ و پرکاربردیه، کمک می‌کنه برنامه‌نویس بهتری هم بشم. گذشته از اون، مفاهیم شی‌ءگرایی در جاوا به خوبی پیاده شدند و میشه تا حد زیادی هم برنامه‌نویسی و طراحی شی‌گرا رو با این زبان یاد گرفت.

خلاصه این که در ساعات بیکاری، دموی رایگان آموزش جاوای مشفق همدانی عزیز (وبسایت) رو  دیدم و کمی هم در مورد جاوا و فرمورک‌هاش و …، تحقیق کردم. خلاصه که خواستم یه پروژه فان بزنم و نتیجتا تصمیم گرفتم کمی پروژه رو چالشی کنم. به همین خاطر تصمیم گرفتم که از دیتابیس در پروژه استفاده کنم. رسیدن به این نتیجه که الان در قالب آموزش برای شما درآمده، کار ساده‌ای نبود ولی خب ارزشش رو داشت.

اسکولایت (SQLite) چیه؟

اسکولایت یک سیستم مدیریت پایگاه‌داده رابطه‌ایه که در سال ۲۰۰۰ توسط ریچارد هیپ ساخته شده. این RDBMS عزیز، برخلاف نمونه‌های بزرگ و معروفی مثل MySQL, PostgresSQL, SQL Server و … که نیازمند یک سرور جداگانه هستند، نیازی به داشتن سرور نداره و همه چیز رو در یک فایل، عموما با پسوند sqlite یا sqlite3 ذخیره می‌کنه و اطلاعاتی مثل روابط و داده‌ها رو روی اون فایل می‌نویسه.

این نوع مدیریت دیتابیس برای نرم‌افزارهایی که نیاز دارند داده رو به صورت محلی ذخیره کنند و همچنین سرویس‌های آنلاین کوچک که کاربر زیادی ندارند کاربردیه. همچنین میتونه برای ذخیره موقت اطلاعات هم استفاده بشه. به همین خاطر، محبوبیت زیادی کسب کرده. گذشته از این، در بسیاری از چارچوب‌ها مانند جنگو یا ریلز، در محیط آزمایش (test) و توسعه (development) معموله که از SQLite استفاده کنند تا صرفا ببینن که آیا ساختار داده‌هاشون درسته یا خیر.

تعریف پروژه

خب، حالا که می‌دونیم قراره از جاوا و SQLite استفاده کنیم، بیایم پروژه رو تعریف کنیم. پروژه برای من به این شکل تعریف شده بود:

برنامه‌ای بنویسید که یک نام و یک شماره تلفن از کاربر دریافت کرده و سپس آن را در یک پایگاه‌داده SQLite ذخیره کند.

برای این که پروژه رو کمی متفاوت از چیزی که خودم برای تمرین زدم کنیم، صورتش رو به این شکل تغییر میدیم :

برنامه‌ای بنویسید که یک نام، شماره تلفن و ایمیل از کاربر دریافت کرده و سپس آن را در یک پایگاه‌داده SQLite ذخیره کند.

ابزارهای مورد استفاده در این پروژه

در این پروژه، من از این ابزارها استفاده کردم:

  • جاوا نسخه ۱۳
  • محیط یکپارچه توسعه IntelliJ IDEA
  • درایور SQLite برای جاوا (لینک)

ضمنا، من از سیستم‌عامل لینوکس (در حال حاضر اوبونتو/دبیان) استفاده می‌کنم و چیزایی که در این آموزش بهشون اشاره می‌کنم عموما دستورات لینوکسی هستند. اگر ویندوزی هستید هم میتونید از WSL استفاده کنید یا دستورات مشابه پیدا کنید.

آماده‌سازی و ایجاد پروژه

پس از باز کردن IntelliJ IDEA و سپس ایجاد یک پروژه Command Line جدید، از منوی File و زیرمنوی Project Structure زبانه Dependencies را انتخاب کرده و سپس فایل jar ای که برای SQLite JDBC Driver دریافت کرده‌اید را به پروژه وارد کنید. همچنین، من با دستور زیر، یک دیتابیس خالی در پوشه‌ای در کامپیوتر خودم ایجاد کردم:

touch /home/prp-e/playground/java.sqlite3

به این شکل، من یک فایل قابل فهم برای SQLite ساخته‌ام. قدم بعدی، آشنایی نسبی با پرس‌وجوهای SQLite است.

کمی آشنایی با SQLite

مثل هر دیتابیس SQL دیگری، SQLite هم مجموعه‌ای از پرس‌وجوها اجرا می‌کنه تا به نتیجه‌ای که ما میخوایم برسه. در این بخش، اونهایی که در پروژه استفاده می‌شن رو بررسی می‌کنیم.

ساخت جدول جدید

همونطور که اول گفتیم، قراره در جدول تماسهامون، نام، تلفن و ایمیل اشخاص رو ذخیره کنیم. به همین خاطر موارد رو لحاظ می‌کنیم:

  • یک شناسه منحصر به فرد برای هرفرد که به صورت خودکار، افزایش پیدا کنه
  • اسم فرد به صورت یک رشته متنی
  • شماره فرد به صورت رشته متنی (برای شماره هایی که – یا + و … دارند)
  • ایمیل فرد به صورت رشته متنی

پس پرس‌وجوی اول ما به این شکل میشه :

CREATE TABLE IF NOT EXISTS contacts(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, number TEXT NOT NULL, email TEXT NOT NULL);

در این پرس‌وجو، داریم می‌گیم که اگر جدولی به اسم contacts نبود بسازش. برای هر کاربر یک شناسه به صورت PRIMARY_KEY یا همون شناسه اولیه/منحصر به فرد درنظر بگیر که به صورت خودکار افزایش پیدا کنه. اسم، شماره و ایمیل هم به صورت متن دریافت کن اما خالی نباشن.

اضافه کردن تماس جدید

برای اضافه کردن تماس جدید، کل کاری که باید انجام بدیم اجرای این پرس و جوئه :

INSERT INTO contacts (name, number, email) VALUES ("John Doe", "1-555-123456", "john.doe@gmail.com");

در این پرس و جو میگیم که یک تماس جدید با مشخصات شخصی به نام John Doe به این پایگاه داده اضافه بشه.

پیاده‌سازی در جاوا

برای پیاده‌سازی پروژه، ما نیاز به این موارد داریم:

  • تابعی که اسم دیتابیس، پرس‌وجوی اولیه و پرس‌وجوی مورد نظر ما رو دریافت کنه
  • نوشتن برنامه‌ای که کار دریافت اطلاعات رو انجام بده

تابع دریافت اطلاعات

public static void database_init(String db_address, String init_query, String query){
        String conn = "jdbc:sqlite:/" + db_address;
        try {
            Connection connection = DriverManager.getConnection(conn);
            System.out.println("Connection established to the database.");

            Statement statement = connection.createStatement();
            statement.execute(init_query);

            System.out.println("Successfully created the table.");

            statement.execute(query);

            System.out.println("Successfully ran the query");
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }

    }

همونطوری که می‌بینید، این تابع آدرس دیتابیس ما رو می‌گیره، اون رو به JDBC میده. پس از اون، یک اتصال با دیتابیس ایجاد می‌کنه و اگر اتصال موفقیت‌آمیز بود، یک پیام به شما میده. سپس، یک statement از دیتابیس ایجاد می‌کنه و پرس و جوی اولیه رو اجرا می‌کنه که در اینجا ساخت جدوله. پس از اون هم، کوئری نهایی یا اصل کاری اجرا میشه که در اینجا، میشه همون اضافه کردن تماس به جدول تماسها. همچنین تعریف شده که پس از اجرای هر پرس‌وجو، یک پیام مناسب چاپ بشه.

در مورد Connection, Statement و try catch ها نگران نباشید. این‌ها چیزایین که توسط IntelliJ IDEA هندل میشن. فقط موقع ساخت Connection حواستون باشه که بهتون خطا میده و ازتون میپرسه که «آیا در try catch قرارش بدم؟» و شما باید تاییدش کنید.

حالا که تابع ارتباط با دیتابیس رو داریم، وقتشه که اطلاعات رو از کاربر بگیریم. این کار رو من در تابع main می‌کنم.

تابع اصلی

در تابع اصلی، لازمه که نام، تلفن و ایمیل افراد رو با پیام مناسب، دریافت کنیم. این تابع اصلی برنامه من شد:

public static void main(String[] args) {
    // write your code here
        String query = "CREATE TABLE IF NOT EXISTS contacts(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, number TEXT NOT NULL, email TEXT NOT NULL);";

        Scanner name = new Scanner(System.in);
        Scanner number = new Scanner(System.in);
        Scanner email = new Scanner(System.in);

        System.out.print("Enter a name: ");
        String input_name = name.nextLine();

        System.out.print("Enter a phone number: ");
        String input_number = number.nextLine();

        System.out.print("Enter an email address:");
        String input_email = email.nextLine();

        String insertion_query = "INSERT INTO contacts (name, number, email) VALUES (\"" + input_name + "\", \"" + input_number + "\"" + ", \"" + input_email +"\")";

        database_init("/home/prp-e/playground/java.sqlite3", query, insertion_query);




    }

همونطور که می‌بینید ابتدا یک رشته به اسم query دارم که در اون توضیح دادم دقیقا میخوام چه جدولی با چه مشخصاتی برام ساخته شه. همچنین چک بشه که اگر جدول موجوده، ساخته نشه و روی همون جدول موجود داده‌های جدید وارد بشن.

بعد از اون، سه تا شیء Scanner ایجاد کردم که ورودی رو از ترمینال کاربر بخونن. پس از اون، پیام‌های مناسب رو چاپ کردم و مقداری که Scanner از شما دریافت کرده رو داخل رشته‌های جدید ریختم.

پس از اون هم یه پرس‌وجوی بزرگ ساختم و در اون تعریف کردم که چیزایی که توسط Scanner ها خونده شدند، دقیقا کجا قرار بگیرند. در نهایت، هرچه بود و نبود رو دادم به تابع database_init .

برنامه کامل

این هم کد برنامه کامل که ببینید چی به چیه:

package com.haghiri75;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;

public class Main {

    public static void database_init(String db_address, String init_query, String query){
        String conn = "jdbc:sqlite:/" + db_address;
        try {
            Connection connection = DriverManager.getConnection(conn);
            System.out.println("Connection established to the database.");

            Statement statement = connection.createStatement();
            statement.execute(init_query);

            System.out.println("Successfully created the table.");

            statement.execute(query);

            System.out.println("Successfully ran the query");
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }

    }


    public static void main(String[] args) {
    // write your code here
        String query = "CREATE TABLE IF NOT EXISTS contacts(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, number TEXT NOT NULL, email TEXT NOT NULL);";

        Scanner name = new Scanner(System.in);
        Scanner number = new Scanner(System.in);
        Scanner email = new Scanner(System.in);

        System.out.print("Enter a name: ");
        String input_name = name.nextLine();

        System.out.print("Enter a phone number: ");
        String input_number = number.nextLine();

        System.out.print("Enter an email address:");
        String input_email = email.nextLine();

        String insertion_query = "INSERT INTO contacts (name, number, email) VALUES (\"" + input_name + "\", \"" + input_number + "\"" + ", \"" + input_email +"\")";

        database_init("/home/prp-e/playground/java.sqlite3", query, insertion_query);




    }
}

جمع‌بندی

گرچه این پروژه خیلی از مفاهیم شی‌گرایی رو در خود نداره، تا حد زیادی هم به نظر خودم کثیف نوشته شده و می‌شد از این بهتر باشه، اما پروژه خوبی برای سرگرم شدن به مدت ۲-۳ روز باشه. همچنین توضیح دوباره‌ش باعث شد که کمی کد رو تمیزتر کنم و سپس مطلب رو بنویسم.

این پروژه، برای به چالش کشیدن خیلی از توانایی‌های شما، میتونه گزینه خوبی به حساب بیاد. فلذا اگر میخواید کمی توانایی برنامه‌نویسی خودتون رو محک بزنید، توصیه می‌کنم که شما هم این پروژه رو پیاده‌سازی کنید 🙂

موفق باشید!

Share

کاپریس لینوکس نسخه ۱.۰ پایدار «اتمورا» ریلیز شد.

قبل از اینکه داستان کاپریس‌لینوکس رو تعریف کنم، لازمه داستانی از کاری که باعث شد کاپریس‌لینوکس ساخته بشه کمی بگم. چرا که این داستان، داستانیه که خیلی کم پیش اومده جایی مثل بلاگ مکتوبش کنم. فلذا، اول کمی داستان‌سرایی می‌کنم و بعد به سراغ جزییات فنی می‌ریم.

در اسفند ۹۸، دوست خوبی به نام دانیال بهزادی (که اسمی آشنا برای اهالی نرم‌افزار آزاد و همچنین دوستان لینوکسیه) با من تماس گرفت و پیشنهاد کاری رو داد. اون کار، تهیه یک توزیع لینوکس با حمایت یک شرکت بود و خب من اولش یکم نسبت بهش تردید داشتم اما بعدتر، قبول کردم و سراغ کار رفتیم. در حین این کار، من فهمیدم به یک «زمین بازی» نیاز دارم. همون پروسه‌ای که برای تولید توزیع لینوکسی که شرکت بابتش هزینه می‌کرد رو بابت یک پروژه شخصی طی کردم و هرچی به نظرم این وسط ممکن بود مشکل‌ساز شده باشه رو یه جا یادداشت می‌کردم که باگها دربیان.

کم‌کم دیدم چیزی که خودم ساختم هم کم چیزی نشده. نتیجتا، یه سری از ایده‌های خودم رو روش پیاده کردم و اسمش هم شد «کاپریس لینوکس». کاپریس، هم اسم یه مدل ماشین از شورلته هم به قطعات موسیقی که تغییرات ناگهانی رو شامل میشن اطلاق میشه. این اسم خیلی میومد به پروژه و بعدها بهتر هم فیت شد.

کم کم وسطای پروژه، هیچ پوینتی برای ادامه‌ش نداشتم. اما از طرفی هم وبسایت داشتیم براش، هم یه سری کلا بهم ملحق شده بودند که این پروژه رو به یه جایی برسونن. به همین خاطر، تصمیم گرفتم هرچی ایده‌آل برای یک توزیع لینوکسی دارم رو بریزم در کاپریس! اولین قدم، تولید این میزکار قشنگ براش بود :

گرچه خود این هم چند روزی وقت گرفت ازم (و در نسخه‌های جدیدتر کمی بهبود یافت) اما ارزشش رو داشت.

بعد از اون، به سرم زد که کمی به BSD ها نزدیکش کنم. به همین خاطر APT که سیستم نصب بسته‌های دبیانه رو نگه داشتم، سیستم pkgsrc که یک سیستم مدیریت پورت در NetBSD عه (و تقریبا روی هر سیستم‌عامل دیگری هم امکان اجرا شدن داره، البته با کمی انگولک شدن) رو برای این توزیع پیاده‌سازی کردم.

تا اینجا همه چی خوب بود، به سرم زد که systemd هم یه جوری ازش حذف کنم! کمی تحقیق و بررسی کردم و دیدم به همین سادگی‌ها نیست و یه سری ملزومات خاص داره. اما به سرم زد که سیستم rc.d رو از همون NetBSD حداقل برای سرویس‌هایی که از طریق pkgsrc نصب میشن پیاده کنم.

و خب به همین شکل، این قضیه پیشرفته و پیشرفته‌تر شد تا رسید به کاپریسی که ۱ آگوست ۲۰۲۰ معادل ۱۰ مرداد ۱۳۹۹ منتشر شد.

لینک در وبگاه خبری اصلی

از اونجایی که احتمالا شما هم کنجکاو شدید بیشتر ازش بدونید، دیگه توضیحات اضافه رو اینجا نمی‌دم. بلکه شما رو به وبسایت خود پروژه کاپریس راهنمایی می‌کنم :

http://capricelinux.org/2020/08/01/Caprice-Linux-1.0-STABLE-release-notes.html

 

Share

به روز رسانی اوبونتو از نسخه های LTS به STS

توزیع اوبونتو، معمولا در دونسخه ارائه میشه. نسخه های «پشتیبانی طولانی مدت» یا همون LTS (مخفف Long Term Support ) که اگر اشتباه نکنم هر کدوم تا پنج سال، پشتیبانی دریافت میکنند. این پشتیبانی به معنای پشتیبانی از سمت کنونیکال (شرکت سازنده این توزیع)، دریافت آپدیت های امنیتی و همچنین به روز شدن مستندات توزیع است.

نسخه های STS که طبق روتین ارائه اوبونتو هر شش ماه یه بار میان، قبلا دو سال پشتیبانی می‌شدند ولی مثل این که الان این پشتیبانی کمتر شده و همون شش ماه (یا یک سال، دقیقا نمیدونم و یادم نیست) پشتیبانی رو دریافت میکنن. این نسخه ها به قول معروف «روی لبه تکنولوژی حرکت میکنند» و معمولا تکنولوژی های جدیدی رو در خودشون جای دادن.

هر کدوم از این نسخه ها، مزایای خودش رو داره. خیلی از افراد رو دیدم که با هر آپدیتی، سریعا سیستم عامل خودشون رو آپدیت میکنند و خیلی ها هم ترجیح میدند دو سال یک بار، نسخه های LTS رو آپدیت کنند و یا حتی کل پنج سالی که برای LTS ها پشتیبانی در نظر گرفته شده، روی اون بمونن. اما برگردیم به دسته اول!

فرض کنیم شما آخرین اوبونتوی LTS (در حال حاضر ۱۸.۰۴ ) رو نصب کردید و میخواهید به STS جدید (در حال حاضر ۱۹.۰۴) به‌روز رسانی کنید. برای این کار، نیاز به چند مرحله داریم. اول لازمه که update-manager رو نصب کنیم :

sudo apt install update-manager-core

و البته معمولا این بسته روی اوبونتو نصب شده. فقط در صورتی که نصب نباشه، این دستور نصبش میکنه. نصب هم باشه یا به شما میگه که آخرین نسخه رو نصب کردید یا به روز رسانی میکنه.

گام دوم، اینه که به آپدیت منیجر، بگیم که به جای lts در نسخه های normal برامون دنبال ریلیز جدید بگرده. فقط کافیه این فایل رو با یک ویرایشگر متن باز کنیم (البته ترجیحا ویرایشگرهای خط فرمان؛ چون دسترسی ریشه نیاز داریم) :

/etc/update-manager/release-upgrades

سپس در این فایل، شما احتمالا این خط رو می‌بینید :

Prompt=lts

با تغییر مقدار متغیر prompt به normal ، شما به آپدیت منیجر گفتید که در نسخه های STS به دنبال ریلیز جدید بگرده. بعد از این که عبارت lts رو با normal جایگزین کردید، کافیه فایل رو ذخیره کرده، ببندید و در ترمینال تایپ کنید :

do-release-upgrade

و جایی هم نیاز به پسورد داشته باشید، این دستور ازتون دریافتش خواهد کرد.

این راه حلی بود که خودم دقیقا استفاده کردم برای آپدیت به ۱۹.۰۴. نمیدونم قبلتر کسی در وب فارسی توضیحش داده یا نه، ولی خب امیدوارم که به کارتون بیاد 🙂

Share

نصب و راه اندازی KTechLab برای پروژه های الکترونیک

پروژه های الکترونیک، مثل طراحی مدار، مدارهای منطقی، الکترونیک دیجیتال و … ، همه معمولا توسط نرم افزار Proteus و در سیستم عامل ویندوز انجام میشن. پروتئوس نرم افزار کامل و جامعیه و همه چی هم داره. شما میتونید به سادگی یک پروژه میکروکنترلری در پروتئوس پیاده سازی و اجرا کنید و مطمئن باشید نتیجه‌ای که میگیرید، تا حد بسیار زیاد و قابل قبولی، شبیه نتیجه‌ایه که در پیاده‌سازی حقیقی از پروژه خواهید داشت.

اما مشکلی که اکثر کاربران لینوکس دارند، اینه که پروتئوس نسخه لینوکس نداره. اجرای اون روی واین هم زیاد چنگی به دل نمیزنه و گذشته از اون، همه هم سیستمی ندارند که ماشین مجازی رو تحمل و ساپورت کنه، پس نتیجتا اکثر افرادی که پروژه های الکترونیک انجام میدن، یک سیستم عامل ویندوز هم کنار لینوکسشون دارند. امروز تصمیم داشتم که یک پروژه‌ای رو آزمایش کنم و میخواستم ببینم که روی اوبونتو، چه ابزاری نصب دارم. طبق معمول به دنبال Logisim گشتم ولی فهمیدم که هنوز نسخه جدیدش رو دانلود نکردم. پس، گفتم بهتره سرچ کنم و به نتیجه مطلوب برسم.

در نتیجه جست و جو، به KTechLab رسیدم. گرچه اسمش برام آشنا بود ولی هیچوقت ازش استفاده نکرده بودم. گفتم که بهتره الان به دنبالش باشم و ازش کمی (حتی شده آزمایشی) استفاده کنم. شاید، نتیجه‌ای که خواستم رو گرفتم. خب، خوشبختانه این نرم افزار اون چیزایی که میخواستم رو داشت. این هم تصویری از محیطش :

و الان یک سوال پیش میاد :

چطور نصبش کنیم؟

من اسمش رو جست و جو کردم و به وبسایتش رسیدم (لینک) و بعد سورس کدش رو دانلود کردم. اما فهمیدم که برای نصبش نیاز به cmake دارم، پس اون رو نصب کردم :


کد   
sudo apt install cmake

و بعد از نصب این، کمی گشتم تا ببینم چه پیش‌نیازهایی داره، سپس اونا رو نصب کردم :


کد   
sudo apt install git kdelibs5-dev kdevplatform-dev qt4-dev-tools cmake libglib2.0-dev

بعد از نصب، فایل فشرده حاوی سورس کد رو از حالت فشرده درآوردم، درون پوشه سورس یک پوشه به اسم build ساختم و به ترتیب این سه دستور رو زدم :


کد   
cmake ..
make
sudo make install

و در آخر، دیدم که KTechLab به لیست نرم افزارهای نصب شده اضافه شده.

در آینده، در مورد این که این نرم افزار چطوره و کجاها به درد میخوره، بیشتر خواهم نوشت. امیدوارم این پست مفید واقع شده باشه، موفق باشید 🙂

Share

پیشنهادهای شما برای پیاده سازی یک ایده سخت افزاری

با سلام. خیلی وقت بود وبلاگ نویسی نکرده بودم و حالا پس از مدتها اومدم که بنویسم! شاید بگید الان که فرجه امتحانات هست و بهتره برم به زندگیم برسم، ولی خب توی همین فرجه هم وقت آزاد فراوان هست.

بگذریم، جادی چند وقت پیش در مورد ایده ای که بشه ازش استارتاپ ساخت صحبت کرد. البته ایده و همچنین پیاده سازی که بعد ها به کار گرفت یا همون استارتاپ بستون، کاملا نرم افزاری و بر پایه وب پیش رفت. حالا چرا من اینجا دارم این مطلب رو مینویسم؟

توی پست های جادی چند مساله جالب به چشم میخوره، اولیش اینه «چی نداریم؟! آیا وسیله ای هست اون کار رو انجام بده؟ اگر نیست، خودم میسازمش». و دومین نکته هم «پیاده سازی ایده و تبدیل کردنش به استارتاپ و حتی تا حدی به پول رسوندنش، اونقدر ها هم که فکر میکنیم سخت نیست». و حتی شاید سومیش این باشه که «معطل نکن، شروع کن به پیاده سازی». خب، حالا بیایم ببینم که من میخوام چی کار کنم؟ جادی به من ایده داد که ایده جمع کنم برای یک محصول سخت افزاری! اما محصولی که بشه به در یک مدت زمان نه چندان کوتاهی پیاده سازیش کرد و بعد ازش به پول رسید (بر خلاف StrongPC که بیشتر فاز تحقیقی داره).

ایده هایی که در ذهن خودم هستن اینان :

  • پیاده سازی یه دستگاه ساده با استفاده از میکروکنترلرهایی که توی بازار موجودند، و روبرو شدن با چالش هایی مثل مطالعه معماری، برنامه نویسی برای ریزپردازنده، طراحی مدارهای واسط و … .
  • پیاده سازی یه دستگاه ساده با استفاده از آردوینو و ماژول هاش
  • پیاده سازی یک دستگاه ساده IoT طور با استفاده از Cubieboard یا رزبری
  • و …

حالا از شماها که این پست رو میخونید، میخوام در این باره کمک بدید. اول این که «دستگاه ساده» چی میتونه باشه (مثلا ساعت؟! تقویم رومیزی؟ سیستم اطفاء حریق و …) و دوم این که با چی و چطوری پیاده سازی بشه. بعد از این که ایده مشخص بشه، مرحله مرحله پیاده سازیش در همین وبلاگ، گزارش میشه.

Share

پروژه گاه‌شمار

خب، من در گروه های تلگرامی این پیام رو میذاشتم :

دوستی مدتی پیش (که خیلی هم ازش نگذشته ) یک چالش رو بعنوان تمرین برنامه نویسی پیشنهاد داد، و اون هم نوشتن یک API بود برای دریافت ساعت و تاریخ.
من هم وارد این چالش شدم و یک API با روبی و سیناترا نوشتم، روی گیتهاب هم قرارش دادم ولی الان دپلویش کردم که اگر شما هم خواستید بتونید ازش استفاده کنید :
https://gahshomar-api.herokuapp.com/

خب، این هم پروژه ای بود که محسن بعنوان تمرین خواست که ما یه API بنویسیم، من هم این رو با Sinatra نوشتم و الان دپلوی شده و در دسترسه! امیدوارم ازش لذت ببرید 🙂

Share

FreeBSD 11.0-RC1 – نخستین دیدار

امروز بعد از مدتها به وبسایت محبوب و معروف دیستروواچ سر زدم و دیدم که یکی از سیستم عامل های محبوبم یعنی FreeBSD یک نسخه نامزد انتشار منتشر کرده!

خب با خوشحالی تمام دانلودش کردم.

اولین چیزی که در FreeBSD 11 برام جالب شد، این بود که توی نصاب خیلی ریز شده بودن و سوال پرسیده بودن، یعنی عمده پیکربندی رو جزئی از نصاب کردن که این خودش یک پوئن مثبت در نوع خودش محسوب میشه. و یک پیشرفت خیلی بزرگ، چون عمده کاربران FreeBSD مدیران سیستم ها هستند، پس این تیپ پیکربندی هنگام نصب بدرد میخوره.

خب، بعد نصب، تصمیم گرفتم اول pkg رو راه بندازم. بعد nano رو نصب کردم (ادیتور محبوب من در CLI ! یه چیز تنبل پسند و عالی!) ، بعدش تصمیم گرفتم دسکتاپ رو راه اندازی کنم. دیدم توی هندبوک، به gnome3 اشاره شده، اونجا بود که فهمیدم احتمالا گنوم شل دوست داشتنیمون هم اومده به FreeBSD . پس gnome3 رو نصب کردم و این خطوط رو به rc.conf افزودم :

کد   
dbus_enable="YES"
hald_enable="YES"
 
#Running GNOME and GDM services
 
gdm_enable="YES"
gnome_enable="YES"

و بعد از یک ریبوت، چشممون به جمال گنوم شل با 3D Acceleration روشن شد :

و این عکس هم به جهت تایید اصالت سیستم عامل :

در مورد این دسکتاپ، که خب یک دسکتاپ مدرن محسوب میشه و تا مدتها در FreeBSD پیداش نبود، میشه گفت که با اضافه شدنش بدون مشکل به سیستم عامل، میتونه به پیشرفت این سیستم عامل در حوزه دسکتاپ کمک کنه. البته، در کل 11 نرم تر از ۹ و ۱۰ بود که قبل تر تست کرده بودم و حتی به عنوان سیستم عامل اصلی ازشون استفاده میکردم.

موفق باشید 🙂

Share

نوشتن اسمبلی ۳۲ بیت

در گذشته، پست هایی که در مورد اسمبلی قرار دادم، همه در مورد اسمبلی ۱۶ بیت بودن اما حالا میخوایم بریم سراغ اسمبلی ۳۲ بیت. خب فرق ۱۶ با ۳۲ بیت در چیه؟!

اولین نکته، سایز ثبات هاست! در ۱۶ بیت در هر ثبات میتونستیم حداکثر یک مقدار ۴ رقمی هگزادسیمال ذخیره کنیم ولی در ۳۲ بیت این مقدار به ۸ رقم میرسه! حالا خیلی مسائل دیگه مثل دیتاباس و کنترل باس و … که بماند (چون اینجا داریم برنامه نویسی میکنیم و بیشتر با ثبات ها کار داریم).

اینجا، قضیه یه فرقای کوچولویی داره، مثلا اسمبلر nasm قراره استفاده بشه (گرچه قبلا در ساخت اون سیستم عامل کوچک ازش استفاده کردیم) و همچنین وقفه ها و system call هایی که استفاده میکنیم شماره و مقدارشون و مکانشون متفاوته.

بیاید این برنامه رو در نظر بگیریم :

کد   
section .text
	global_start
 
_start:
	mov edx, len
	mov ecx, msg
	mov eax, 0x04
	int 0x80
 
	mov eax, 0x01
	int 0x80
 
section .data
	msg db 'Hello, World!', 0xa
	len equ $ - msg

 

خب در بخش اول، تابعی که نیاز داریم فراخوانی کنیم رو تعریف کردیم. بعدش اومدیم start رو نوشتیم. حالا بیاید این بخش رو بررسی کنیم :

کد   
mov edx, len
mov ecx, msg
mov eax, 0x04
int 0x80

اینجا، مقدار طول رشته ای که خواستیم چاپ کنیم رو توی EDX یا رجیستر داده قرار دادیم. بعدش اومدیم پیامی که میخوایم چاپ بشه رو قرار دادیم درو نECX .

بعدش سیستم کال ۴ یا sys_write رو توی eax قرار دادیم و وقفه ۸۰ رو صدا زدیم. حالا وقفه ۸۰ با مقدار ۴ که توی eax ذخیره شده، میگرده دنبال رشته ای که توی ecx هست و بعدش چاپش میکنه.

حالا بخش دوم کد سگمنت رو بررسی میکنیم :

کد   
mov eax, 0x01
int 0x80

اینجا هم مقدار ۰۱ یا sys_exit رو وارد eax کردیم، تا برنامه پس از اجرا، خارج شه. بعد از این هم باز وقفه ۸۰ رو صدا زدیم.

بخش دیتا هم، مثل همه برنامه های قبلی، تمام داده های مورد نیاز رو با Directive ها تعریف کردیم که بتونیم به راحتی توی کد سگمنت ازشون استفاده کنیم و چون قبلا توضیح داده شده، دیگه دوباره کاری نمی کنم. فقط این پست رو نوشتم تا فرقهای اسمبلی ۳۲ و ۱۶ بیت رو ببینیم. که درآینده بسطش خواهم داد به ۶۴ بیت.

امیدوارم که این پست، بدردتون خورده باشه.

موفق و موید باشید!

Share

درآمدی بر پردازنده ها

ALUwithRegister

پس از مدتها تحقیق و بررسی در مورد پردازنده های مرسوم، و همچنین خوندن داکیومنت های مربوط به ساخت و پیاده سازی پردازنده ها، تصمیم گرفتم یک داکیومنت ساده دست و پا کنم، که توی اون از ساده ترین قطعات و بخش های کامپیوتر، به یک پردازنده ساده برسیم که بتونه چند عملیات انجام بده و نتیجه رو ذخیره کنه.

داکیومنت از اینجا قابل دریافت هست.

با تشکر.

Share