在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何區(qū)分xenomai、linux系統(tǒng)調用/服務

Linux閱碼場 ? 來源:Linux閱碼場 ? 作者:Linux閱碼場 ? 2022-05-10 10:28 ? 次閱讀

一、如何區(qū)分xenomai、linux系統(tǒng)調用/服務

1. 引出問題

上一篇文章xenomai內核解析--雙核系統(tǒng)調用(一)以X86處理器為例,分析了xenomai內核系統(tǒng)調用的流程,讀了以后可能會覺得缺了點什么,你可能會有以下疑問:

  1. 系統(tǒng)中的兩個內核都是POSIX接口實現(xiàn)系統(tǒng)調用,那么我們用POSIX接口寫了一個應用程序,怎樣知道它調用的內核,或者如何區(qū)分這個應用是cobalt內核的應用,而不是普通linux應用?

  2. 對于同一個POSIX接口應用程序,可能既需要xenomai內核提供服務(xenomai 系統(tǒng)調用),又需要調用linux內核提供服務(linux內核系統(tǒng)調用),或者既有l(wèi)ibcobalt,又有glibc庫,他們是如何實現(xiàn)和區(qū)分的?

    ade56f4e-cff5-11ec-bce3-dac502259ad0.png

2. 編譯鏈接

對于問題1,答案是:由編譯的鏈接過程決定,鏈接的庫不同當然執(zhí)行的也就不同,如果普通編譯,則該應用編譯后是一個普通linux運用。如果要編譯為xenomai應用,則需要鏈接到xenomai庫。但是我們應用程序調用的代碼函數symbol完全一樣,我們會有疑惑xenomai是如何貍貓換太子的?首先鏈接是通過符號表(symbol)來鏈接的,當然也就要從代碼符號(symbol)入手,首先來看一個常用的編譯xenomai 應用的makefile:

XENO_CONFIG := /usr/xenomai/bin/xeno-config
PROJPATH = .
CFLAGS := $(shell $(XENO_CONFIG)   --posix --alchemy --cflags)LDFLAGS := $(shell $(XENO_CONFIG)  --posix --alchemy --ldflags)INCFLAGS= -I$(PROJPATH)/include/

EXECUTABLE := rt-app
src = $(wildcard ./*.c)obj = $(patsubst %.c, %.o, $(src))
all: $(EXECUTABLE)
$(EXECUTABLE): $(obj)        $(CC) -g -o $@ $^  $(INCFLAGS) $(CFLAGS) $(LDFLAGS)
%.o:%.c        $(CC) -g -o $@ -c $<  $(INCFLAGS) $(CFLAGS) $(LDFLAGS)
.PHONY: cleanclean:        rm -f $(EXECUTABLE) $(obj)

其中最重要的就是編譯時需要 xeno-config來生成gcc參數。xeno-config在我們編譯安裝xenomai庫后,默認放在 /usr/bin/xeno-config

$ /usr/bin/xeno-config --helpxeno-config --verbose        --core=cobalt        --version="3.1"        --cc="gcc"        --ccld="/usr/bin/wrap-link.sh gcc"        --arch="x86"        --prefix="/usr"        --library-dir="/usr/lib"Usage xeno-config OPTIONSOptions :        --help        --v,--verbose        --version        --cc        --ccld        --arch        --prefix        --[skin=]posix|vxworks|psos|alchemy|rtdm|smokey|cobalt        --auto-init|auto-init-solib|no-auto-init        --mode-check|no-mode-check        --cflags        --ldflags        --lib*-dir|libdir|user-libdir        --core        --info        --compat

例如編譯一個POSIX接口的實時應用,參數 --cflags表示編譯,指定接口(skin) --posix,就能得到編譯該程序的gcc參數了,看著沒什么特別的:

$ /usr/bin/xeno-config --posix --cflags-I/usr/include/xenomai/cobalt-I/usr/include/xenomai-D_GNU_SOURCE-D_REENTRANT-fasynchronous-unwind-tables-D__COBALT__-D__COBALT_WRAP__

再看鏈接--ldflags表示鏈接,如下得到鏈接參數:

$ /usr/bin/xeno-config --ldflags --posix-Wl,--no-as-needed-Wl,@/usr/lib/cobalt.wrappers-Wl,@/usr/lib/modechk.wrappers/usr/lib/xenomai/bootstrap.o-Wl,--wrap=main-Wl,--dynamic-list=/usr/lib/dynlist.ld-L/usr/lib-lcobalt-lmodechk-lpthread-lrt

這一看就多出不少東西,重點就在這 cobalt.wrappersmodechk.wrappers,兩個文件的內容如下:

...--wrap open--wrap open64--wrap socket--wrap close--wrap ioctl--wrap read....--wrap recv--wrap send--wrap getsockopt--wrap setsockop...

里面是一些posix系統(tǒng)調用,前面的 --wrap是什么作用?這是執(zhí)行鏈接過程的程序 ld的一個參數,通過 man ld可以找到該參數的說明:

--wrap symbol           Use a wrapper function for symbol.  Any undefined reference to symbol will be resolved to "__wrap_symbol".  Any undefined reference to "__real_symbol" will be resolved to symbol.
           This can be used to provide a wrapper for a system function.  The wrapper function should be called "__wrap_symbol".  If it wishes to call the system function, it should call "__real_symbol".
           Here is a trivial example:
                   void *                   __wrap_malloc (size_t c)                   {                     printf ("malloc called with %zu
", c);                     return __real_malloc (c);                   }
           If you link other code with this file using --wrap malloc, then all calls to "malloc" will call the function "__wrap_malloc" instead.  The call to "__real_malloc" in "__wrap_malloc" will call the real "malloc"           function.
           You may wish to provide a "__real_malloc" function as well, so that links without the --wrap option will succeed.  If you do this, you should not put the definition of "__real_malloc" in the same file as           "__wrap_malloc"; if you do, the assembler may resolve the call before the linker has a chance to wrap it to "malloc".

簡單來說就是:任何 對 symbol未定義 的 引用 (undefined reference) 將 解析為 __wrap_symbol. 任何 對 __real_symbol未定義 的 引用 將 解析為 symbol。意思就是我們代碼里使用到且是參數 --wrap指定的符號 symbol(即文件里的內容),鏈接的時候就認為它是 __wrap_symbol,比如我們代碼用到了 open()在鏈接的時候是與庫中的 __wrap_open()鏈接的, __wrap_open就是在xenomai 實時庫libcobalt中實現(xiàn),現(xiàn)在我們明白我們的posix函數如何和xenomai對接上了。

對于 xeno-config的其他更多參數可通過xenomai Manual Page了解。

這樣就將POSIX接口源碼編譯成一個xenomai可執(zhí)行程序了。

我們還有另一個問題,既然鏈接到了libcobalt,但我們是要Linux來提供服務,又是怎么讓Linux來提供服務的呢?看libcobalt具體實現(xiàn)可以知道答案。

3. libcobalt中的實現(xiàn)

下面來看問題2,既然我們已將一個接口鏈接到實時內核庫libcobalt,當然由實時內核庫libcobalt來區(qū)分該發(fā)起linux內核調用還是xenomai內核系統(tǒng)。與上一篇文章一樣,以一個POSIX接口 pthread_cretate()來解析libcobalt中的實現(xiàn)。

xenomai線程的創(chuàng)建流程比較復雜,需要先讓linux創(chuàng)建普通線程,然后再由xenomai創(chuàng)建該線程的shadow 線程,即xenomai調度的實時線程,很符合我們上面的提出的問題2。說到這先簡答介紹一下xenomai實時線程的創(chuàng)建,詳細的創(chuàng)建流程后面會寫專門寫一篇文章解析,敬請期待。

pthread_cretate()不是一個系統(tǒng)調用,由NPTL(Native POSIX Threads Library)實現(xiàn)(NPTL是Linux 線程實現(xiàn)的現(xiàn)代版,由UlrichDrepper 和Ingo Molnar 開發(fā),以取代LinuxThreads),NPTL負責一個用戶線程的用戶空間棧創(chuàng)建、內存分配、初始化等工作,與linux內核配合完成線程的創(chuàng)建。每一線程映射一個單獨的內核調度實體(KSE,Kernel Scheduling Entity)。內核分別對每個線程做調度處理。線程同步操作通過內核系統(tǒng)調用實現(xiàn)。

xenomai coblat作為實時任務的調度器,每個實時線程需要對應到 coblat調度實體,如果要創(chuàng)建實時線程就需要像linux那樣NPTL與linux 內核深度結合,那么coblat與libcoblat實現(xiàn)將會變得很復雜。在這里,xenomai使用了一種方式,由NPTL方式去完成實時線程實體的創(chuàng)建(linux部分),在普通線程的基礎上附加一些屬性,對應到xenomai cobalt內核實體時能被實時內核cobalt調度。

所以libcoblat庫中的實時線程創(chuàng)建函數 pthread_cretate最后還是需要使用 glibc的 pthread_cretate函數,xenomai只是去擴展glibc pthread_cretate創(chuàng)建的線程,使這個線程可以在實時內核cobalt調度。

pthread_cretate()在libcobalt中pthread.h文件中定義如下:

COBALT_DECL(int, pthread_create(pthread_t *ptid_r,        const pthread_attr_t *attr,        void *(*start) (void *),        void *arg));

COBALT_DECL宏在 wrappers.h中如下,展開上面宏,會為 pthread_create()生成三個類型函數:

#define __WRAP(call)    __wrap_ ## call#define __STD(call)    __real_ ## call#define __COBALT(call)    __cobalt_ ## call#define __RT(call)    __COBALT(call)#define COBALT_DECL(T, P)    __typeof__(T) __RT(P);    __typeof__(T) __STD(P);   __typeof__(T) __WRAP(P)  int __cobalt_pthread_create(pthread_t *ptid_r,        const pthread_attr_t *attr,        void *(*start) (void *),        void *arg);int __wrap_pthread_create(pthread_t *ptid_r,        const pthread_attr_t *attr,        void *(*start) (void *),        void *arg);int __real_pthread_create(pthread_t *ptid_r,        const pthread_attr_t *attr,        void *(*start) (void *),        void *arg);

聲明 pthread_create()函數的這三個宏意思為:

__RT(P):__cobalt_pthread_create明確表示Cobalt實現(xiàn)的POSIX函數

__COBALT(P):與__RT()等效。

__STD(P):__real_pthread_create表示這是原始的POSIX函數(Linux glibc實現(xiàn)),cobalt庫內部通過它來表示調用原始的POSIX函數(glibc NPTL).

__WRAP(P)__wrap_pthread_create__cobalt_pthread_create的弱別名,如果編譯器編譯時知道有該函數其它的實現(xiàn),該函數就會被覆蓋。

主要關注前面兩個,對于最后一個宏,如果外部庫想覆蓋已有的函數,應提供其自己的 __wrap_pthread_create()實現(xiàn),來覆蓋Cobalt實現(xiàn)的 pthread_create()版本。原始的Cobalt實現(xiàn)仍可以引用為 __COBALT(pthread_create)。由宏COBALT_IMPL來定義:

#define COBALT_IMPL(T, I, A)                \__typeof__(T) __wrap_ ## I A __attribute__((alias("__cobalt_" __stringify(I)), weak));  \__typeof__(T) __cobalt_ ## I A

最后cobalt庫函數 pthread_create實現(xiàn)主體為

COBALT_IMPL(int, pthread_create, (pthread_t *ptid_r,          const pthread_attr_t *attr,          void *(*start) (void *), void *arg)){  pthread_attr_ex_t attr_ex;  ......  return pthread_create_ex(ptid_r, &attr_ex, start, arg);}

COBALT_IMPL定義了 __cobalt_pthread_create函數及該函數的一個弱別名 __wrap_pthread_create,調用這兩個函數執(zhí)行的是同一個函數體。

對于 NPTL函數 pthread_create,在Cobalt庫里使用 __STD()修飾,展開后即 __real_pthread_create(),其實只是NPTL pthread_create()的封裝, __real_pthread_create()會直接調用 NPTL pthread_create,在libcobaltwrappers.c實現(xiàn)如下:

/* pthread */__weakint __real_pthread_create(pthread_t *ptid_r,        const pthread_attr_t * attr,        void *(*start) (void *), void *arg){  return pthread_create(ptid_r, attr, start, arg);}

它調用的就是glibc中的 pthread_create函數.同樣我們接著 __cobalt_pthread_create()看哪里調用的.

int pthread_create_ex(pthread_t *ptid_r,          const pthread_attr_ex_t *attr_ex,          void *(*start) (void *), void *arg){  ......  __STD(sem_init(&iargs.sync, 0, 0));
  ret = __STD(pthread_create(&lptid, &attr, cobalt_thread_trampoline, &iargs));/*__STD 調用標準庫的函數*/  if (ret) {    __STD(sem_destroy(&iargs.sync));    return ret;  }
  __STD(clock_gettime(CLOCK_REALTIME, &timeout));    .....}

下面再看另一個例子,實時任務在代碼中使用了linux的網絡套接字(xenomai任務也是一個linux任務,也可以使用linux來提供服務,只不過會影響實時性),有以下代碼,:

....    int sockfd,ret;                                                struct sockaddr_in addr;                               sockfd = socket(PF_INET, SOCK_STREAM, 0);            .....    bind(sockfd, (struct sockaddr *)&my_addr,sizeof(struct sockaddr_in));        ....

該代碼編譯時鏈接到了libcobalt,socket()函數即libcobalt中的 __cobalt_socket(),其定義在xenomai- 3.x.xlibcobalt tdm.c,如下:

COBALT_IMPL(int, socket, (int protocol_family, int socket_type, int protocol)){  int s;  s = XENOMAI_SYSCALL3(sc_cobalt_socket, protocol_family,           socket_type, protocol);  if (s < 0) {    s = __STD(socket(protocol_family, socket_type, protocol));  }  return s;}

可以看到,libcobalt中的函數會先嘗試調用實時內核cobalt的系統(tǒng)調用, 當cobalt系統(tǒng)調用不成功的時候才繼續(xù)嘗試通過 __STD()宏來調用linux系統(tǒng)調用(cobalt內核根據socket協(xié)議類型參數 PF_INET, SOCK_STREAM判斷),這樣就有效的分清了是linux系統(tǒng)調用還是xenomai系統(tǒng)調用,這也是所有l(wèi)ibcobalt實現(xiàn)的posix都鏈接到libobalt庫的原因。

一般情況下,可以直接在代碼中使用 __STD()宏指明我們調用的linux內核的服務,修改如下:

....    int sockfd,ret;                                                struct sockaddr_in addr;                               sockfd = __STD(socket(PF_INET, SOCK_STREAM, 0));            .....     __STD(bind(sockfd, (struct sockaddr *)&my_addr,sizeof(struct sockaddr_in)));....

現(xiàn)在一切都明了了,一個函數編譯時通過參數鏈接到xenomai庫后,通過 __STD()宏來表示使用linux接口。

4. 總結

  • 在實時程序或實時庫libcobalt中,通過__STD()宏來表示使用linux接口。

  • 對于一個未指明的接口,libcobalt會先嘗試發(fā)起xenomai系統(tǒng)調用,不成功會接著嘗試linux內核系統(tǒng)調用或者調用glibc函數。

  • 如果我們向libcobalt庫中新添加一個libcobalt庫中沒有的自定義POSIX函數/系統(tǒng)調用時,一定要在內部先嘗試發(fā)起xenomai系統(tǒng)調用,不成功時接著嘗試linux內核系統(tǒng)調用,此外還必須將該接口添加到文件xenomailibcobaltcobalt.wrappers中,這樣才能正確鏈接,否則編譯后的應用還是原來的。

二、 如何為xenomai添加一個系統(tǒng)調用

1. 添加系統(tǒng)調用

有的時候我們需要給系統(tǒng)添加一個特殊功能的系統(tǒng)調用,比如我們在對xenomai做benchmark測試的時候,需要測試每個系統(tǒng)服務操作系統(tǒng)需要消耗多長時間,比如測量獲取信號量操作系統(tǒng)的耗時。我們知道中斷優(yōu)先級最高,會強占前臺的操作系統(tǒng)和應用,為了更準確的測量獲取信號量時操作系統(tǒng)的耗時,這里需要將這種情況下的結果丟棄,我們就需要一個獲取xenomai中斷次數的系統(tǒng)調用。

假設該系統(tǒng)沒有任何實時驅動運行,且設置了xenomai.supportedcpus和linux irqaffinity,supportedcpus啟用tickless,下面給xenomai添加一個系統(tǒng)調用 get_timer_hits(),用于獲取應用程序運行CPU的定時器中斷產生的次數(類似于VxWorks里的tickGet(),VxWorks是采用周期tick的方式來驅動系統(tǒng)運作,tickGet()獲取的也就是tick定時器中斷的次數)。以該系統(tǒng)調用來舉例如何為xenomai添加一個實時系統(tǒng)調用。

在前兩篇文中說到,xenomai每個系統(tǒng)的系統(tǒng)系統(tǒng)調用號在 cobaltuapisyscall.h中:

#definesc_cobalt_bind0#definesc_cobalt_thread_create1#definesc_cobalt_thread_getpid2......#definesc_cobalt_extend96

在此添加 sc_cobalt_get_timer_hits的系統(tǒng),為了避免與xenomai系統(tǒng)調用沖突(xenomai官方添加的系統(tǒng)調用號從小到大),那我們就從最后一個系統(tǒng)調用添加,即127號系統(tǒng)調用,如下。

#definesc_cobalt_bind0#definesc_cobalt_thread_create1#definesc_cobalt_thread_getpid2......#definesc_cobalt_extend96#definesc_cobalt_ftrace_puts97#definesc_cobalt_recvmmsg98#definesc_cobalt_sendmmsg99#definesc_cobalt_clock_adjtime100#definesc_cobalt_thread_setschedprio101#definesc_cobalt_get_timer_hits127#define__NR_COBALT_SYSCALLS128/*Powerof2*/

先確定一下我們這個函數的API形式,由于是一個非標準的形式,這里表示如下:

int get_timer_hits(unsigned long *u_tick);

參數為保存hits的變量地址;

返回值:成功0;出錯 <0;

系統(tǒng)調用的頭文件,然后添加一個系統(tǒng)調用的聲明,覺得它和clock相關,那就放在 kernelxenomaiposixclock.h中吧。

#includeCOBALT_SYSCALL_DECL(get_timer_hits,(unsignedlong__user*u_tick));

然后是該函數的內核實現(xiàn),放在 /kernelxenomaiposixclock.c,如下:

COBALT_SYSCALL(get_timer_hits,primary,(unsignedlong__user*u_tick)){structxnthread*thread;  unsignedlongtick; intcpu; intret=0;    unsignedintirq;thread=xnthread_current();if(thread==NULL)    return-EPERM;/*得到當前任務CPU號*/cpu=xnsched_cpu(thread->sched);irq=per_cpu(ipipe_percpu.hrtimer_irq,cpu);/*讀取該CPU中斷計數*/tick=__ipipe_cpudata_irq_hits(&xnsched_realtime_domain,cpu,irq); if(cobalt_copy_to_user(u_tick,&tick,sizeof(tick))) return-EFAULT;returnret;}

需要注意的是該系統(tǒng)調用的權限,這里使用 primary,表示只有cobalt上下文(實時線程)才能調用。

修改完成后重新編譯內核并安裝。

2.Cobalt庫添加接口

在前兩篇文中說到,xenomai系統(tǒng)調用由libcobalt發(fā)起,所以修改應用庫來添加該函數接口,添加聲明 includecobalt ime.h

COBALT_DECL(int,get_timer_hits(unsignedlongtick));

xenomai3.x.xlibcobaltclock.c添加該接口定義:

COBALT_IMPL(int,get_timer_hits,(unsignedlong*tick)){intret;ret=-XENOMAI_SYSCALL1(sc_cobalt_get_tick,tick);returnret;}

因為該系統(tǒng)調用和posix接口沒有符號重名,不需要修改wrappers文件,完成上述步驟后重新編譯并安裝xenomai庫

3. 應用使用

由于我們添加 get_timer_hits()系統(tǒng)調用時,指定了系統(tǒng)調用的權限為primary,這里創(chuàng)建一個實時任務,使用宏 __RT()指定鏈接到libcobalt庫。

#include #include #include #include #include #include #include #include #include #include #include #include #include 
#define PRIO 50
void test(void *cookie){  unsigned long tick;  int ret;  ret  = __RT(get_timer_hits(&tick));  if (ret){    fprintf(stderr,      "%s: failed to get_tick,%s
",      __func__,strerror(-ret));    return ret;  }      fprintf(stdout,"timer_hits:%ld
",tick);    /*....*/  return 0;}
int main(int argc, char *const *argv){    struct sigaction sa __attribute__((unused));  int sig, cpu = 0;  char sem_name[16];  sigset_t mask;  RT_TASK task;    int ret;        sigemptyset(&mask);  sigaddset(&mask, SIGINT);  sigaddset(&mask, SIGTERM);  sigaddset(&mask, SIGHUP);  sigaddset(&mask, SIGALRM);  pthread_sigmask(SIG_BLOCK, &mask, NULL);  setlinebuf(stdout);      ret = rt_task_spawn(&task, "test_task", 0, PRIO,             T_JOINABLE, test, NULL);  if (ret){    fprintf(stderr,      "%s: failed to create task,%s
",      __func__,strerror(-ret));    return ret;  }        __STD(sigwait(&mask, &sig));    rt_task_join(&task);    rt_task_delete(&task);        return 0;}

編譯Makefile:

XENO_CONFIG := /usr/xenomai/bin/xeno-config
PROJPATH = .
CFLAGS := $(shell $(XENO_CONFIG)   --posix --alchemy --cflags)LDFLAGS := $(shell $(XENO_CONFIG)  --posix --alchemy --ldflags)INCFLAGS= -I$(PROJPATH)/include/

EXECUTABLE := get-timer-hits
src = $(wildcard ./*.c)obj = $(patsubst %.c, %.o, $(src))
all: $(EXECUTABLE)
$(EXECUTABLE): $(obj)        $(CC) -g -o $@ $^  $(INCFLAGS) $(CFLAGS) $(LDFLAGS)
%.o:%.c        $(CC) -g -o $@ -c $<  $(INCFLAGS) $(CFLAGS) $(LDFLAGS)
.PHONY: cleanclean:        rm -f $(EXECUTABLE) $(obj)

運行結果:

$./get-timer-hitstimer_hits:3

可以看到,雖然系統(tǒng)已經啟動十幾分鐘了,但一直沒有運行xenomai應用,xenomai tick相關中斷才產生了3次,這就是tickless,后面會出xenomai調度及時間子系統(tǒng)和xenomai benchmark相關文章,敬請關注。

審核編輯 :李倩

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11479

    瀏覽量

    213026
  • Xenomai
    +關注

    關注

    0

    文章

    10

    瀏覽量

    8081

原文標題:xenomai內核解析--雙核系統(tǒng)調用(二)--應用如何區(qū)分xenomai/linux系統(tǒng)調用或服務

文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦
    熱點推薦

    如何配置Linux防火墻和Web服務

    在當今數字化時代,網絡安全顯得尤為重要。Linux作為一種開源操作系統(tǒng),廣泛應用于服務器管理和網絡配置中。本篇文章將詳細介紹如何配置Linux防火墻和Web
    的頭像 發(fā)表于 05-24 15:26 ?845次閱讀
    如何配置<b class='flag-5'>Linux</b>防火墻和Web<b class='flag-5'>服務</b>器

    詳解Linux系統(tǒng)中的服務管理

    Linux中,無論何時當你安裝任何帶有服務和守護進程的包,系統(tǒng)默認會把這些服務的初始化及 systemd腳本添加進去,不過此時它們并沒有被啟用。
    的頭像 發(fā)表于 05-23 15:10 ?175次閱讀
    詳解<b class='flag-5'>Linux</b><b class='flag-5'>系統(tǒng)</b>中的<b class='flag-5'>服務</b>管理

    服務器數據恢復—Linux系統(tǒng)服務器崩潰的數據恢復案例

    服務器數據恢復環(huán)境: linux操作系統(tǒng)服務器中有一組由4塊SAS接口硬盤組建的raid5陣列。 服務器故障:
    的頭像 發(fā)表于 05-20 15:46 ?115次閱讀

    Linux系統(tǒng)用戶權限詳解

    Linux 是一種開源的、基于 Unix 的操作系統(tǒng),它因其靈活性、穩(wěn)定性和高性能而廣泛應用于服務器、嵌入式系統(tǒng)、超級計算機、桌面計算等領域。
    的頭像 發(fā)表于 04-25 10:56 ?250次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>系統(tǒng)</b>用戶權限詳解

    Linux網絡設置與基礎服務

    Linux網絡設置與基礎服務
    的頭像 發(fā)表于 04-09 11:51 ?2195次閱讀
    <b class='flag-5'>Linux</b>網絡設置與基礎<b class='flag-5'>服務</b>

    有3566或者3588移植xenomai的方法嗎?

    有3566或者3588移植xenomai的方法嗎?
    發(fā)表于 03-26 10:17

    如何在RakSmart服務器上用Linux系統(tǒng)部署DeepSeek

    Linux系統(tǒng) DeepSeek 部署方案,結合RakSmart 服務器硬件推薦及多場景適配建議,主機推薦小編為您整理發(fā)布如何在RakSmart服務器上用
    的頭像 發(fā)表于 03-14 11:53 ?356次閱讀

    迅為RK3588開發(fā)板實時系統(tǒng)編譯-Preemption系統(tǒng)/ Xenomai系統(tǒng)編譯-實時系統(tǒng)燒寫-固件獲取方式

    開發(fā)板】基礎資料\\\\10_實時系統(tǒng)配套資料 \\\\04_Xenomai 實時系統(tǒng)鏡像”路徑下下載使用。每種鏡像提供了不同接口屏幕的鏡像,如下圖所示: 然后根據屏幕類型選擇該系統(tǒng)
    發(fā)表于 02-11 14:50

    迅為RK3588開發(fā)板實時系統(tǒng)編譯-Preemption系統(tǒng)/ Xenomai系統(tǒng)編譯-獲取Linux源碼包

    3.1 Preemption 系統(tǒng)/ Xenomai 系統(tǒng)編譯 3.1.1 獲取 Linux 源碼包 編譯環(huán)境說明: 本手冊使用的是迅為提供的編譯環(huán)境 ubuntu20.04,在網盤資
    發(fā)表于 01-09 11:03

    如何在Linux系統(tǒng)上設置站群服務器IP地址

    Linux系統(tǒng)上設置站群服務器的IP地址,可以通過以下步驟進行,主機推薦小編為您整理發(fā)布如何在Linux系統(tǒng)上設置站群
    的頭像 發(fā)表于 12-11 10:05 ?455次閱讀

    HarmonyOS NEXT應用元服務開發(fā)Intents Kit(意圖框架服務)技能調用方案概述

    一、概述 技能調用是意圖框架依托系統(tǒng)AI多模態(tài)大模型能力做深度用戶輸入理解,并通過解析的用戶意圖對接應用或元服務內的功能和內容。 二、場景體驗 用戶通過對小藝對話進行自然語言輸入實現(xiàn)內容查詢,知識
    發(fā)表于 11-08 15:38

    迅為瑞芯微RK3568開發(fā)板/核心板《iTOP-3568開發(fā)板實時系統(tǒng)使用手冊》

    編譯 3.1 翼輝系統(tǒng)編譯 3.2 Preemption 系統(tǒng)/ Xenomai系統(tǒng)編譯 3.2.1 獲取Linux源碼包 3.2.2 SD
    發(fā)表于 10-31 09:53

    如何優(yōu)化Linux服務器的性能

    優(yōu)化Linux服務器的性能是一個綜合性的任務,涉及硬件、軟件、配置、監(jiān)控等多個方面。以下是一個詳細的指南,旨在幫助系統(tǒng)管理員和運維人員提升Linux
    的頭像 發(fā)表于 09-29 16:50 ?615次閱讀

    迅為RK3568開發(fā)板/核心板助力實時系統(tǒng)

    編譯 3.1 翼輝系統(tǒng)編譯 3.2 Preemption 系統(tǒng)/ Xenomai系統(tǒng)編譯 3.2.1 獲取Linux源碼包 3.2.2 SD
    發(fā)表于 09-26 11:29

    Linux服務器性能查看方法

    Linux服務器性能查看是系統(tǒng)管理員和開發(fā)人員在日常工作中經常需要進行的任務,以確保系統(tǒng)穩(wěn)定運行并優(yōu)化資源使用。以下將詳細介紹多種Linux
    的頭像 發(fā)表于 09-02 11:15 ?1703次閱讀
    主站蜘蛛池模板: 中文字幕二区三区 | 免费在线看片网站 | 国产精品福利视频手机免费观看 | 国产成人精品日本亚洲语言 | 一级毛片免费毛片一级毛片免费 | 欧美人成网 | 日本三区四区免费高清不卡 | 五月在线观看 | 精品国内视频 | 亚洲国产欧美视频 | 拍真实国产伦偷精品 | 美女被免费网站在线视频九色 | 久久综合九九亚洲一区 | 狼色在线视频 | 免费抓胸吻胸激烈视频网站 | 日本大片免a费观看在线 | 免费h视频网站 | 日韩欧美中文字幕在线视频 | 亚洲网站色 | 天天在线天天看成人免费视频 | 欧美伊久线香蕉线新在线 | 国产人成高清视频观看 | 波多野结衣50连精喷在线 | 好硬好大好爽女房东在线观看 | 黄色免费网站在线播放 | 亚洲a人片在线观看网址 | 天天操天天爱天天干 | 特级一级毛片 | 成人精品亚洲人成在线 | 你懂的在线免费视频 | 久草资源网站 | 久久电影www成人网 久久电影福利 | 高清视频一区 | 日韩成人午夜 | 丁香六月欧美 | 中文字幕1页 | 免费一级牲交毛片 | 欧美一区二区三区不卡免费观看 | 国产精品黄页网站在线播放免费 | 你懂的视频在线观看资源 | 午夜免费福利在线观看 |