|
|
Biên dịch Linux kernel - phần 2
Hướng dẫn chi tiết các bước trong quá trình tái biên dịch Linux kernel cho kernel 2.4.x và 2.6.x.
Chuẩn bị mã nguồn và những điểm liên quan.
<hnd viết cho vninformatics.com>
6.3 Kiểm tra thực tính của mã nguồn
Điều quan trọng khi tải mã nguồn của kernel, nên tải gpg .sign cho phiên bản tương ứng. Mục đích là để kiểm tra thực tính của mã nguồn được tải về. Khi mã nguồn của Linux kernel được công bố, chúng được dồn lại thành một gói .tar và sau đó được nén bằng GNUzip hoặc bzip2, cả hai loại này sau khi được nén đều được tạo "chữ ký" .sign.
Kiểm tra thực tính của mã nguồn được tải về bằng phương pháp kiểm tra "chữ ký" của từng gói mã nguồn là một thói quen cần thiết. Lý do: các mã nguồn mở nói chung được công bố và phổ biến rộng rãi, ai cũng có thể chỉnh sửa (một cách không chính thức và không được nhóm phát triển chính thức cho phép) rồi đưa lên một server nào đó trên Internet. Người dùng tải về, biên dịch và cài trên máy mà không kiểm tra thực tính của chúng (và mã nguồn này có những thay đổi mờ ám) thì hậu quả khó mà lường.
Quy trình kiểm tra "chữ ký" chỉ đơn giản gói gọn trong một dòng lệnh:
$ gpg --verify linux-2.4.26.tar.bz2.sign linux-2.4.26.tar.bz2, trong đó
linux-2.4.26.tar.bz2.sign là "chữ ký" của gói linux-2.4.26.tar.bz2 được tải về từ server chứa mã nguồn Linux kernel
linux-2.4.26.tar.bz2 là gói mã nguồn Linux kernel được nén bằng bzip2
Trước khi có thể kiểm tra thành công bằng lệnh trên, bạn phải có gpg đã cài trong máy, tải và nhập public key của server chứa mã nguồn Linux kernel mà bạn tải về. Chi tiết hướng dẫn cho quy trình này ở:
http://www.kernel.org/signature.html
Quy trình tải mã nguồn Linux kernel và kiểm tra thực tính của mã nguồn này có thể tóm tắt bằng một ví dụ như sau:
# chuyển vào thư mục chứa mã nguồn của máy ở /usr/src là nơi thông thường. Đối với kernel 2.6.x series, bạn có thể dùng thư mục khác tùy ý:
cd /usr/src
# dùng wget để lấy một phiên bản mã nguồn từ server về ở dạng .bz2
wget http://www.kernel.org/pub/linux/kern...6.tar.bz2
# dùng wget để lấy .sign của phiên bản mã nguồn vừa được tải về
wget http://www.kernel.org/pub/linux/kern....bz2.sign
# Dùng gpg với option verify để kiểm thực tính của mã nguồn vừa tải về
gpg --verify linux-2.4.26.tar.bz2.sign linux-2.4.26.tar.bz2
Ngoài phương pháp dùng signature cho vấn đề kiểm chứng thực tính của mã nguồn (không chỉ mã nguồn của Linux kernel) , bạn cũng thấy rất nhiều nơi trên Internet dùng "MD5sum" cho mục đích này (cho đến nay, mã nguồn Linux kernel dùng signature để kiểm chứng, không dùng MD5sum). Quy trình kiểm tra "MD5sum" chỉ đơn giản là một quy trình tạo một "MD5sum" từ mã nguồn được tải về trên máy và so sánh kết quả "MD5sum" này với hồ sơ "MD5sum" được tải về kèm với mã nguồn. Nếu "MD5sum" bạn tạo ra trên máy của mình với cùng gói mã nguồn mà không trùng hợp với "MD5sum" nguyên thuỷ tải về từ server thì thực tính của phần mã nguồn này không đáng tin cậy. Cách tốt nhất là chỉ nên tải mã nguồn ở những địa chỉ phố biến và đáng tin cậy. Cẩn thận hơn nữa (really paranoid), thì so sánh MD5sum với một số server chứa mã nguồn khác nhau.
- Kiểm tra thực tính của mã nguồn bằng MD5 checksum khá đơn giản. Tiện ích md5sum có sẵn hần như trên mọi bản phân phối. Lệnh tạo MD5 checksum đơn giản là lệnh:
# md5sum <file_cần_kiểm_tra>
sẽ tạo ra 1 chuỗi chữ và số tương tự như: 2fe2a5fabcc3a33722b4ffe05714bec3 *<file_cần_kiểm_tra>. Nếu chuỗi này trùng với chuỗi được cung cấp chính thức với mã nguồn thì mã nguồn này có thực tính và đáng tin cậy.
6.4 Xả nén mã nguồn
Tùy vào gói mã nguồn được tải về thuộc dạng nén .gz hay .bz2 mà dùng tiện ích thích hợp để xả nén. Như đã tóm tắt trong phần 6.3 ở trên, gói mã nguồn được chứa trong /usr/src (wget được chạy sau khi cd vào /usr/src), cho nên bạn phải ở trong thư mục này trước khi thao tác các bước kế tiếp (không thì các bước kế tiếp phải thêm và đường dẫn đến nơi chứa gói mã nguồn). Đối với kernel 2.6.x series, mã nguồn của Linux kernel có thể được xả, chứa và biên dịch từ bất cứ nơi đâu mà bạn có quyền chứa trên hệ thống. Tuy nhiên, để giữ cho hệ thống sạch và thống nhất, bạn nên giữ mã nguồn ở /usr/src.
- nếu gói mã nguồn có dạng .gz thì dùng:
$ gunzip linux-2.x.xx.tar.gz (x.xx là bất cứ phiên bản nào bạn tải về).
$ tar xf linux-2.x.xx.tar (lệnh này dùng option x để extract (xả) và f để chỉ định hồ sơ nào cần được xả, ở đây hồ sơ cần được xả là linux-2.x.22.tar).
Hai lệnh trên cũng có thể gọp chung lại như sau:
$ tar xfz linux-2.x.xx.tar.gz (lệnh này dùng thêm option z để ngầm xả nén .gz file "on-the-fly" trước khi xả gói tar).
Hoặc có thể tạo cùng kết quả bằng cách khác nữa:
$ gzip -dc linux-2.x.xx.tar.gz | tar xvf - (cụm lệnh này dùng chương trình gzip để xả nén (option -d) ra stdout (option -c) và "tee" nó qua chương trình tar để xả gói tar ra "on-the-fly". Cả cách này và cách ở trên đều tiện dụng cho những ai eo hẹp dung lượng trên đĩa).
- nếu gói mã nguồn có dạng .bz2 thì dùng:
$ bunzip2 linux-2.x.xx.tar.bz2
$ tar xf linux-2.x.xx.tar
Hai lệnh trên cũng có thể gọp chung lại như sau:
$ tar xfj linux-2.x.xx.tar.bz2 (lệnh này dùng thêm option j để ngầm xả nén .bz2 file "on-the-fly" trước khi xả gói tar).
Hoặc có thể tạo cùng kết quả bằng cách khác nữa:
$ bzip2 -dc linux-2.x.xx.tar.bz2 | tar xvf - (cụm lệnh này dùng chương trình bzip2 để xả nén (option -d) ra stdout (option -c) và "tee" nó qua chương trình tar để xả gói tar ra "on-the-fly". Cả cách này và cách ở trên đều tiện dụng cho những ai eo hẹp dung lượng trên đĩa).
Cả ba trường hợp đều cho kết quả là một thư mục có tên là linux-2.x.xx bên trong thư mục /usr/src/
Trong phần này, chúng ta chỉ đề cập đến trường hợp tải trọn bộ mã nguồn của Linux kernel về để biên dịch. Trường hợp đã có mã nguồn cũ hơn của Linux kernel trên máy và chỉ cần tải patch và "vá" thì có quy trình khác. Vấn đề này sẽ đề cập sau.
6.5 Dùng "config" nào thì thích hợp?
Cấu hình biên dịch nhân Linux đơn giản là một "text file" chứa các biến với giá trị Y (Yes), N (No) hoặc M (Module). Các giá trị này được xử dụng trong quá trình biên dịch; chúng dùng để xác định những gì không được biên dịch, những gì được biên dịch và nếu được biên dịch thì sẽ theo dạng nào.
Tùy vào cách sắp xếp của mỗi Linux bản phân phối, cấu hình biên dịch nhân Linux nằm nhiều nơi khác nhau. Hồ sơ cấu hình theo mặc định của "vanilla" kernel nằm ở ./arch/i386/defconfig (nếu dùng dòng phần cứng IA32 nói chung), các hồ sơ cấu hình khác cho những dòng phần cứng khác nằm ở ./arch/$ARCH/defconfig; trong đó $ARCH là dòng phần cứng của máy. Nếu dùng cấu hình mặc định, không chỉnh sửa thì kernel sẽ được tái biên dịch trọn bộ theo giá trị mặc định và chắc hẳn, kernel này sẽ không thích hợp cho bạn (ngay cả nếu nó được biên dịch thành công). Điều này đi ngược lại mục đích cần tái biên dịch Linux kernel ngay từ đầu. Bạn có thể dùng hồ sơ cấu hình này để khởi đầu và chỉnh sửa giá trị cho thích hợp. Đây là một bước rất khó khăn cho những ai chưa từng đi qua giai đoạn này và không có sẵn một cấu hình biên dịch nhân hoàn chỉnh cho máy.
Cấu hình cho kernel hiện hữu trên máy cũng có thể nằm trong thư mục /boot ở dạng config-2.x.xx nếu bạn dùng kernel do RedHat (hoặc dựa RedHat) và một số bản phân phối khác cung cấp. Bạn có thể an toàn dùng cấu hình này và chỉnh sửa, loại bỏ các chi tiết (driver module) không cần dùng. Nếu hệ thống đã được biên dịch kernel trước đây, bạn có thể tìm thấy cấu hình biên dịch nhân Linux có tên là .config, được lưu trong thư mục <KERNEL_SRC> (nơi trước đây mã nguồn của kernel được xả nén và biên dịch).
7. Chỉnh cấu hình biên dịch nhân Linux
7.1 Thành phần của cấu hình biên dịch nhân Linux
Thành phần trong cấu hình biên dịch nhân Linux cho kernel 2.4.x và 2.6.x có một số tương đồng và dị biệt. Tuy nhiên, quy trình chọn Y, N hoặc M cho các modules vẫn như nhau. Bước chọn lựa và chỉnh liệu cấu hình biên dịch nhân Linux là một bước mất nhiều thời gian nhất, nó cũng là một bước gây nhiều trở ngại nhất nếu chỉnh sửa không hợp lý hoặc thiếu sót.
7.1.1 Thành phần cấu hình biên dịch nhân Linux thuộc kernel 2.4.x series
code Maturity Level Options
Chọn lựa của mục này cho phép dùng các modules / drivers còn ở trạng thái "alpha" (thử nghiệm). Nếu hệ thống làm việc là một máy production, cần tính ổn định cao thì nên tắt bỏ chọn lựa của phần này. Làm như thế sẽ tắt bỏ rất nhiều modules / drivers thuộc dạng "alpha" trong những phần bên dưới. Nếu muốn thử dùng một số modules / drivers ở dạng alpha thì nên cho phép phần này (Y) và cẩn thận khi lựa chọn các modules được biên dịch sau này. Việc chọn lựa các "alpha" drivers ở chế độ mặc định của các kernel trong nhiều bản phân bố Linux là một trong những nguyên nhân chính tạo nên tình trạng bất ổn định trên một số hệ thống Linux. Nếu chọn lựa các driver này một cách cẩn thận, cơ hội va phải tình trạng bất ổn định sẽ giảm thiểu rõ rệt.
Loadable Module Support
Đây là chức năng nòng cốt của Linux kernel (loadable module). Như đã đề cập ở phần tổng quan (phần 1), loadable modules tiện dụng và linh động, cho nên bạn gần như sẽ chọn Y trong trường hợp này. Trong trường hợp bạn cần dùng kernel modules được viết thêm bên ngoài kernel tree chính thức (3rd party modules), bạn phải chọn "enable set version information on all modules symbols" trong mục này. Nếu bạn cần biên dịch trọn bộ các drivers thẳng vào kernel và không dùng modules (vì lý do bảo mật chẳng hạn), bạn có thể chọn N ở đây. Bạn cũng phải chọn "Y" cho trọn bộ các drivers trong cấu hình biên dịch nhân để thích hợp với chọn lựa "N" cho phần Loadable Module Support này.
Processor Type and Features
Phần này có lẽ là phần tối quan trọng trong cấu hình biên dịch nhân Linux. Đây là nơi để chọn đúng CPU đang dùng trên máy. Ngoài ra còn rất nhiều chọn lựa khác nhau cho vấn đền system scheduling, SMP (symetrical multi-processing) nếu máy có nhiều CPU, hỗ trợ số lượng lớn memory có trong máy.... Nếu bạn chon CPU là i386 thì có lẽ sẽ không có sự cố vì i386 là architecture chung nhất (cả Intel và AMD CPU đều chạy với chọn lựa i386). Tuy nhiên, chọn lựa này sẽ không đạt hiệu năng tối đa và thích hợp cho từng loại CPU cụ thể. Nên chọn đúng CPU để bảo đảm hiệu năng của máy và nhất là để tránh trường hợp không thể boot vào Linux sau khi cài kernel mới (vì loại CPU chỉnh định cho kernel không đúng với CPU có trên máy hay nói một cách kỹ thuật, instructions giữa kernel và máy không tương đồng).
General Setup
Mục này cho phép chọn lựa các ứng dụng hỗ trợ cho những thiết bị (cards) trên máy như ISA, PCI, PCMCIA và các chức năng thuộc về vấn đề quản trị năng lượng nâng cấp (Advanced Power Management).
Memory Technology Devices
Phần này cho phép lựa chọn những ứng dụng thiết bị liên hệ đến memory. Nếu bạn dùng các thiết bị như digital camera hoặc các loại compact flash thì bạn nên chỉnh lý phần này cho thích hợp.
Block Devices
Đây là một phần rất quan trọng trong cấu hình biên dịch nhân Linux. Nó bao gồm các chọn lựa cho những thiết bị thông thường và cần thiết như đĩa cứng, đĩa mềm, băng lưu trữ cũng như các thiết bị điều tác (controllers) cho parallel ports và RAID. Hầu như các chọn lựa trong mục này đều cần thiết; đặc biệt là chức năng hỗ trợ initrd cần thiết để tải sẵn các drivers cần thiết ở dạng module trong quá trình boot máy.
Multi-Device support (RAID and LVM)
Phần này chuyên chú đến các chức năng cần thiết cho hệ thống ở cấp độ server. Các chọn lựa ở đây hỗ trợ những thiết bị như RAID và LVM. Nếu máy của bạn hiện đang dùng RAID và LVM thì không thể bỏ qua phần này trong quá trình xác lập cấu hình biên dịch nhân Linux. Chọn lựa trong phần này đòi hỏi phải hiểu rõ nhu cầu dùng những công nghệ thuộc dạng này trên máy. Nếu máy không dùng đến những công nghệ này, bạn có thể an toàn tắt bỏ chúng (dùng N). Nên nhớ, nếu tắt bỏ RAID trong phần này thì phải tắt bỏ chọn lựa RAID trong phần "block devices" ở trên để tránh gặp phải lỗi biên dịch sau này.
ATA/IDE/MFM/RLL support
Phần này bao gồm các chọn lựa và hỗ trợ cho IDE và ATAPI dùng trên các pc-compatible (và trên nhiều architecture khác hiện có trên thị trường). Hầu hết các hệ thống cần các chức năng hỗ trợ trong phần này.
Cryptography Support (CryptoAPI)
Đây là một phần khá mới và lý thú trong mã nguồn của Linux kernel 2.4.x (chỉ được giới thiệu và công bố trong các phiên bản sau này của 2.4.x). Phần này có những lựa chọn thuộc về vấn đề "mã hoá" cho filesystems. Bạn có thể biên dịch các chọn lựa trong mục này và xử dụng (hoặc không) trên máy tùy ý.
Networking Options
Đây là một phần cực kỳ quan trọng trong cấu hình biên dịch nhân Linux nếu bạn muốn máy của mình gắn liền với mạng. Nó bao gồm các chọn lựa cho cả IPv4 và IPv6 networking. Đây cũng là một phần hết sức phức tạp, cho nên, để có thể hiểu rõ và chọn lựa đúng cho hiệu năng tối đa của máy về mặt networking, bạn nên tham khảo rộng rãi các tài liệu về Linux networking, ít nhất là nên đọc các tài liệu kèm theo trong mã nguồn Linux kernel ở <KERNL_SRC>/Documentation/networking/ (thường là /usr/src/linux-2.x.xx/Documentation/networking/).
SCSI Support
Phần chọn lựa cho SCSI ít được những người dùng PC bình thường quan tâm đến vì không mấy ai dùng SCSI cho máy con. Tuy nhiên nếu bạn dùng SCSI card (hoặc SCSI built-in trên motherboard) hoặc dùng CDR/W qua IDE nhưng chạy ở dạng SCSI emulation thì phải điều chỉnh các chọn lựa trong mục này. Điều quan trọng cần nhớ, nếu không dùng tiện dụng initrd, khi chọn lựa SCSI cho một filesystem chạy trên SCSI disk bạn phải biên dịch trực tiếp các chọn lựa cho SCSI vào kernel thay vì dùng dưới dạng module. Nếu không, kernel sẽ treo trong giai đoạn Linux kernel boot vì module hỗ trợ SCSI chưa được load trong giai đoạn này.
Character Devices
Trong mục này có khá nhiều lựa chọn tập trung vào các thiết bị như serial và parellel, mouse, joysticks (để chơi games). Tắt hoặc mở các lựa chọn trong mục này thường ít tạo ảnh hưởng nghiêm trọng.
File Systems
Mục này chứa trọn bộ các chọn lựa liên quan đến file system và các loại file system được hỗ trợ trên Linux (bao gồm các file system thường được hỏi đến như FAT, FAT32, NTFS, ISO cho CD-ROM....). Các file system phụ trợ như NTFS, FAT... có thể được biên dịch như một module cho kernel. Không nên biên dịch các modules cho file system dùng để "mount" trong giai đoạn boot như ext3, jbd mà nên biên dịch thẳng vào kernel (Lý do tương tự như đã đề cập trong phần "SCSI Support" ở trên). Cách này sẽ làm kích thước kernel lớn hơn nhưng sẽ an toàn và đơn giản hơn. Chức năng hỗ trợ initrd có thể dùng để tải các modules cần thiết trong quá trình Linux kernel boot nhưng phải nhớ bật chức năng này lên trong phần block devices. Đây là vấn đề tùy chọn của từng cá nhân.
7.1.2 Thành phần Linux kernel configuration thuộc kernel 2.6.x series
code Maturity Level Options
Phần này tương tự như đã đề cập ở trên cho kernel 2.4.x series
General Setup
Phần này tương tự như đã đề cập ở trên cho kernel 2.4.x series
Loadable Module Support
Phần này tương tự như đã đề cập ở trên cho kernel 2.4.x series
Processor Type and Features
Phần này tương tự như đã đề cập ở trên cho kernel 2.4.x series
Power Management Options
Phần này tương tự như đã đề cập ở trên cho kernel 2.4.x series
Executable File Formats
Đây là một mục riêng biệt trong cấu hình biên dịch nhân của series 2.6.x. Nếu bạn quan tâm đến "a.out", "elf" và "misc", nên nghiên cứu kỹ phần này qua các tài liệu kèm theo với mã nguồn kernel, đặt biệt cho các tiện dụng của "misc" (<KERNEL_SRC>/Documentation/mono.txt, <KERNEL_SRC>/Documentation/binfmt_misc.txt, <KERNEL_SRC>/Documentation/filesystem/proc.txt)
Device Drivers
Đây là một mục mới trong phần cấu hình biên dịch nhân của series 2.6.x. Thật ra device drivers nằm rải rác khắp nơi trong kernel build configuration của series 2.4.x. Ở series 2.6.x, mọi vấn đề liên quan đến "device drivers" được gom lại trong cùng một nhóm. Các chọn lựa thuộc về các thiết bị như graphic card, sound card, USB, SCSI và vấn đề hiệu chỉnh chúng đều tập trung ở đây.
File Systems
Phần này tương tự như đã đề cập ở trên cho kernel 2.4.x series
Security Options
Phần này dành riêng cho các vấn đề về bảo mật của kernel. Cho đến nay vẫn còn đang phát triển, tuy nhiên, đây là phần đầy hứa hẹn cho một Linux kernel mang tính bảo mật cao.
<kết thúc phần 2>. Xem tiếp phần 3 tại /hvaonline/posts/list/87.html.
<hnd, vninformatics.com / diendantinhoc.net - 30/05/2004>
Tác giả : Conmale (hnd) -
Nguồn : www.diendantinhoc.net
|
|
|
Biên dịch Linux kernel - phần 1
Hướng dẫn chi tiết các bước trong quá trình tái biên dịch Linux kernel cho kernel 2.4.x và 2.6.x.
Tổng lược về Linux kernel và những yếu tố cần chuẩn bị.
<hnd viết riêng cho vninformatics.com>
Compile Linux Kernel
1. Tổng quan về Linux kernel trên phương diện tái biên dịch
1.1 Linux kernel và vấn đề tái biên dịch:
Linux kernel là một "modern kernel", nặng tính modular. Từ kernel phiên bản 2.6.x trở đi, có rất nhiều chức năng và mở rộng được đưa vào kernel. Với tinh thần "compile kernel", một yếu tố chính yếu và quan trọng nhất cần ghi nhận đó là tính phân bộ (modularity) của Linux kernel.
Đối với người dùng bình thường, tính modularity này cho phép chọn lựa cách biên dịch các drivers kernel theo dạng modules hay theo dạng biên dịch trực tiếp vào kernel. Thông thường, kernel build configuration cho phép ba chọn lựa: Y, M và N cho mỗi "driver" trong kernel configuration. Có những "driver" không thể compile như một module vì nó phải được load and link trực tiếp ngay khi kernel khởi động. Cũng có những "driver" cho phép chọn như một module và được load trong khi và sau khi kernel được boot. Điểm chính yếu cần nắm bắt trong giới hạn chủ đề "compile Linux kernel" là hiểu rõ tại sao phải chọn M (cho module), Y (cho compile trực tiếp) và N (không dùng) các drivers này.
- Biên dịch trực tiếp vào kernel có nghĩa là các "drivers" này dù có được dùng hay không vẫn được load lên khi kernel khởi tác và tất nhiên nó sẽ chiếm một phần memory. Lợi điểm chính của chọn lựa này là một khi "drivers" đã được compile vào kernel thì không còn phải quan ngại đến tính trung thực của kernel và các driver nữa. Các hệ thống làm việc đòi hỏi tính bảo mật cao không dùng modules mà compile thẳng vào kernel để tránh trường hợp các modules không tin cậy "bị" cài vào kernel lúc nào đó trong quá trình hoạt động của máy. Lợi điểm kế tiếp của chọn lựa này là tính hiệu xuất (rất nhỏ), khi cần driver thì đã có sẵn và không cần ứng tải nữa.
- Biên dịch như các modules cho kernel có nghĩa là chỉ khi nào cần dùng các "drivers" này mới được ứng tải. Lợi điểm của chọn lựa này nổi bật ở khía cạnh xử dụng memory và tài nguyên trên máy. Với lựa chọn này, bạn có thể tạo nên một kernel cực nhỏ và dễ dàng di chuyển cho nhiều mục đích khác nhau. Lợi điểm kế tiếp là khả năng tái biên dịch chỉ một hoặc một số modules nào đó (cần cập nhật chẳng hạn). Tất nhiên để thực hiện chuyện này thì phải thoả mãn tất cả những đòi hỏi về dependency cho system.
1.2 Tóm tắt các bước biên dịch (dành cho những kẻ thiếu kiên nhẫn )
Biên dịch Linux kernel rất đơn giản nếu như đã hiểu rõ các quy trình và các bước thực hiện. Sau đây là các lệnh cần thiết, giả định bạn đã có trọn bộ các công cụ để biên dịch và các công cụ này đúng phiên bản:
1. $ cd /usr/src # chuyển vào thư mục /usr/src, nơi thông thường chứa mã nguồn để biên dịch kernel
2. $ wget http://www.kernel.org/pub/linux/kern...>.tar.bz2 (<KERNEL_SRC> là phiên bản kernel cần biên dịch, ví dụ ở đây tải mã nguồn được nén ở dạng bz2)
3. $ gpg --verify <KERNEL_SRC>.tar.bz2.sign <KERNEL_SRC>.tar.bz2 (xác thực chữ ký và thực tính của mã nguồn)
4. $ bzip2 -dc <KERNEL_SRC>.tar.bz2 | tar xvf - (xả nén gói chứa mã nguồn)
5. $ make xconfig (dùng GUI để điều chỉnh các chọn lựa cho kernel build configuration và lưu trữ configuration)
6. $ make dep clean bzImage (tập họp lệnh để tạo dependencies và includes, tiếp theo là dọn dẹp các objects không cần thiết và kernel image ở dạng nén)
7. $ make modules (biên dịch các modules đã được chọn lựa)
8. $ su (chuyển sang chế độ super user cho lệnh tiếp theo)
9. # make modules_install (cài các modules vào /lib/modules/<KERNERL_SRC>, chỉ có super user mới có thể thực hiện lệnh này)
10. # make install (cài kernel vào máy, bước này bao gồm quy trình cài các hồ sơ cần thiết vào thư mục /boot)
Bước thứ 10 có thể thay thế bằng một loạt thao tác bằng tay (chi tiết ở phần 9.2) nếu như Linux distribution không có sẵn một số công cụ thuộc gói mkinitrd chỉ có trong RedHat distribution và các distribution dựa trên RedHat.
Lưu ý: đối với kernel 2.6.x series, bạn có thể dùng các bước như trên. Tuy nhiên bước "make dep" không cần thiết nữa. Bài viết này bao gồm kernel 2.4.x và 2.6.x series nên có một số chi tiết không cần thiết cho kernel 2.6.x. Tuy vậy, những chi tiết này sẽ không ảnh hưởng đến sự thành công của quy trình biên dịch kernel.
2. Tại sao cần compile lại Linux kernel?
Đối với người dùng đã quen với những hệ điều hành "đóng" thì khái niệm tái biên dịch kernel là một khái niệm hết sức lạ lẫm. Điều này cũng dễ hiểu vì kernel của các hệ điều hành "đóng" hiển nhiên là "đóng" và người dùng bình thường không thể có cơ hội tiếp cận với mã nguồn của kernel cho thao tác quy trình tái biên dịch. Trong khi đó, mã nguồn của Linux kernel hoàn toàn "mở" và đây là phương tiện cũng như động lực tiên quyết cho vấn đề tái biên dịch kernel. Câu hỏi được đặt ra là tại sao lại cần phải tái biên dịch Linux kernel?
Câu trả lời ngắn: không cần nếu như không cần và cần nếu như cần
Câu trả lời dài: có vô số lý do khiến cho người dùng cần phải tái biên dịch Linux kernel. Sau đây là một số trường hợp thường gặp nhất:
a. tái biên dịch kernel để chữa lỗi của kernel. Nếu các lỗi này thuộc về lõi của kernel thì phải vá nguồn của kernel và tái biên dịch nó để sửa chữa các lỗi được công bố.
b. tái biên dịch kernel để nâng cao hiệu năng của kernel. Theo mặc định, các Linux distribution thường kèm một phiên bản kernel biên dịch với hầu hết những thành phần có sẵn để có thể đáp ứng rộng rãi cấu hình hardware (có thể hiện diện trên các máy). Đây là điểm lợi tổng quát lúc khởi điểm. Tuy nhiên, sau khi đã cài thành công và nắm chắc máy có những thiết bị gì (sound card, graphic card, network cards, SCSI card..... ) và biết rõ cần những thành phần nào cho cấu hình của máy thì không có lý do gì phải bao gồm trọn bộ các thứ không cần thiết và không dùng. Đối với kernel 2.4.x, mức độ nâng cao hiệu năng không rõ rệt (ngoại trừ dùng phương pháp test load để đo). Tuy nhiên, từ kernel 2.6.x trở đi, tính hiệu năng qua việc tái biên dịch và điều chỉnh "driver" modules cho kernel tạo hiệu xuất rõ rệt, nhất là trong việc điều chỉnh "thời biểu" (scheduling) của các công tác mà system phải đảm nhiệm.
c. tái biên dịch để loại bỏ những "drivers" không được dùng và có thể gây "hiểu lầm" cho kernel, tạo ra trường hợp máy có những triệu chứng hoạt động thiếu ổn định và hay gây lỗi.
d. tái biên dịch kernel để thử nghiệm một chức năng hoặc một module mình vừa tạo ra. Trường hợp này không nhiều như các trường hợp trên nhưng cũng nằm trong các lý do phổ biến.
3. Cấu trúc và quy định phiên bản của Linux kernel
Phiên bản của Linux có quy định rất đơn giản và dễ nhớ. Vấn đề này cần nắm rõ trước khi chọn một phiên bản nào đó của Linux kernel để vá và biên dịch.
Phiên bản của Linux bao gồm ba nhóm số tách ra bởi các dấu chấm. Ví dụ: 2.4.26
Số thứ nhất: 2 là phiên bản
Số thứ nhì: 4 là chỉ định cho tình trạng phiên bản. Nếu số này là số chẵn, nó chỉ định cho phiên bản ổn định (stable), có thể dùng cho môi trường production. Nếu số này là số lẻ, nó chỉ định cho phiên bản không ổn định, nó thường dùng trong môi trường đang phát triển (development). Các kernel thuộc dạng này thường có nhiều bugs và không ổn định. Nếu dùng các phiên bản này để tìm bugs và thông báo cho nhóm phát triển Linux kernel thì đây là điều rất tốt. Không nên dùng phiên bản development cho môi trường production.
Số thứ ba: 26 là chỉ định cho số hiệu phát hành của một phiên bản Linux kernel. Một phiên bản ổn định của một Linux kernel có thể có nhiều số hiệu phát hành khác nhau.
Đây là các quy định chung cho dạng Linux kernel "vanilla" có nghĩa là ứng dụng cho các phiên bản kernel từ http://www.kernel.org, các phiên bản kernel được điều chỉnh bởi mỗi distribution có những điểm dị biệt. Có nhiều Linux distribution xử dụng số hiệu con (extra-version) cho phiên bản kernel họ đã điều chỉnh. Ví dụ RedHat có những cập nhật phụ cho các kernel như: 2.4.20-8 chẳng hạn. Điều cần nắm ở đây là chỉ nên xử dụng phiên bản ổn định (stable) của Linux kernel (số chẵn ở giữa) cho môi trường production và dùng phiên bản thử nghiệm (development) của Linux kernel (số lẻ) cho môi trường thử nghiệm và phát triển.
4. Đòi hỏi tối thiểu trong việc tái biên dịch Linux kernel
Trước khi bắt tay vào việc tái biên dịch Linux kernel, điều cần thiết là phải có đủ chỗ chứa trên disk. Ít nhất là phải đủ chỗ chứa cho mã nguồn (trước và sau khi xả nén), chỗ chứa để cài kernel và các modules mới sau khi biên dịch.
Đòi hỏi quan trọng khác là phải có một bộ công cụ cần thiết và đúng phiên bản, không thể biên dịch được kernel nếu không thoả mãn yêu cầu này. Phiên bản cho bộ công cụ với mỗi series kernel khác nhau. Nên nhớ, nhóm phát triển kernel yêu cầu bạn phải có đúng phiên bản của các công cụ để đảm bảo việc biên dịch kernel thành công.
4.1 Đòi hỏi cho Linux kernel 2.4.x
Đồ nghề Phiên bản tối thiểu Cách xác định phiên bản có trên máy
Gnu C 2.91.66 # gcc --version
Gnu make 3.77 # make --version
binutils 2.9.1.0.25 # ld -v
util-linux 2.10o # fdformat --version
modutils 2.4.2 # insmod -V
e2fsprogs 1.19 # tune2fs
reiserfsprogs 3.x.0b # reiserfsck 2>&1|grep reiserfsprogs
pcmcia-cs 3.1.21 # cardmgr -V
PPP 2.4.0 # pppd --version
isdn4k-utils 3.1pre1 # isdnctrl 2>&1|grep version
Tham khảo thêm chi tiết các công cụ này và địa chỉ để tải các công cụ cho đúng (ít nhất phải cùng phiên bản đã cung cấp ở trên hoặc mới hơn) trong hồ sơ ./Documentation/changes của mã nguồn kernel bạn đang dự tính biên dịch.
4.2 Đòi hỏi cho Linux kernel 2.6.x
Đồ nghề Phiên bản tối thiểu Cách xác định phiên bản có trên máy
Gnu C 2.95.3 # gcc --version
Gnu make 3.78 # make --version
binutils 2.12 # ld -v
util-linux 2.10o # fdformat --version
module-init-tools 0.9.10 # depmod -V
e2fsprogs 1.29 # tune2fs
jfsutils 1.1.3 # fsck.jfs -V
reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs
xfsprogs 2.1.0 # xfs_db -V
pcmcia-cs 3.1.21 # cardmgr -V
quota-tools 3.09 # quota -V
PPP 2.4.0 # pppd --version
isdn4k-utils 3.1pre1 # isdnctrl 2>&1|grep version
nfs-utils 1.0.5 # showmount --version
procps 3.1.13 # ps --version
oprofile 0.5.3 # oprofiled --version
Tham khảo thêm chi tiết các công cụ này và địa chỉ để tải các công cụ cho đúng (ít nhất phải cùng phiên bản đã cung cấp ở trên hoặc mới hơn) trong hồ sơ ./Documentation/changes của mã nguồn kernel bạn đang dự tính biên dịch.
Nếu phiên bản của các công cụ trên máy cũ hơn các phiên bản đưa ra ở trên, bạn cần phải tải phiên bản mới (đã biên dịch) từ website của distribution nào bạn đang dùng. Bạn cũng có thể chọn cách tải mã nguồn của từng công cụ về biên dịch lại. Cách này mất thời gian hơn rất nhiều và chỉ thích hợp cho những ai đã quen thuộc với vấn đề biên dịch mã nguồn trên Linux. Lợi điểm của cách này là bạn tạo cho mình một bộ công cụ rất "sạch" vì đã biên dịch theo ý, thích hợp với môi trường của máy (và vừa đủ).
Đối với IA64 architecture, bạn cần GCC 64bit compliant compiler, nên tham khảo chi tiết ở:
http://gcc.gnu.org/install/specific.html (nếu bạn may mắn có một con IA64 để thử
5. Xác định cấu hình (hardware) của máy
Phần lớn người dùng bình thường ít khi quan tâm đến cấu hình của máy ngoại trừ có nhu cầu cụ thể. Ngay cả những ai dùng Linux đã lâu và không cần phải tái biên dịch kernel, cũng ít khi quan tâm đến cấu hình hardware của máy. Dù có biết nhiều hay ít về cấu hình hardware của máy mình dùng, bạn vẫn phải thu thập thông tin chính xác của cấu hình trước khi bắt tay vào việc điều chỉnh kernel build configuration.
Giả định mọi chỉnh lý đã ổn định và làm việc tốt đẹp (do installer tự detect trong khi cài Linux hay do bạn phải điều chỉnh lại), bạn cần tái biên dịch Linux kernel và cần thâu thập thông tin về cấu hình của máy, hai lệnh sau cung cấp các chi tiết hardware có trên máy:
# /sbin/lspci để liệt kê trọn bộ những PCI "card" đang gắn vào máy. Lệnh này liệt kê trọn bộ các "card" đang trực tiếp làm việc trên máy, hardware version và model của chúng.
# cat /proc/cpuinfo để xem chi tiết CPU của máy là loại gì. Nếu Linux distribution bạn dùng không dùng /proc filesystem thì bạn có thể dùng lệnh # dmesg để thu thập thông tin về hardware trên máy của mình. Ngoài ra, lệnh lsmod cũng ít nhiều giúp bạn xác định các modules đang được dùng trên máy và tên của các modules này.
Những thông tin thâu thập được ở đây hết sức quan trọng trong giai đoạn điều chỉnh kernel build configuration. Nó giúp bạn xác định các chọn lựa đúng cho cấu hình máy, tránh đi những trở ngại có thể rất mất thời gian sau này.
6. Các bước chuẩn bị
6.1 Tạo một bootable floppy disk dùng kernel đang chạy
Đây là một bước cần thiết đề phòng sự cố gì đó khiến bạn không thể boot vào Linux system sau khi cài kernel mới. Trường hợp này hiếm khi xảy ra trong quá trình biên dịch kernel và cài kernel mới nếu bạn thực hiện và điều chỉnh đúng. Những sự cố với bootloader (LILO hoặc GRUB) ít thấy xảy ra vì bootloader đã được thiết lập hoàn chỉnh trước khi cập nhật kernel. Phần lớn giai đoạn tái điều chỉnh config của LILO hoặc GRUB không chính xác tạo trở ngại. Vấn đề này sẽ được đề cập sau. Trước mắt chúng ta cần tạo một "bootable floppy disk".
Có rất nhiều cách để tạo một bootable floppy lấy từ kernel hiện đang chạy trên máy. Thay vì trình bày nhiều cách khác nhau cho việc tạo bootable floppy disk, ở đây tôi chỉ đề cập đến phương thức đơn giản nhất. Cách dễ nhất có lẽ là cách dùng mkbootdisk. Đây là một binary được cài mặc định trên các RedHat distribution và hầu hết các distribution dựa RedHat. Nếu binary này không hiện diện trên máy, bạn có thể tải mã nguồn về và biên dịch cho distribution mình đang dùng. Chạy lệnh:
# mkbootdisk --device /dev/fd0 `uname -r`, trong đó
`uname -r` là lệnh ngầm để lấy phiên bản kernel hiện dùng trên máy. Nếu không muốn phiên bản này, bạn có thể gõ vào phiên bản nào đó theo ý (tất nhiên là phiên bản kernel này phải hiện hữu trên system).
/dev/fd0 là "device" chỉ cho đĩa mềm thứ nhất trên máy (tương tự như drive A: trên DOS). Bạn phải chọn đúng "device" thì mới có dữ liệu viết vào đĩa mềm mình muốn tạo.
Quy trình này chỉ mất khoảng vài phút. Sau khi tạo bootable floppy disk ở trên, bạn nên dùng nó để thử boot vào Linux trước khi thực hiện các bước kế tiếp. Nên nhớ phải chỉnh BIOS để cho phép máy boot từ A:
Ở trang:
http://www.yolinux.com/TUTORIALS/Lin...Disk.html
có các hướng dẫn tạo disk cấp cứu rất hay. Bạn nên tham khảo thêm nếu trên máy mình dùng không có sẵn mkbootdisk.
6.2 Tải mã nguồn
Mã nguồn của Linux kernel cả stable lẫn development có rất nhiều nơi trên Internet. Nên vào trang trung tâm của Linux kernel ở http://www.kernel.org và tham khảo danh sách "mirrors" để tìm nơi "gần" chỗ mình cư ngụ nhất để tải về. Nơi "gần" không nhất thiết là "gần" theo phương diện địa lý mà nên chọn "gần" nhất dựa trên "ping time". Chịu khó lấy vài địa chỉ trên mirror và ping những địa chỉ này để chọn lấy nơi có ping time ngắn nhất mà download. Bằng cách sẽ giúp bạn đỡ mất thời gian và tiện cho vấn đề chia xẻ băng thông.
Có nhiều cách tải mã nguồn. Bạn có thể dùng browser để tải qua http hoặc dùng một ftp client nào đó để tải qua ftp. Bạn cũng có thể dùng wget để download. Có lẽ đây là cách tiện nhất và nhanh nhất nếu biết rõ địa chỉ và đường dẫn đến gói mình muốn download. Ví dụ:
$ wget http://www.kernel.org/pub/linux/kern...6.tar.bz2 (trong trường hợp này, gói cụ thể cần tải là linux-2.4.26.tar.bz2).
Mã nguồn ổn định của Linux kernel được nén ở hai dạng khác nhau: dạng có đuôi là .gz (dùng GNUzip để nén) và dạng có đuôi .bz2 (dùng bzip2 để nén). Thông thường cả hai tiện ích nén / xả nén trên đều có sẵn trong các Linux distribution thông dụng. Nếu không có sẵn trên máy thì tìm trong trong CD của distribution (tham khảo thêm tài liệu của distribution mình dùng cho cách cài thêm software trên máy) hoặc tải về từ:
- http://www.gzip.org/ cho GNUzip
- http://sources.redhat.com/bzip2/ cho bzip2
<kết thúc phần 1>
Các bạn có thể xem tiếp phần 2 tại /hvaonline/posts/list/64.html.
<hnd, vninformatics.com / diendantinhoc.net - 27/05/2004>
Tác giả : Conmale (hnd) -
Nguồn : www.diendantinhoc.net
|
|
|
Sử Dụng Tiếng Việt Với LaTeX
Bài viết của tác giả Nguyễn Đức Kính gởi cho Diễn Đàn Tin Học.
Để minh hoạ trực tiếp khả năng sử dụng tiếng Việt trong LaTeX, bài viết được giữ nguyên gốc dạng PDF.
Bạn có thể download và đọc bài viết ở đây: http://www.diendantinhoc.net/tute/tiengviet/vnlatex/vntex4win.pdf
Xin cảm ơn tác giả Nguyễn Đức Kính đã cung cấp bài viết này!
File phụ trợ
Các file phụ trợ dùng trong bài viết có thể download theo link cung cấp trong bài viết hoặc ở đây:
- Font .VnTime (dạng Zip - 187Kb) : http://www.diendantinhoc.net/tute/tiengviet/vnlatex/vntime.zip
- GVS & VNTeX (dạng Self-Extract ZIP - 6,37Mb) : http://www.diendantinhoc.net/tute/tiengviet/vnlatex/gvsvntex.exe
Ghi chú: Bài viết đồng thời được lưu trữ ở địa chỉ http://www.diendantinhoc.net/tute/tiengviet/vnlatex/
|
|
|
Xóa mù Linux - Cài đặt và Sử dụng Fedora Core 2
Đây là tài liệu hướng dẫn chi tiết cách cài đặt và sử dụng hệ điều hành Linux, phiên bản Fedora Core 2, dành cho những người chưa hề biết Linux là gì, cũng như những bạn đã có chút kiến thức về Linux.
Tất cả các files liên quan được gói gọn trong gói xmlinux.tbz, các bạn cần download gói này về để thực hiện theo hướng dẫn.
Chúc các bạn vui vẻ với Fedora Core 2 và hẹn gặp lại tại "XMLinux - Hướng dẫn cài đặt và sử dụng Fedora Core 6"
1) Hướng dẫn chi tiết:
http://www.nhatban.net/downloads/xmlinux.pdf
2) Files liên quan:
http://www.nhatban.net/downloads/xmlinux.tbz
Tác giả : Nguyễn Đức Kính
Nguồn : www.nhatban.net
|
|
|
Nhân (kernel) của Linux gồm 5 tiểu hệ thống chính:
1. Bộ phân thời cho tiến trình (Process Scheduler-SCHED):
Như bạn biết về cơ bản PC vẫn là một hệ thống xử lý đơn tức là chỉ có 1 lệnh thực thi tại một thời điểm. Tuy nhiên các hệ điều hành đa nhiệm(multi-task) như Windows, Linux v.v đều cho phép nhiều chương trình chạy cùng một lúc. Làm sao chúng làm được như vậy? Bằng cách chuyển quyền thực thi qua lại giữa các chương trình thật nhanh làm cho chúng ta có cảm giác các chương trình chạy cùng lúc với nhau. Ví dụ bạn vừa đánh Winword vừa chơi Winamp thì thật ra SCHED sẽ chạy Winword 5,10 lệnh xong chuyển qua Winamp 5,10 lệnh rồi chuyển lại v.v Việc này cực kì nhanh nên bạn không có cảm giác gì.
Hệ điều hành MSDOS ngày xưa thật sự là hệ điều hành đơn nhiệm, tuy nhiên bạn vẫn có thể bẩy ngắt 1Ch (hook interrupt) để giả lập đa nhiệm. Interrupt 1Ch thực chất được Timer IRQ (6 hay 8 gì quên mất rồi) gọi. Timer IRQ là một ngắt cứng tức là tín hiệu do bộ phát xung gởi tới CPU. Mặc định là 1/13 giây 1 lần bộ phát xung này gởi 1 tín hiệu IRQ đến CPU. Khi đó CPU sẽ ngưng lệnh đang thi hành chuyển qua xử lý ngắt. Timer IRQ sau đó sẽ gọi ngắt 1Ch. Nếu bạn viết 1 chương trình con hook int 1Ch, thì bạn sẽ có cảm tưởng nó chạy song song với chương trình chính (thật ra 1/13s nó mới chạy 1 lần). Ứng dụng cái này tôi có viết một chương trình chạy banner trong màn hình DOS, hay chương trình ping pong gồm 1 hay nhiều trái tim chạy va đập vào các cạnh của màn hình, trong khi vẫn chạy DOS.
Các hệ điều hành đa nhiệm sau này đều xử dụng nguyên tắc này để làm SCHED. Tuy nhiên 1/13s thì không đủ nhanh để switch qua nhiều tiến trình nhưng xài hàm của BIOS ta có thể tăng tốc cho SCHED 1/100s 1 lần chẳng hạn.
2. Bộ quản lý bộ nhớ (Memory Manager-MM):
Bộ nhớ qui ước (conventional memory) của PC chỉ có 640K thôi. Do chương trình BIOS chỉ quản lý được tới FFFFF, mà vùng nhớ cao (High memory từ A0000 trở lên) dùng để ánh xạ (map) BIOS, Video card memory và các thiết bị ngoại vi khác, vùng nhớ còn xài được (Low memory) là từ 9FFFF trở xuống. Dùng calculator đổi 9FFFF ra decimal bạn sẽ có đúng 640K ). Chắc bạn ngạc nhiên hỏi rằng cây RAM 512M mua hết $70 của tôi biến đâu mất rồi??? Hihihi nó bây giờ teo lại còn có 1 page 64K trong vùng nhớ cao. Tuy nhiên bạn có thể thay đổi ánh xạ để truy xuất hết 512M. RAM card màn hình cũng tương tự như vậy. Ở chế độ bảo vệ (protect mode) của CPU 32bít đưa ra khái niệm virtual memory (bộ nhớ ảo). Lúc này mỗi process được cấp cho 4G virtual memory từ 00000000-FFFFFFFF. Nhưng kernel sẽ giữ 1 table mô tả ánh xạ từng page của virtual memory với physical memory. Physical memory bây giờ bao gồm cả RAM và swap disk space. Tất nhiên là 4G virtual memory không bao giờ được ánh xạ đầy đủ (ánh xạ hết lấy gì cho mấy process khác chạy). Phần lớn mặc dù có đánh địa chỉ , nhưng chỉ khi bạn đọc hoặc ghi lên đó thì kernel mới allocate từ physical memory.
3. Hệ thống file ảo (Virtual File System VFS)
Hệ thống này không chỉ cung cấp truy xuất đến hệ thống file trên harddisk mà còn cho tất cả các thiết bị ngoại vi. Nếu như Triump tất cả là thời trang thì ta có thể nói ở Linux tất cả là file. Ý tưởng này bắt nguồn từ Unix và các hệ điều hành sau này điều thiết lập theo hướng đấy. Đừng quên là trong DOS bạn dùng copy xxx con để in file xxx ra màn hình. Khi đó con là filehandler cho thiết bị xuất chuẩn (console).
4. Giao diện mạng (Network Interface-NET).
Linux dựng săn TCP/IP trong kernel. Do DOS không có cái này nên tác giả chưa hiểu rõ lắm.
5. Bộ truyền thông nội bộ (Inter-process communication IPC)
Cung cấp các phương tiện truyền thông giữa các tiến trình trong cùng hệ thống Linux. Chúng ta sẽ cùng nhau tìm hiểu sau.
Các cấu trúc dữ liệu hệ thống.
Hệ điều hành Linux hoạt động nhờ vào các dữ liệu này
1. Task list (Danh sách tác vụ)
SCHED lưu 1 bộ dữ liệu cho mỗi tiến trình đang hoạt động. Các bộ dữ liệu này làm thành 1 danh sách liên kết gọi là danh sách tác vụ. SCHED còn có 1 con trỏ current để chỉ tác vụ nào đang active. Theo tôi nghĩ thì các dữ liệu này phải có các giá trị của các thanh ghi của process đó ngay lúc nó bị switch. Khi một tiến trình được active trở phải SCHED sẽ khôi phục các giá trị này.
2. Memory map(Ánh xạ bộ nhớ)
Như giải thích ở trên MM cần 1 ánh xạ từ bộ nhớ vật lý cho bộ nhớ ảo 4G của mỗi tiến trình. Ngoài ra còn các thông tin để chỉ cách lấy và thay cho từng trang cụ thể. Tất cả các thông tin này chứa trong memory map và memory map được chứa trong trong task list.
3. I-nodes
VFS dùng i-nodes để định vị các file. Cấu trúc dữ liệu i-nodes dùng để ánh xạ các file block thành các địa chỉ vật lý ở trường hợp đĩa cứng và đĩa mềm là các sector, cyclinder và head.
4. Data connection
Mô tả network connection đang mở
Tất cả các cấu trúc dữ liệu này đều bắt nguồn từ task list. Mỗi 1 process có một con trỏ chỉ tới cấu trúc memory map, 1 con trỏ chỉ tới danh sách các i-node của các file đang mở cho riêng process đó, và 1 con trỏ chỉ tới danh sách các data connection cho tất cả các network connection đang mở.
**************************
Cấu trúc của SCHED
Bây giờ ai cũng biết đây là bộ phận trung tâm của hệ điều hành. Nó chịu trách nhiệm chia sẽ thời gian xử dụng CPU cho tất cả các process , process bình thường cũng như các tiểu hệ thống.
SCHED được chia thành 4 module
1. Module luật định thời (scheduling policy): chịu trách nhiệm phân xử xem process nào được quyền truy xuất CPU. Hệ thống hoạt động có thông suốt hay không nhờ vào bộ luật này, tránh trường hợp 1 process lợi dụng sơ hở của điều luật mà chiếm thời gian hệ thống qua nhiều làm các process khác bị đóng băng (freeze)
2. Module phụ thuộc kiến trúc (architeture-specific): module này gồm các code assembly phụ thuộc vào mỗi loại CPU dùng để suspend hay assume process.
3. Module độc lập kiến trúc (architeture-independent): module gọi các hàm từ module phụ thuộc kiến trúc và module luật để switch giửa các process đồng thời nó còn gọi các hàm ở MM để thiết lập virtual memory cho các process được resume. Nên nhớ module phụ thuộc kiến trúc sẽ khác nhau ở mỗi loại CPU (ỉ386, apha, v.v) nhưng module độc lập kiến trúc thì không đổi kĩ thuật này ai lập trình hướng đối tượng sẽ biết nó là abstract
4. Module hàm gọi hệ thống (system call). Gồm các hàm mà user có thể dùng để tương tác với SCHED. Ai lập trình Linux và Unix sẽ quen với các system call này.
Cấu trúc dữ liệu
Task list: chứa dữ liệu đủ để suspend và resume 1 process. Ngoài ra còn có các dữliệu dùng để thống kê trạng thái hệ thống. Các dữ liệu này được public. Các bạn có thể dùng nó để phân tích hệ thống đang chạy
Cấu trúc MM
MM chịu trách nhiệm điểu khiển tiến trình truy xuất tài nguyên bộ nhớ. Bản thân CPU cũng có một hệ thống quản lý bộ nhớ vật lý mà cho phép ánh xạ giửa bộ nhớ process với bộ nhớ vật lý. MM phải lưu trữ ánh xạ này cho từng process. Thêm vào đó MM còn cho phép swap; nó sẽ di chuyển những trang bộ nhớ không dùng xuống ổ cứng cho phép PC dùng bộ nhớ RAM còn trống.
MM có 3 module
1. Module phụ thuộc kiến trúc: code gọi các lệnh của hệ thống quản lý bộ nhớ của CPU
2. Module độc lập kiến trúc: ánh xạ cho từng process và swap bộ nhớ ảo. Nó cũng quyết định xem phải remove trang nào , load trang nào. Các lập trình viên Linux không thiết kế 1 module policy riêng vì policy cho MM sẽ không thay đổi.
3. System call cho phép các process tác động lên MM bao gồm xin cấp phát vùng nhớ
Cấu trúc VFS
VFS thiết kế để thống nhất cách truy xuất tất cả các thiết bị phần cứng. Ngoài ra VFS còn chịu trách nhiệm load các chương trình thực thi.
Modules
1. Các module thiết bị điều kiển, mỗi một phần cứng sẽ có 1 module thiết bị điều kiển riêng, cái này thường gọi là driver. Linux cũng như các hệ điều hành khác cho phép thêm vào 1 driver mới.
2. Module giao diện độc lập thiết bị. Cái này là abstract cho tất cả các driver
3. Các module hệ thống file logic: Trên thực tế có nhiều hệ thống fiel khác nhau, mỗi hệ thống file có một module điều khiển riêng.
4. Module độc lập hệ thống file: Cái này là abstract không những cho các loại file system mà còn cho tất cả các driver. Ai lập trình driver cho DOS thì có lẽ nhớ chổ này tất cả các driver qui về 2 loại loại block mỗi lần đọc hay ghi đều đi theo block dữ liệu ví dụ nhưng disk và loại kí tự mỗi lần đọc và ghi 1 kí tự như máy in bàn phím v.v
5. Cuối cùng là system call các hàm gọi hệ thống cho VFS
Cấu trúc NET
NET cho phép Linux connect với các hệ thống khác bằng mạng. Ai cũng biết mạng thì rất nhiều loại thiết bị và giao thức mạng. NET abstract tất cả cho phép những phần khác có thể truy xuất qua mạng mà không quan tâm đền các thiết bị và giao thức được sử dụng
NET có 5 module
1. Các Driver cho thiết bị mạng, mỗi module cho mỗi loại thiết bị
2. Module độc lập thiết bị: abstract tất cả các thiết bị mạng
3. Các Module giao thức mạng: mỗi module cho mỗi loại giao thức truyền
4. Module độc lập giao thức mạng: abstract cho tất cả các module giao thức mạng và các driver.
5. System call
Booting (khởi động)Ở đây ta chỉ phân tích cho hệ thống máy tính PC i386 còn các loại khác thì không biết
Có 6 bước khởi động máy tính
1. Chương trình BIOS chọn thiết bị boot
2. Chương trình BIOS đọc bootsector từ thiết bị boot lên bộ nhớ
3. Quyền điều khiển chuyển qua cho chương trình bootsector, chương trình này đọc tiếp phần setup , các chương trình giải nén và kernel image đã được nén
4. Kernel sẽ được giải nén ở trong protected mode
5. Khởi động mức thấp bởi assembly code
6. Khởi động mức cao cho C code
Bước 1: BIOS POST (Khởi động của BIOS)
Theo bản thiết kế đầu tiên của máy tính máy Turing, máy tính là 1 thiết bị cho phép chạy đúng 1 chương trình thôi. Các máy tinh Casio chẳng hạn cũng chạy 1 chương trình calculator. Các máy tinh chạy băng giấy cũng vậy bạn nạp chương trình bằng tay vào chạy kết thúc rồi lại nạp chương trình khác. Bản thân máy PC Pent4 hiện đại nhất cũng vậy cũng chỉ cho phép chạy đúng 1 chương trình thôi. Tuy nhiên chương trình này có khả năng nạp những chương trình khác lớn hơn phức tạp (khác với việc nạp tay như hồi xưa) hơn rồi chuyển quyền điều khiển cho chúng để tiếp tục những dòng lệnh thực thi không ngừng cho đến khi tắt máy tính. Chương trình ban đầu này được gọi là chương trình khởi động, để thuận tiện người ta nạp nó vào con BIOS và gắn chung vào hệ thống PC.
Mục đích của chương trình khởi động là nạp cho được chương trình hệ điều hành (OS). OS sẽ là chương trình lập vô tận (infinite loop) nó chờ lệnh của user để nạp các chương trình ứng dụng , khi các chương trình ứng dụng kết thúc thì quyền thực thị trả về cho OS ... OS lại tiếp tục chờ để nạp chương trình khác. Vậy từ khả năng chỉ chạy được 1 chương trình người ta đã phát minh ra hệ điều hành là 1 chương trình cho phép nạp tự động những chương trình khác giúp cho máy tính có khả năng to lớn hơn.
BIOS -----> OS --------> Application
...................|____________|
a. Khi bật điện, Bộ nguồn sẽ chạy bộ tạo xung (đồng hồ nhịp - tốc độ Hetz của memboard phục thuộc vào đồng hồ này), và tín hiệu POWERGOOD được gởi vào bus báo cho các thiết bị trong PC.
b. Đồng thời đường #RESET của CPU on, CPU khởi động ở real mode(8086)
c. Các thanh ghi %ds=%es=%fs=%gs=0, %cs=0xFFFF, %ip=FFF0
d. Chương trình kiểm tra thiết bị chạy (giá trị RAM chạy vèo vèo trên màn hình)
e. Bảng interrupt được khởi động tại 0
f. Chương trình BIOS Bootstrap Loader chạy qua int 0x19 %dl=dsố hiệu ổ đĩa khởi động. Chương trình này tải track 0 sector 1 (boot sector) lên địa chỉ 0x7C00
Kết luận:
Hột nhưng Linux được xây dựng theo các khái niệm hệ điều hành thông thường thôi, tuy nhiên các programmer của Linux cố gắng phân chia thành nhiều lớp, Lớp sau là abstract cho lớp trước. Cách này cho phép nhiều người khác nhau cùng làm việc trên các phần khác nhau mà hệ thống vẩn đảm bảo tính thống nhất và ổn định.
Okê phần này chủ yếu dịch từ Conceptual Architecture of the Linux Kernel http://plg.uwaterloo.ca/~itbowman/CS746G/a1/. Tức là cấu trúc khái niệm. Chúng ta sẽ đi sâu vào chi tiết ở các phần sau. Không thấy ai đọc và có ý kiến chẳng lẽ mình nói đúng hết hixhixhix, phần này hơi khó đây.
Giài thích:
Ở đây là những từ kĩ thuật về cấu trúc máy tính , tôi không tiện giải thích cặn kẽ vì sẽ tốn rất nhiều thời gian.
Bootsector và phần setupĐĩa cứng và đĩa mềm lưu trữ ghi dữ liệu thành từng rãnh (track) là những vòng tròn đồng tâm. Đầu từ của ổ đĩa không đọc hay ghi 1 bit hay 1 byte dữ liệu mà là 1 đoạn trên 1 track, học hình học ai cũng biết 1 đoạn trên 1 đường tròn gọi là cung (sector). Mỗi sector thường lưu trữ được 512 bytes.
Track đầu tiên còn gọi là track 0 trên đĩa mềm được định vị bằng 1 lổ tròn to tướng. Sector đầu tiên sector 1 của track 0 (đánh số hơi bị kì nhưng phải nhớ) gọi là bootsector vì nó sẽ được BIOS tải lên khi boot. Toàn bộ chương trình khởi động mềm 512bytes nằm trong sector này.
Bây giờ hãy download source code linux kernel 2.4 từ site www.kernel.org khoảng 34M không thôi chép từ đĩa cài đặt Linux cũng được.
Mở file: arch/i386/boot/bootsect.S. Đây là source code viết bằng ngôn ngữ assembly cho Linux bootsector .
Ở đây các programmer Linux chú thích khá kĩ (không như các source code của Vietnam ).
1. Chép 512 bytes bootsector từ vị trí khởi đầu mà BIOS POST tải lên 0x7C0:0 đến ví trí cuối cùng của vùng nhớ qui ước 0x9000:0, rồi jmp tới đó. Chổ này chưa hiểu ý định của người lập trình vì chương trình khởi động của DOS không làm vậy. Có lẽ vùng nhớ 0x7C00 nhanh chóng sẽ bị chép đè bởi các chương trình tải lên sau.
2. Stack được khỏi động tại khoảng giữa của segment 0x9000
3. Khởi tạo bảng tham số ổ dĩa mới (disk parameters table). Phần cứng của ổ đĩa hoạt động phụ thuộc bảng tham số này. Mặc định có bảng tham số nằm trong BIOS, tuy nhiên nhiều BIOS chỉ set chế độ đọc từng sector. Linux programmer set lại chế độ đọc nhiều sector cũng lúc để tăng tốc độ tải HĐH. Bảng tham số này được chép về ngay dưới đoạn stack (stack chạy ngược lên nên bảo đảm không đụng hàng) gồm 12 bytes. Bytes 0x4 là dữ liệu chứa số sector maxium đọc cùng 1 lúc được patch thành 36 36 là số sector trong 1 track của ổ đĩa 2.88M, set cao như vậy nhưng tuy loại ổ đĩa giá trị thực tế sẽ khác; trích từ chú thích của người lập trình high doesn’t hurt but low does.
4. Tính toán số sector trên 1 track. Hồi xa xưa đây là phần nhức đầu với các bác viết bootvirus. Gần như không có cách chính xác cái này với cái xác định FAT12 và FAT16. Tuy nhiên cách giải quyết của mấy tay Linux programmer này cũng hay. Lần lựa đọc các sector cao nhất của ổ đĩa. 36 là 2.88M. 18 là 1.44M thường dùng. 15 là 1.2M đĩa to như bánh tráng và 9 là 760K cũng to như vậy như chỉ có 1 mặt thôi. Có điều nếu đĩa 1.44M bị lỗi tại sector 18, chẳng lẽ Linux lại hiểu nó là 1.2M sao , mà kệ hỏng bất cứ sector nào ở track 0 thì coi như vứt.
Lúc này Linux sẽ in dòng chử : Loading lên màn hình
5. Chương trình setup của Linux nằm ở các sector tiếp theo bootsector sẽ được tải lên ngay sau bootsector: 0x90200. Số sector cho phần setup mặc định là 4. Mỗi lần đọc 1 track nó in dấu chấm ra màn hình.
6. Tiếp theo chương trình system ở dạng nén(compressed kernel image) sẽ được tải ở vị trí 0x10000 - chừa 64K low memory. Kích thước mặc định là 0x7F00 tính theo đơn vị 16-bytes = 508K. Linux còn có chể độ big-kernel khi này kernel image sẽ vượt quá bộ nhớ qui ước 640K. Khi đó trong code của phần setup có hàm bootsect_kludge nằm tại offset 0x220 chịu trách nhiệm tải kernel vào bộ nhớ cao.
7. Kết thúc quá trình tải setup và system, chương trình setup sẽ được thực hiện tại segment 0x9020
Mở file: arch/i386/boot/setup.S. Đây là source code viết bằng ngôn ngữ assembly cho Linux setup.
1. Phần setup này có thể được tải bởi các loader khác nhau bootsect.S chỉ là loader chuẩn của Linux thôi ngoài ra còn còn LILO hay Loadin v.v. Mở đầu setup check xem nó có được tải đầy đủ không. Nên không nó sẽ cố gắng tải lại cho đủ. Nếu vẫn không được nó đành báo lỗi loader sai. Pó tay ...
2. Kiểm tra kích thước bộ nhớ. Nhưng ta đã đề cập bộ nhớ cao của máy tính (từ 640K trở lên) khá phức tạp. Linux dùng 3 cách khác nhau để detect. Cách đầu tiên là E820h, dùng hàm ax=E820, int 15h để kiểm tra. Nếu thất bại dùng hàm ax=E801h, int 15h. Cuối cùng là dùng cách ax=8800h, int 15h đây là cách cổ điển chỉ cho memory dưới 64M.
3. Tiếp theo setup gọi hàm video nằm trong file video.S đây là code assembly để detect chế độ đồ hoạ
4. Lấy disk parameter table của harddisks. Các bảng này nằm trong BIOS, trong quá trình BIOS detect thiết bị hay là bạn set tay trong bảng BIOS. Sau quá trình BIOS POST, vị trí của các bảng này được đặt tại 04 * 41h) cho hd0 và 04 * 46h) cho hd1.
5. Check MCA bus bằng hàm c0h của int 15h
6. Check con chuột PS/2 dùng int 11h
7. Check APM bios: cách này không biết
8. Thiết lập protected mode. Chuyển từ real mode sang protected mode
Protected mode.
Thật khó để định nghĩa protected mode là cái gì. Chúng ta quay trở lại thời kì CPU 8086. 8086 bao gồm các thanh ghi 16 bít (2 bytes).
AX: Accumulate thanh ghi tích lũy vì ax thường lưu giữ kết quả các phép tính toán học.
BX: Base thanh ghi cơ sở vì bx thường dùng để định vị [bx+??]
CX: Count thanh ghi đếm vì cx thường dùng chứa số đếm trong các lệnh loop rep
DX: Data thanh ghi dữ liệu vì dx thường chứa dữ liệu trong phép tinh toán học
SI,DI: source index, destination index-thanh ghi chỉ mục địa chỉ nguồn và địa chỉ đích
SP: stack pointer: thanh ghi con trỏ stack
IP: intruction pointer: thanh ghi con trỏ lệnh
BP: base pointer: thanh ghi con trỏ cơ sở dùng định stack frame trong cấu trúc ngôn ngử bậc cao.
CS: code segment: thanh ghi đoạn lệnh
DS: data segment: thanh ghi đoạn dữ liệu
ES: extra segment: thanh ghi đoạn dữ liệu
SS: stack segment: thanh ghi đoạn stack
Để xác định 1 vị trí trong bộ nhớ cần 2 cặp thanh ghi seg và index:
CS:IP con trỏ đến code sắp thi hành
DS:SI: con trỏ địa chỉ dữ liệu nguồn
ESI: con trỏ địa chỉ dữ liệu đích
SS:SP: con trỏ stack
SS:BP: con trỏ stack frame
8086 sẽ không phân biệt các đâu trên bộ nhớ là code, data hay stack. Nếu CS=DS thì code cũng là data mà data cũng là code. Ngoài ra không có hạn chế gì, bạn tự do đọc thi hành hay thay đổi code, dữ liệu cũng tất cả trong memory. vị dụ kernel của DOS được tải lên ở vùng nhớ 0x40000, bảng Interupt 0x0, đều có thể thay đổi bởi bất cứ 1 chương trình bình thường nào. Rõ ràng 8086 chỉ thích hợp cho hệ thống 1 người dùng.
Bắt đầu từ 80286 CPU 16 bít protected mode rồi 80386 CPU 32 bít protected mode. Tất cả các dòng CPU Intel sau này cho đến Pent IV đều chung kiến trúc protected nên người ta gọi là dòng i386.
Ở chế độ protected mode, bộ nhớ máy tính được bảo vệ chặt chẽ việc truy xuất được phần cứng CPU kiểm soát. Lúc này 1 địa chỉ được xác định bởi 1 thanh ghi segment selector 16 bít và chỉ mục 32 bít.. Có 6 thanh ghi segment selector cs,ss,ds,es,gs,fs.Điểm khác của thanh ghi segment selector và thanh ghi segment ở 8086 ở chổ thanh ghi segment xác định trực tiếp vùng nhớ còn thanh ghi segment selector lại xác định 1 segment descriptor (mô tả đoạn) trong bảng mô tả. Rồi giá trị trong segment descriptor mới giúp chúng ta xác định bộ nhớ vật lý.
Bảng mô tả bộ nhớ:
Bộ nhớ máy tính được chia nhỏ thành nhiều đoạn. Cách thức chia bộ nhớ được mô tả trong 1 bảng mô tả (Nếu bạn không hình dung được thì hãy nhớ đến việc chia đĩa cứng thành nhiều đĩa logic cần bảng partion , bảng này mô tả cách thức chia đĩa). Có 2 loại bảng mô tả - GDT(Global Descriptior Table) và LDT(Local Descriptor Table). Chỉ có 1 bảng GDT được build trong bộ nhớ và vị trí của bảng này được chứa trong thanh ghi gdtr của CPU. Mỗi process sẽ có 1 bảng LDT riêng của nó mô tả cách phân chia riêng cho process đó -tất nhiên cho vùng nhớ mà nó có quyền thôi. Địa chỉ LDT nằm trong thanh ghi ldtr. Mỗi khi swap process ta chỉ cần load lại ldtr thì sẽ có phân vùng bộ nhớ cho process đó ...
Mỗi một đoạn được mô tả bởi 8 bytes trong bảng mô tả. Bao gồm:
1. 32 bít Base: là địa chỉ phẳng của byte đầu tiên của đoạn trong vùng nhớ 4G
2. Cờ G 1 bít: là các định kích thước đoạn 0 là tính theo byte, 1 là tính theo 4096 bytes
3. 20 bít Limit: là kích thước đoạn nếu G=0 thì đoạn có size=1bytes-1Mbyte(2^20) nếu G=1 thì đoạn có size=4K-4G
4. Cờ S 1 bít: S=0: đoạn kernel, S=1: đoạn bình thường
5. 4 bít Type: có các type sau đây: Code, Data, Task State đây là đoạn đặc biệt chỉ có trong GDT dùng để chỉ nơi chứa các dữ liệu liên quan các task. Khi SCHED muốn swap task sẽ đọc trong đây là phục hồi các giá trị của task. Local Descriptor Table đây cũng là đoạn đặt biệt chuyên chưa các LDT của các task và chỉ có trong GDT.
6. 2 bít DPL: Quyền thấp nhất được truy xuất đoạn này. CPU i386 cho 4 mức quyền 0 là cao nhất tương đương với kernel. Còn 3 là User Application. Nếu DPL cho 1 segment là 0 thì user application không thể truy xuất vào đoạn này.
7. Các bít còn lại không dùng.
Các thanh ghi segment selector (cs,ds,ss,es,gs,fs)
Mỗi khi 1 giá trị được set trong 1 thanh ghi segment selector thì CPU sẽ tìm 8 bytes mô tả tương ứng của selector tải vào thanh ghi nội bộ. Vì vậy việc chuyển địa chỉ không cần truy xuất GDT hay LDT 1 cách thường xuyên. Mỗi thanh ghi segment selector có 16 bít trong đó:
1. 13 bít chỉ mục:chỉ 1 mục trong GDT hay LDT
2. Cờ 1 bit TI : 0: đoạn này trong GDT, 1: đoạn này trong LDT
3. 2 bít RPL: Từ 0-3 chỉ mức yêu cầu truy cập đoạn này chỉ có tác dụng với CS Theo tài liệu Intel thì khi 1 process set thanh ghi CS thì RPL có thể nạp với những mức thấp hơn hay bằng mức mà process có quyền. Theo tôi hiểu thì như vậy 1 process kernel có thể chạy 1 đoạn code với quyền thấp hơn ví dụ set RPL=3 chẳng hạn.
Vậy 1 địa chỉ sẽ là Base của đoạn đó + giá trị của thanh ghi chỉ mục (ebx,esi,edi v.v) nhưng theo tôi thường thấy các chương trình 32bít thường set base của tất cả các đoạn =0 hết.
Mục đầu tiên của bảng mô tả luôn toàn là số 0, vì vậy nếu 1 segment selector =0 thì nó sẽ invalid. Do 1 segment selector có 13 bít chỉ mục nên số segment trong bảng mô tả tối đa là 2^13 1 = 8191.
Linux Protected Mode.
Nếu bạn choáng về sự phức tạp của chế độ protected mode (thực ra còn nhiều nữa), thì may mắn cho bạn cho tôi và cho cả lập trình viên Linux là không ai mà implement hết. Giống Windows, Linux cũng làm protected mode đơn giản thôi chỉ có 2 mức 0 cho Kernel và 3 cho User Application. Vấn đề là tương thích với các kiến trúc CPU khác nữa. Tất cả các phân đoạn của Linux dùng GDT không cần LDT. Có duy nhất 1 bảng GDT bao gồm:
1. Null
2. Kernel Code Segment: Chứa code của kernel. Base=0. Limit=0xFFFF. G=1. S=1. Type=A có thể đọc và thi hành (không modify được). DPL=0 Kernel mode only.
3. Kernel Data Segment: Chứa dữ liệu kernel. Base=0. Limit=0xFFFF.G=1.S=1. Type=2 có thể đọc và ghi (không thi hành được). DPL=0
4. User Code Segment: Chứa code segment cho tất cả user proccess. Base=0. Limit=0xFFFF.G=1.S=1. Type=A. DPL=3
5. User Data Segment: Chứa data segment cho tất cả user process. Base=0. Limit=0xFFFF.G=1.S=1. Type=2. DPL=3
6. Default null LDT
7. Ngoài ra còn 4 segment cho APM (advenced power mangement) , 4 segment để dành.
8. Mỗi process sẽ có 1 TSS Segment ở đây: Base lúc này sẽ là địa chỉ của bảng ghi process đó. G=0. Limit=236 vậy mỗi đoạn sẽ có 236 bytes. DPL=0 kernel only. Mỗi process có 1 LDT segment. Default là null để chỉ rằng không dùng LDT. Ai thích dùng thì phải tự viết. GDT có tối đa 2^13 là 8192 mục. Trừ 14 mục system là còn 8178 /2= 4089 process. Như vậy Linux không thể có hơn 4089 proccess.
copy right : vol2
|
|
|
|
|
|
|