linux內核版本信息,linux 內核 發送數據類型,Linux內核數據類型及跨平臺

 2023-10-15 阅读 37 评论 0

摘要:一、內核對象數據類型1.1 C語言類型(int)char、short、int、long long在不同的平臺上大小不變。linux內核版本信息。long、ptr(指針)平臺不同其大小不同,但二者的大小始終相同。char的符號問題:大多數平臺上char默認是signed,但有些平臺上默認是 unsigne

一、內核對象數據類型

1.1 C語言類型(int)

char、short、int、long long在不同的平臺上大小不變。

linux內核版本信息。long、ptr(指針)平臺不同其大小不同,但二者的大小始終相同。

char的符號問題:

大多數平臺上char默認是signed,但有些平臺上默認是 unsigned。

char i = -1; 大部分平臺上i是-1,有些平臺上是255。

Linux 內核,應該使用:signed char i = -1; ? unsigned char i = 255;

1.2 確定大小的類型(u32)

u8、u16、u32、u64、?s8、s16、s32、s64是linux內核確定大小的類型。

__u8等式linux用戶態確定大小的類型。(頭文件linux/types.h)

java并發包常用類,uint8_t、uint32_t是新編譯器支持的C99標準確定大小的類型,可以跨平臺。

1.3 特定內核對象的類型(pid_t)

進程標識符使用pid_t類型,而不使用int,屏蔽了實際的數據類型中任何可能的差異。

特定內核對象的類型,打印時,不太好選擇printk或printf的輸出格式:

UNIX/LINUX、1. ?一些平臺上排除的警告,在另一平臺上可能會出現(size_t在一些平臺上是unsigned long,在一些平臺上是unsigned int)。

2. 將其強制轉換成可能的最大類型,然后用響應的格式打印輸出。

二、字節序

2.1 大端、小端

vim 上一頁下一頁、數值0x01020304,內存從低到高依次存儲:04 03 02 01 為小端。 存儲順序反過來為大端)

數值0x00000001,內存從低到高依次存儲:01 00 00 00 為小端。

2.2 轉換函數

u32?__cpu_to_be32(u32); ? ?/* 把cpu字節序轉為大端字節序?*/

linux最新內核?u32?__be32_to_cpu(u32);? ? /* 把大端字節序轉為cpu字節序?*/

u32?__cpu_to_le32(u32); ? ? ?/* 把cpu字節序轉為小端字節序?*/

u32?__le32_to_cpu(u32); ? ? ?/* 把小端字節序轉為cpu字節序?*/

在頭文件中

linux內核版本號、2.3 檢測本機大端小端的代碼

#include

#include

/*int is_little_endian()

{

const static union

{

unsigned int i;

unsigned char c[4];

}u = { 0x00000001 };

return u.c[0];

}*/

int is_little_endian()

{

int i = 1;

return *(char*)&i;

}

int main(int argc, char*argv[])

{

if (is_little_endian())

printf("little endian.\n");

else

printf("big endian.\n");

return 0;

}

三、數據對齊

3.1 數據對齊

對齊:如果一個變量的內存地址正好是它長度的整數倍,它就被稱作是自然對齊的。

3.2?數據未對齊印發的問題

一些平臺不能訪問未對其的數據,一些平臺可以訪問未對齊的數據,但是效率很低。

用指針進行類型轉換引發的未對齊:

char dog[10]; //是對齊的

char *p = &dog[1];

long l = *(long*)p; //l是未對齊的

3.3 盡量保證數據對齊

為了實現跨平臺,應盡量讓數據自然對齊。

編譯器會悄悄的插入數據保證struct的自然對齊:

1. 下面的代碼,沒有__attribute__((packed)),長度為16;

2. 下面的代碼,有__attribute__((packed)),長度為10;

3. ?__attribute__((packed))不讓編譯器對struct進行填充,以保證其自然對齊(有時候我們需要這樣的數據)。

#include

#include

#include

int main(int argc, char*argv[])

{

struct

{

__u16 i;

__u64 j;

}__attribute__((packed)) u;

printf("struct u len:%d\n", sizeof(u));

return 0;

}

3.4 訪問未對齊的數據

應該使用下面的宏:

#include

get_unaligned(ptr)

put_unaligned(var, ptr)

四、其他有關可移植性的問題

避免使用顯示的常量值

4.1 時間間隔

使用HZ代表一秒。

不能假定每秒就1000個jiffies。

與msec毫秒對應的jiffies數目總是msec*HZ/1000。

4.2 頁大小

頁大小為PAGE_SIZE個字節,而不是4KB。

分配16KB的空間臨時存儲數據,如下:

#include

int order = get_order(16*1024);

buf = get_free_pages(GFP_KERNEL, order);

4.3 指針和錯誤值

許多內核函數通過把錯誤值編碼到一個指針值中來返回錯誤信息,這種函數必須小心使用,它的返回值不能簡單地和NULL比較。

#include

static struct task_struct *kapmd_task;

kapmd_task = kthread_create(apm, NULL, "kapmd");

if (IS_ERR(kapmd_task)) {

printk(KERN_ERR "apm: disabled - Unable to start kernel "

"thread.\n");

err = PTR_ERR(kapmd_task);

kapmd_task = NULL;

remove_proc_entry("apm", NULL);

return err;

}

4.4 其他

處理器排序(rmb()、wmb())、SMP、內核搶占、高端內存

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/2/137700.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息