Home Php C# Sql C C++ Javascript Python Java Go Android Git Linux Asp.net Django .net Node.js Ios Xcode Cocoa Iphone Mysql Tomcat Mongodb Bash Objective-c Scala Visual-studio Apache Elasticsearch Jar Eclipse Jquery Ruby-on-rails Ruby Rubygems Android-studio Spring Lua Sqlite Emacs Ubuntu Perl Docker Swift Amazon-web-services Svn Html Ajax Xml Java-ee Maven Intellij-idea Rvm Macos Unix Css Ipad Postgresql Css3 Json Windows-server Vue.js Typescript Oracle Hibernate Internet-explorer Github Tensorflow Laravel Symfony Redis Html5 Google-app-engine Nginx Firefox Sqlalchemy Lucene Erlang Flask Vim Solr Webview Facebook Zend-framework Virtualenv Nosql Ide Twitter Safari Flutter Bundle Phonegap Centos Sphinx Actionscript Tornado Register | Login | Edit Tags | New Questions | 繁体 | 简体


2 questions online user: 13

0
votes
answers
42 views
+10

copy_to_user在char設備讀取函數中返回一個錯誤

0

我爲我的內核模塊實現了一個char設備併爲其實現了一個讀取函數。讀函數調用copy_to_user將數據返回給調用者。我最初以阻塞的方式實現了讀取功能(使用wait_event_interruptible),但即使以非阻塞方式實現讀取,問題也會再現。我的代碼在MIPS處理器上運行。copy_to_user在char設備讀取函數中返回一個錯誤

用戶空間程序打開char設備並讀入堆棧中分配的緩衝區。

我發現的是偶爾copy_to_user將無法??複製任何字節。此外,即使我用(僅用於檢查......我知道這不是正確的做法)調用替換copy_to_user,然後立即打印目標緩衝區,我看到memcpy失敗複製任何字節。

我真的不知道如何進一步調試 - 我如何確定爲什麼內存不被複制?流程上下文有可能是錯誤的嗎?

編輯:下面是一些僞代碼概述了代碼目前的樣子:

用戶模式(重複運行):

char buf[BUF_LEN]; 
FILE *f = fopen(char_device_file, "rb"); 
fread(buf, 1, BUF_LEN, f); 
fclose(f); 

內核模式:

char_device = 
    create_char_device(char_device_name, 
     NULL, 
     read_func, 
     NULL, 
     NULL); 

int read_func(char *output_buffer, int output_buffer_length, loff_t *offset) 
{ 
    int rc; 
    if (*offset == 0) 
    { 
     spin_lock_irqsave(&lock, flags); 

     while (get_available_bytes_to_read() == 0) 
     { 
      spin_unlock_irqrestore(&lock, flags); 
      if (wait_event_interruptible(self->wait_queue, get_available_bytes_to_read() != 0)) 
      { 
       // Got a signal; retry the read 
       return -ERESTARTSYS; 
      } 

      spin_lock_irqsave(&lock, flags); 
     } 

     rc = copy_to_user(output_buffer, internal_buffer, bytes_to_copy); 

     spin_unlock_irqrestore(&lock, flags); 
    } 
    else rc = 0; 

    return rc; 
} 
+1

你的代碼有問題,但你不顯示它。 – Tsyvarev

+0

@Tsyvarev添加了一些僞代碼,希望能夠說明代碼所做的工作。不幸的是,我還沒有能夠縮小到一個小的,再現的例子。 – YSK

+0

@YSK你已經聲明瞭兩次'int rc'。從'int rc = copy_to_user(output_buffer,internal_buffer,bytes_to_copy)''行中刪除'int'。 – Gaurav

沙发
0
0

它進行了相當多的調試,但最終Tsyvarev的提示(關於不採用自旋鎖調用copy_to_user的評論)似乎是原因。

我們的程序有一個後臺線程,偶爾會啓動一個新進程(fork + exec)。當我們禁用此線程時,一切運行良好。我們擁有的最好理論是,fork使我們所有的內存頁面都可以在寫入時進行復制,所以當我們試圖複製它們時,內核必須做一些無法使用自旋鎖執行的工作。希望它至少有一定意義(儘管我已經猜到這隻適用於子進程,並且父進程頁面仍然是可寫的,但是誰知道......)。

我們重寫了我們的代碼,使其無法鎖定,問題消失。

現在我們只需要驗證我們的無鎖代碼在不同的架構上確實是安全的。易如反掌。

0
votes
answers
45 views
+10

特拉維斯MIPS交叉編譯

3

如何設置一個.travis.yml爲MIPS目標交叉編譯?對於PowerPC,這是微不足道的:特拉維斯MIPS交叉編譯

addons: 
    apt: 
     packages: 
     - gcc-powerpc-linux-gnu 

由於我有權訪問軟件包directly

對於MIPS我無法在Ubuntu忠實的找到一個編譯器爲它:

即使它似乎被列入白名單:

看來我需要一個更新的Ubuntu圖像(上特拉維斯不可能):

的替代的解決方案將是使用一些預建立MIPS編譯器,例如:

但文件明確地,而不是說緩存那些事:

大文件是安裝迅速,但是進展緩慢,下載做 受益於高速緩存,因爲他們採取只要從緩存 從下載原始來源:

  • Android SDK
  • Debian軟件包
  • JDK軟件包
  • 編譯的二進制文件
  • 泊塢窗圖像

你如何安裝Ubuntu默認特拉維斯圖像上的MIPS交叉編譯?


更新我嘗試了天真的解決方案:

addons: 
    apt: 
    sources: 
    - debian-sid 
    packages: 
    - gcc-mips-linux-gnu 

但這種失敗:

dpkg-deb: error: archive '/var/cache/apt/archives/gcc-7-base_7.2.0-18_amd64.deb' has premature member 'control.tar.xz' before 'control.tar.gz', giving up 
dpkg: error processing archive /var/cache/apt/archives/gcc-7-base_7.2.0-18_amd64.deb (--unpack): 
subprocess dpkg-deb --control returned error exit status 2 

看來dpkg在Ubuntu /忠實的將不支持這些DEB文件:

沙发
0
1

看來我不能使用基於的,因爲這個要求的容器,我放棄了,只是用:

sudo: true 
dist: trusty 

addons: 
    apt: 
    packages: 
    - u-boot-tools 

before_install: 
    - sudo add-apt-repository -y "deb http://archive.ubuntu.com/ubuntu/ xenial main universe" 
    - sudo apt-get -qq update 
    - sudo apt-get install -qq gcc-mips-linux-gnu 

我仍然一個事實,即gcc-mips-linux-gnu是明確列入白名單的興趣。