Làm cách nào để tạo một hệ thống Linux chạy một ứng dụng?


17

Tôi đang cố chạy một ứng dụng Linux và tất cả những gì tôi muốn chạy là ứng dụng này không khởi động. Tôi cần kết nối mạng và đó là tất cả (không có màn hình, thiết bị ngoại vi, v.v.). Tôi muốn không có ứng dụng nào khác chạy để ứng dụng tôi chạy có 100% CPU. Điều này có thể không?


Nó sẽ không thể lấy 100% CPU khi hệ điều hành của bạn vẫn cần một số tài nguyên.
n0pe

@MaxMackie Rõ ràng, nhưng tôi muốn HĐH chỉ thay mặt ứng dụng (ví dụ cho mục đích kết nối mạng).
dschatz

1
Bạn nhận ra rằng ngay cả với môi trường máy tính để bàn được tải, nhưng ngồi đó không hoạt động, nó không sử dụng bất kỳ thời gian cpu nào phải không? Và ram nó đang sử dụng có thể bị tráo đổi nếu các ứng dụng khác yêu cầu.
psusi

@dschatz Sẽ hữu ích nếu bạn bao gồm nhiều chi tiết hơn trong câu hỏi của bạn. Giống như cho chúng tôi biết thêm về ứng dụng bạn muốn chạy, cách bạn muốn ứng dụng hoạt động và loại phần cứng bạn đang sử dụng.
NN

Nếu có thể, tôi muốn biết tại sao bạn muốn điều này. Theo những gì tôi hiểu, bạn muốn xóa mọi thứ khỏi HĐH (bao gồm bảng điều khiển) chỉ để chạy ứng dụng của bạn. Hiệu suất đạt được sẽ không đáng kể, vậy điểm quan trọng của việc có tất cả là gì?
ngày

Câu trả lời:


13

Tối thiểu CPIO xin chào chương trình thế giới từng bước

nhập mô tả hình ảnh ở đây

Biên dịch một thế giới xin chào mà không có bất kỳ sự phụ thuộc nào kết thúc trong một vòng lặp vô hạn. init.S:

.global _start
_start:
    mov $1, %rax
    mov $1, %rdi
    mov $message, %rsi
    mov $message_len, %rdx
    syscall
    jmp .
    message: .ascii "FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n"
    .equ message_len, . - message

Chúng tôi không thể sử dụng sys_exit, hoặc nếu không thì sự hoảng loạn hạt nhân.

Sau đó:

mkdir d
as --64 -o init.o init.S
ld -o init d/init.o
cd d
find . | cpio -o -H newc | gzip > ../rootfs.cpio.gz
ROOTFS_PATH="$(pwd)/../rootfs.cpio.gz"

Điều này tạo ra một hệ thống tập tin với thế giới xin chào của chúng tôi /init, đây là chương trình người dùng đầu tiên mà kernel sẽ chạy. Chúng tôi cũng có thể đã thêm nhiều tệp vào d/và chúng có thể truy cập được từ /initchương trình khi kernel chạy.

Sau đó cdvào cây nhân Linux, xây dựng như bình thường và chạy nó trong QEMU:

git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux
git checkout v4.9
make mrproper
make defconfig
make -j"$(nproc)"
qemu-system-x86_64 -kernel arch/x86/boot/bzImage -initrd "$ROOTFS_PATH"

Và bạn sẽ thấy một dòng:

FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR

trên màn hình giả lập! Lưu ý rằng nó không phải là dòng cuối cùng, vì vậy bạn phải nhìn xa hơn một chút.

Bạn cũng có thể sử dụng các chương trình C nếu bạn liên kết chúng tĩnh:

#include <stdio.h>
#include <unistd.h>

int main() {
    printf("FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n");
    sleep(0xFFFFFFFF);
    return 0;
}

với:

gcc -static init.c -o init

Bạn có thể chạy trên phần cứng thực với bật USB /dev/sdXvà:

make isoimage FDINITRD="$ROOTFS_PATH"
sudo dd if=arch/x86/boot/image.iso of=/dev/sdX

Nguồn tuyệt vời về chủ đề này: http://landley.net/wr/rootfs-howto.html Nó cũng giải thích cách sử dụng gen_initramfs_list.sh, đó là một tập lệnh từ cây nguồn Linux để giúp tự động hóa quy trình.

Bước tiếp theo: thiết lập BusyBox để bạn có thể tương tác với hệ thống: /unix/2692/what-is-the-smallest-possible-linux-im THỰCation / 203902#203902

Đã thử nghiệm trên Ubuntu 16.10, QEMU 2.6.1.


3

bạn có thể khởi động kernel với init=/path/to/myapptham số được xác định trong bộ tải khởi động của bạn.


2
Đây là một giải pháp khá cực đoan. Thay thế tập lệnh khởi động bằng ứng dụng người dùng sẽ giúp ứng dụng chạy mà không cần kết nối mạng, không có bất kỳ hệ thống tập tin nào ngoài rootfs được gắn (không có sysfs hoặc Proc hoặc tmpfs) và có thể một số nút thiết bị sẽ không được tạo.
mùn cưa

2
@sawdust: Hoàn toàn đồng ý. Nhưng câu hỏi cũng hơi cực ... :-)
Michał rajer

2

Có vẻ như bạn đang cố gắng thiết lập một ki-ốt . Hầu hết các hướng dẫn trên Internet tập trung vào một trình duyệt web như Firefox là ứng dụng duy nhất chạy. Hãy xem hướng dẫn này cho ý tưởng.


2
Hmm, tôi thực sự chỉ đang cố gắng chạy một ứng dụng duy nhất với mạng. Tôi không muốn bất kỳ X và càng ít ứng dụng khác chạy càng tốt. Tôi không thấy cách này hạn chế tất cả các trình tiện ích không cần thiết chạy.
dschatz

ứng dụng có thể chạy mà không có X mặc dù?
Journeyman Geek

2

Bạn chắc chắn có thể chạy chỉ một ứng dụng người dùng sau khi khởi động kernel. Nhưng nó sẽ không có 100% CPU vì sẽ có một số quy trình liên quan đến nhân khác phải tồn tại. Điều này thường được thực hiện trong các thiết bị nhúng Linux, ví dụ như bộ định tuyến không dây. Tôi cũng có kinh nghiệm trực tiếp làm điều này cho một ứng dụng đa luồng.

Khi kernel đã khởi động, tập lệnh khởi tạo hoặc khởi động sẽ được chạy. Đọc về runlevels Linux và quá trình init. Có nhiều chương trình khởi động khác nhau được sử dụng, vì vậy không thể cụ thể. Nhưng Linux sẽ cho phép bạn định cấu hình chính xác những ứng dụng và trình tiện ích nào sẽ thực thi cho tình huống của bạn. Khác với tệp khởi động ở gốc, các tệp cần sửa đổi nằm trong / etc và đặc biệt là /etc/init.d

BTW trừ khi bạn là người lập trình siêu lập trình hoặc trước khi bạn chạy máy chủ GDB từ xa, bạn sẽ cần một số bảng điều khiển gỡ lỗi (bảng điều khiển PC hoặc cổng nối tiếp) cho ứng dụng của bạn. Điều này sẽ cho phép bạn được thông báo về lỗi seg, lỗi bus và lỗi xác nhận. Vì vậy, kế hoạch có một số "ngoại vi" bên cạnh "mạng".


1

Có một số ứng dụng hệ thống phải được chạy, ngoài chúng, chắc chắn, bạn có thể dành phần còn lại của tài nguyên máy tính cho ứng dụng đó. Để có mức tối thiểu, bạn có thể xem các bản phân phối Linux thực sự nhỏ như TinyCore Linux, v.v.

Ngoài ra, nó cũng phụ thuộc vào chính ứng dụng, những dịch vụ nào nó yêu cầu ngoài mạng, v.v.

Tôi nghĩ rằng nếu bạn có thể cung cấp thông tin cụ thể hơn, bạn sẽ nhận được phản hồi chi tiết hơn.

Giống như những loại ứng dụng, vv


Ứng dụng của tôi sử dụng thư viện pthread để chạy một số khối lượng công việc đã đọc (hoạt động số học) và có thể được hướng dẫn thực hiện các phép tính khác nhau dựa trên đầu vào từ tcp / ip. Nhìn vào TinyCore Linux, nó khởi động vào một môi trường máy tính để bàn đầy đủ, điều mà tôi không muốn.
dschatz

TinyCore có một người anh em nhỏ hơn tên là MicroCore. Không có GUI, hãy kiểm tra nó.
n0pe

1
@MaxMackie Tôi thực sự muốn không có giao diện nào trên máy ngoài ngăn xếp tcp / ip. Ứng dụng có thể chặn trên một cổng và có thể được điều khiển thông qua các gói tcp được gửi đến cổng đó.
dschatz

1
Tôi muốn giới thiệu một môi trường có ít dịch vụ đang chạy (kiểm tra điều này linuxhelp.blogspot.com/2006/04/ Khăn ) và hầu như không có gì khác ngoài ứng dụng của bạn và nó phụ thuộc vào nó.
n0pe

1
@dschatz tốt, sau đó bạn cần hack kernel, xóa mọi thứ khác và biên dịch ứng dụng của bạn vào đó. không bash không có gì khác. chỉ cần ứng dụng của bạn..lol.
bakytn

1

Nếu bạn thực sự không muốn gì ngoài nhân Linux, mạng và ứng dụng của mình, cách duy nhất để làm điều đó là:

  • Bạn sẽ cần phải biến ứng dụng của mình thành một mô-đun hạt nhân - đảm bảo nó được gỡ lỗi và được kiểm tra tốt. Mô-đun hạt nhân này sẽ phải khởi tạo những thứ thường được thực hiện thông qua không gian người dùng, chẳng hạn như đặt địa chỉ IP giao diện và tất cả những thứ tốt.
  • Bạn sẽ cần tải xuống và định cấu hình ( make menuconfig) kernel tùy chỉnh của riêng bạn và xóa tất cả các tính năng không liên quan đến việc chạy hệ thống và kết nối mạng. Bạn sẽ muốn vô hiệu hóa để chặn lớp, tôi không biết làm thế nào để thực hiện điều này trên các nhân gần đây make menuconfig.
  • Sau đó, bạn cần đưa mô-đun của mình vào kernel để nó được đưa vào như một phần của kernel và không phải là mô-đun có thể tải. Bạn có thể sẽ vô hiệu hóa các mô-đun có thể tải trong bước trên. Nếu bạn biết đủ C / C ++ để tạo mô-đun hạt nhân, điều này sẽ dễ dàng cho bạn.
  • Bạn cần sửa đổi bất kỳ phần nào của kernel gây hoảng loạn nếu initkhông thực hiện được điều đó hoặc sẵn sàng sống với 1 quá trình không gian người dùng bổ sung.

Tôi biết các mô-đun hạt nhân có thể tạo các quy trình - một đơn giản ps auxsẽ hiển thị nhiều trên một hệ thống điển hình (tất cả chúng đều nằm trong ngoặc). Bạn có thể muốn mô-đun của bạn tạo ra một quá trình hạt nhân. Để loại bỏ tất cả các quy trình do kernel tạo ra bên cạnh quy trình của bạn, bạn sẽ cần phải vô hiệu hóa các luồng [ kthreadd], quản lý năng lượng [ pm], lớp sự kiện [ events] và các quy trình khác.


Nếu bạn muốn thiết lập thực tế hơn quá trình không gian người dùng kernel + 1, điều đó là có thể.

Linux có một tùy chọn dòng lệnh kernel được gọi init=- đây là những gì kernel sẽ bắt đầu khi tải xong. Chương trình phải nằm trên thiết bị gốc được chỉ định bằng root=hoặc trong initrd (được tải bởi bộ tải khởi động của bạn).

Nếu chương trình này thoát, Linux sẽ hoảng loạn, vì vậy hãy chắc chắn rằng nó không bao giờ thoát.

Nhiều bản phân phối hiện đại của Linux đã thiết lập nó để một initchương trình trong initrd thực hiện một số khởi tạo không gian người dùng bổ sung, trước khi bắt đầu /sbin/inithoặc /sbin/systemd. Bạn sẽ phải tìm hiểu bản phân phối của bạn làm gì ở đây (thông tin cho Debian có ở đây ) và tìm nơi bạn có thể chỉ định chương trình "bàn giao" cuối cùng, và từ đó bạn có thể yêu cầu nó khởi động ứng dụng của mình thay vì inithoặc systemd.

systemdquản lý rất nhiều chức năng cơ bản, như xây dựng /dev, đặt tên máy chủ và những thứ khác, vì vậy nếu bạn linh hoạt, bạn có thể muốn xem xét cấu hình systemdđể sinh ra một quy trình duy nhất và tùy chọn khởi động lại nếu thất bại. Nếu tôi không nhầm thì về cơ bản nó sẽ thực hiện điều này cho chế độ một người dùng hoặc khôi phục - nó khởi động một trình bao.

Bạn sẽ có 2 quy trình đang chạy ( systemdvà chương trình của bạn) nhưng hệ thống sẽ không hoảng loạn nếu chương trình của bạn thoát hoặc gặp sự cố.

Cũng xem xét đơn giản là một bản cài đặt nhẹ của Debian - bản cài đặt "netinst" không chạy nhiều ngoài kernel, shell và một vài dịch vụ - hoặc xem xét OpenWRT / LEDE - nó có một máy chủ web cho Luci chạy theo mặc định và một vài dịch vụ khác nhưng dễ bị vô hiệu hóa

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.