2013-02-08 42 views
8

Tôi có một hệ thống lớn được viết chủ yếu bằng C đang chạy trong không gian người dùng cho đến bây giờ. Bây giờ tôi cần biên dịch mã như một mô-đun hạt nhân. Để làm được điều đó, tôi nên ít nhất viết lại mã và thay thế các hàm như malloc, calloc, free, printf tương đương với hạt nhân của chúng, bởi vì chúng chỉ là các hàm không gian người dùng. Tuy nhiên, vấn đề là tôi không có mã nguồn cho một số thư viện được tạo tùy chỉnh được sử dụng trong hệ thống, và các thư viện đó gọi malloc vv bên trong các chức năng của chúng. Vì vậy, về cơ bản, tôi có thể cần phải reimplement toàn bộ thư viện.Nhập mã vùng người dùng vào không gian hạt nhân

Bây giờ câu hỏi: nó sẽ là một hack thực sự bẩn, nếu tôi muốn viết thực hiện riêng của tôi về malloc như là một wrapper quanh kmalloc, một cái gì đó như thế này:

void *malloc(size_t size) { 
    return kmalloc(size, GFP_USER); 
} 

Sau đó, liên kết thực hiện này vào hệ thống mã sẽ loại bỏ tất cả biểu tượng Không xác định trong mô-đun lỗi.

Thực ra tôi nghĩ rằng đây sẽ là một vấn đề phổ biến và ai đó đã viết một trình bao bọc kmalloc như vậy, nhưng tôi đã googling được vài ngày và không tìm thấy gì hữu ích. EDIT: Lý do để làm điều này là hệ thống tôi đang nói đến là một ứng dụng thời gian thực chạy trên hệ điều hành thời gian thực VxWorks và bây giờ chúng tôi muốn chuyển nó sang Linux RTAI, nơi các ứng dụng chủ yếu chạy trong hạt nhân không gian. Nhưng tôi đoán có khả năng có thời gian thực trong không gian người dùng, vì vậy, tôi có lẽ nên làm như Mike đề xuất và tách mã thành các phần hạt nhân và không gian người dùng và liên lạc giữa chúng với bộ nhớ dùng chung.

+0

Tôi vừa thấy [hack này] (http://stackoverflow.com/a/14728092/912144) cho gcc có thể hữu ích cho bạn. – Shahbaz

+9

Thông thường mọi người cố gắng di chuyển mọi thứ ra khỏi hạt nhân, thay vì theo cách khác. Kinh nghiệm cá nhân của tôi là nếu bạn nghĩ rằng bạn cần tạo một mô-đun hạt nhân của chương trình, thì có thể bạn đang làm sai. –

+0

@JoachimPileborg có lẽ anh ta đã nghĩ đến điều này sẽ nhanh hơn trong không gian hạt nhân – Ulterior

Trả lời

8

Tôi chưa bao giờ thấy điều này được thực hiện trước đây. Tôi đã phải làm một cái gì đó tương tự tại một công việc trước đó (trong điện thoại của chúng tôi, vì lý do tiết kiệm điện năng, chúng tôi đã phải chuyển một phần mã từ không gian người dùng từ nhân), nhưng đó là cách tôi đã làm .. Tôi đã một phần của mã và di chuyển nó, và một phần nhỏ ở đó.

Khi tôi đã làm điều đó tôi đã thay đổi không gian sử dụng cuộc gọi đến hạt nhân cuộc gọi vì một số lý do hai người chính:

  1. Nó được ít gây nhầm lẫn như vậy (những người khác nhìn vào mã không có để tự hỏi tại sao tôi gọi "malloc" từ hạt nhân)

  2. mallockmalloc không hoạt động chính xác như cũ. Ý của tôi là:

    2a. kmalloc có tham số flags, trong ví dụ trên bạn đã mã hóa nó. Điều gì sẽ xảy ra nếu bạn quyết định sau đó rằng bạn muốn thay đổi nó ở một số nơi chứ không phải những người khác? (giả sử bạn có một số địa điểm khác nhau nơi bạn nhận được bộ nhớ động).

    2b. kmalloc không cung cấp cho bạn bộ nhớ giống như cách malloc. malloc() sẽ cung cấp cho bạn số byte bạn chuyển vào là size_t size. Mặt khác, kmalloc() là hạt nhân và do đó xử lý bộ nhớ vật lý của hệ thống, chỉ có sẵn trong các khối có kích cỡ trang; do đó, khi bạn gọi kmalloc(), bạn sẽ chỉ nhận được một số mảng byte được xác định trước, cố định. nếu bạn không biết điều này, bạn có thể yêu cầu chỉ trên một đoạn cụ thể và do đó nhận được nhiều bộ nhớ hơn mức bạn cần ... một cổng trực tiếp của mã của bạn sẽ không bảo vệ bạn khỏi điều đó.

    2c. Các tệp tiêu đề cũng phải thay đổi. Rõ ràng bạn không thể bao gồm <stdlib.h> trong hạt nhân, vì vậy chỉ vì bạn "gói" cuộc gọi malloc, bạn vẫn phải thay thế các tệp tiêu đề thay thế.

dụ nhanh chóng của quan điểm của tôi trong 2b trên:

void * stuff; 
stuff = kmalloc(1,GFP_KERNEL); 
printk("I got: %zu bytes of memory\n", ksize(stuff)); 
kfree(stuff); 

Để hiển thị số tiền thực tế của bộ nhớ phân bổ:

[90144.702588] I got: 32 bytes of memory 

anyway ... về mặt kỹ thuật, làm thế nào bạn mô tả nó, nên làm việc tốt. Cả hai đều lấy size_t và trả lại void * để nó hoạt động; nhưng hãy lưu ý rằng càng có nhiều mã bạn chuyển vào hạt nhân thì những thứ ít xác định trở thành và malloc() < =>kmalloc() không giống như 1: 1.

0

Cố gắng làm cho mã RTAI của tôi có thể được compilable trong cả không gian người dùng và hạt nhân (cũng như làm việc với POSIX), tôi đã phát triển URT mà về cơ bản là những gì bạn đang yêu cầu. Đó là một mức trừu tượng nhẹ trên các hệ thống thời gian thực (và thậm chí trên các không gian người dùng không phù hợp so với các hàm RTAI không gian hạt nhân).

Các vấn đề liên quan