日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
深入剖析LinuxC編程中的ntohl函數(shù)(linuxcntohl)

在Linux C編程中,ntohl函數(shù)是網(wǎng)絡(luò)字節(jié)序和主機字節(jié)序之間轉(zhuǎn)換的重要函數(shù)。由于網(wǎng)絡(luò)中傳輸?shù)臄?shù)據(jù)在通信過程中可能會出現(xiàn)字節(jié)序不一致的情況,因此需要通過ntohl函數(shù)將字節(jié)序進行轉(zhuǎn)換,從而保證數(shù)據(jù)的正確傳輸和處理。本文將深入剖析ntohl函數(shù)的使用、作用原理及其在網(wǎng)絡(luò)編程中的應(yīng)用。

10年的無為網(wǎng)站建設(shè)經(jīng)驗,針對設(shè)計、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時及時工作處理。全網(wǎng)營銷推廣的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整無為建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計,從而大程度地提升瀏覽體驗。成都創(chuàng)新互聯(lián)公司從事“無為網(wǎng)站設(shè)計”,“無為網(wǎng)站推廣”以來,每個客戶項目都認(rèn)真落實執(zhí)行。

一、ntohl函數(shù)的使用

ntohl函數(shù)是Linux系統(tǒng)中的網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)換函數(shù)之一,其函數(shù)原型如下:

uint32_t ntohl(uint32_t netlong);

參數(shù)netlong為需要轉(zhuǎn)換的32位無符號整型數(shù)據(jù),函數(shù)返回值為轉(zhuǎn)換后的32位無符號整型數(shù)據(jù)。ntohl函數(shù)會將參數(shù)netlong從網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)換為主機字節(jié)序,通常情況下,主機字節(jié)序是指大端字節(jié)序(MSB在前,LSB在后)。

在網(wǎng)絡(luò)編程中,ntohl函數(shù)通常和htons、ntohs、htonl等函數(shù)搭配使用,用于對傳輸?shù)臄?shù)據(jù)進行字節(jié)序的轉(zhuǎn)換。比如,如果需要將一個32位整數(shù)在網(wǎng)絡(luò)中傳輸,需要把它轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)序,使用htons函數(shù)可以將它轉(zhuǎn)換為16位網(wǎng)絡(luò)字節(jié)序,使用htonl函數(shù)可以將它轉(zhuǎn)換為32位網(wǎng)絡(luò)字節(jié)序,傳輸過程中再通過ntohl/ntohs函數(shù)將它轉(zhuǎn)換為主機字節(jié)序。

二、ntohl函數(shù)的作用原理

在計算機中,數(shù)據(jù)在存儲時以字節(jié)為單位進行存儲,不同的計算機硬件架構(gòu)決定了不同的字節(jié)序。大端字節(jié)序(MSB在前,LSB在后)也稱為網(wǎng)絡(luò)字節(jié)序,小端字節(jié)序(LSB在前,MSB在后)也稱為主機字節(jié)序。不同的系統(tǒng)(Windows、Linux、Mac OS等)具有不同的字節(jié)序,因此在網(wǎng)絡(luò)通信中,需要將不同字節(jié)序的數(shù)據(jù)進行轉(zhuǎn)換,以保證數(shù)據(jù)的正確傳輸和處理。

ntohl函數(shù)的作用就是將32位無符號整型數(shù)據(jù)從網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)換為主機字節(jié)序,其轉(zhuǎn)換原理如下:

假設(shè)我們要對一個32位無符號整型值0x12345678進行字節(jié)序轉(zhuǎn)換,這個值的二進制表示為

00010010 00110100 01010110 01111000

– 在大端字節(jié)序的計算機中,該值按照從高到低的順序存儲,因此它在計算機中的表示為0x12345678,在網(wǎng)絡(luò)中的表示也應(yīng)該為0x12345678。

– 在小端字節(jié)序的計算機中,該值按照從低到高的順序存儲,因此它在計算機中的表示為0x78563412,在網(wǎng)絡(luò)中的表示應(yīng)該為0x78563412。

– 當(dāng)數(shù)據(jù)從小端字節(jié)序計算機發(fā)送到大端字節(jié)序計算機時,需要把該值轉(zhuǎn)換為大端字節(jié)序,先將低位字節(jié)0x78放在之一個字節(jié),高位字節(jié)0x12放在第四個字節(jié),中間兩個字節(jié)以此類推,得到的結(jié)果為0x78563412。然后接收方可以根據(jù)該值的字節(jié)序?qū)⑺D(zhuǎn)換為主機字節(jié)序。

– 當(dāng)數(shù)據(jù)從大端字節(jié)序計算機發(fā)送到小端字節(jié)序計算機時,需要把該值轉(zhuǎn)換為小端字節(jié)序,方法與上述相仿。

ntohl函數(shù)的作用就是將參數(shù)netlong從網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)換為主機字節(jié)序,其實現(xiàn)原理與上述類似。當(dāng)ntohl函數(shù)在大端字節(jié)序計算機中執(zhí)行時,該函數(shù)不做任何轉(zhuǎn)換,直接將參數(shù)netlong返回;當(dāng)ntohl函數(shù)在小端字節(jié)序計算機中執(zhí)行時,該函數(shù)將參數(shù)netlong的字節(jié)序進行轉(zhuǎn)換,然后將轉(zhuǎn)換結(jié)果返回。

三、ntohl函數(shù)在網(wǎng)絡(luò)編程中的應(yīng)用

在網(wǎng)絡(luò)編程中,ntohl函數(shù)通常和htonl、htons、ntohs等函數(shù)搭配使用,用于對傳輸?shù)臄?shù)據(jù)進行字節(jié)序的轉(zhuǎn)換。以下是ntohl函數(shù)在網(wǎng)絡(luò)編程中的應(yīng)用示例:

– 客戶端向服務(wù)器發(fā)送一個32位整數(shù)數(shù)據(jù):

uint32_t data = 0x12345678;

data = htonl(data); // 將數(shù)據(jù)轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)序

send(sockfd, &data, sizeof(data), 0); // 通過網(wǎng)絡(luò)發(fā)送數(shù)據(jù)

– 服務(wù)器接收到客戶端發(fā)送的數(shù)據(jù)后進行處理:

uint32_t data;

recv(sockfd, &data, sizeof(data), 0); // 從網(wǎng)絡(luò)接收數(shù)據(jù)

data = ntohl(data); // 將數(shù)據(jù)從網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)換為主機字節(jié)序

// 對數(shù)據(jù)進行處理

通過使用ntohl函數(shù),程序可以輕松地對傳輸?shù)臄?shù)據(jù)進行字節(jié)序轉(zhuǎn)換,使得數(shù)據(jù)在不同的計算機之間正確傳輸和處理,在網(wǎng)絡(luò)編程中具有重要的實用價值。

結(jié)語

本文深入剖析了Linux C編程中的ntohl函數(shù)的用法、作用原理及其在網(wǎng)絡(luò)編程中的應(yīng)用。我們了解了ntohl函數(shù)的轉(zhuǎn)換原理,了解了網(wǎng)絡(luò)通訊中字節(jié)序轉(zhuǎn)換的必要性,通過本文,我們可以更好地掌握ntohl函數(shù)的使用技巧,并在實際編程中更加熟練地運用它。

相關(guān)問題拓展閱讀:

  • linux little endian和big endian是什么意思
  • Ubuntu編譯了新的內(nèi)核,進入新內(nèi)核時一直顯示載入Linux 5.6.7,載入初始化內(nèi)存盤咋回事?

linux little endian和big endian是什么意思

1.故事的起源 “endian”這個詞出自《格列佛游記》。小人國的內(nèi)戰(zhàn)就源于吃雞蛋時是究竟從大頭(Big-Endian)敲開還是從小頭(Little-Endian)敲開,由此曾發(fā)生過六次叛亂,其中一個皇帝送了命,另一個丟了王位。 我們一般將endian翻譯成“字節(jié)序”,將big endian和little endian稱作“大尾”和“小尾”。 2.什么是Big Endian和Little Endian? 在設(shè)計計算伏辯機系統(tǒng)的時候,有兩種處理內(nèi)存中數(shù)據(jù)的方法。一種叫為little-endian,存放在內(nèi)存中更低位的數(shù)值是來自數(shù)據(jù)的最右邊部分(也就是數(shù)據(jù)的更低位部分)。 比如某些文件需要在不同平臺處理,或者通過Socket通信。這方面我們可以借助ntohl(), ntohs(), htonl(), and htons()函數(shù)進行格式轉(zhuǎn)換, 個人補充:一個操作數(shù)作htonl或ntohl結(jié)果不一定相同,當(dāng)機器字節(jié)序跟網(wǎng)絡(luò)字節(jié)序剛好是僅僅big endian和little endian的區(qū)別時是相同的。 3. 如何理解Big Endian和Little Endian 舉個例子: int a = 1; a這個數(shù)本身的16進制表示是0x在內(nèi)存中怎么存儲呢? 如果你的CPU是intel x86架構(gòu)的(基本上就是通常我們說的奔廳寬騰cpu),那么就是0x01 0x00 0x00 0x00 , 這也就是所謂扮廳亮的little-endian, 低字節(jié)存放在內(nèi)存的低位. 如果你的CPU是老式AMD系列的(很老很老的那種,因為最新的AMD系列已經(jīng)是x86架構(gòu)了), 它的字節(jié)序就是big-endian, 其內(nèi)存存儲就是 0x00 0x00 0x00 0x01在內(nèi)存中從高字節(jié)開始存放。 現(xiàn)在世界上絕大多數(shù)的CPU都是little-endian。 4. 了解big-endian和little-endian有什么作用? 一個重要的作用就是了解在網(wǎng)絡(luò)上不同的機器間的數(shù)據(jù)如何傳輸。 假設(shè)我們在網(wǎng)絡(luò)上有兩臺機器A和B,

Ubuntu編譯了新的內(nèi)核,進入新內(nèi)核時一直顯示載入Linux 5.6.7,載入初始化內(nèi)存盤咋回事?

概述====1)當(dāng)內(nèi)核配置了內(nèi)存盤時, 內(nèi)核在初始化時可以將

軟盤

加載到內(nèi)存盤中作為根盤.當(dāng)同時配置了初始化內(nèi)存盤(Initail RAM Disk)時, 內(nèi)核在初始化時可以在安裝主盤之前,通過引導(dǎo)程序所加載的initrd文件建立一個內(nèi)存初始化盤, 首先將它安裝成根

文件系統(tǒng)

, 然后執(zhí)行其

根目錄

下的linuxrc 文件,可用于在安裝主盤之前加載一些內(nèi)核模塊. 等到linuxrc 程序退出后, 再將主盤安裝成根文件系統(tǒng),并將內(nèi)存初始化盤轉(zhuǎn)移安皮銀裝到其/initrd目錄下.2)當(dāng)主盤就是initrd所生成的內(nèi)存初始化盤時, 不再進行重新安裝,在DOS下用loadlin加載的搶救盤就是這種工作方式.3)引導(dǎo)程序所加載的initrd為文件系統(tǒng)的映象文件, 可以是gzip壓縮的, 也可以是不壓縮的.能旁枝夠識別的文件系統(tǒng)有minix,ext2,romfs三種.4)當(dāng)內(nèi)核的根盤為軟盤時,內(nèi)核初始化運握敏時會測試軟盤的指定部位是否存在文件系統(tǒng)或壓縮文件映象, 然后將之加載或解壓到內(nèi)存盤中作為根盤. 這是單張搶救軟盤的工作方式.有關(guān)代碼========; init/main.c#ifdef CONFIG_BLK_DEV_INITRDkdev_t real_root_dev; 啟動參數(shù)所設(shè)定的根盤設(shè)備#endifalinkage void __init start_kernel(void){ char * command_line; unsigned long mempages; extern char saved_command_line; lock_kernel(); printk(linux_banner); setup_arch(&command_line);arch/i386/kernel/setup.c中,初始化initrd_start和initrd_end兩個變量 …#ifdef CONFIG_BLK_DEV_INITRD if (initrd_start && !initrd_below_start_ok && initrd_start need_resched = 1; cpu_idle();}static int init(void * unused){ lock_kernel(); do_basic_setup(); /* * Ok, we have completed the initial bootup, and * we’re essentially up and running. Get rid of the * initmem segments and start the user-mode stuff.. */ free_initmem(); unlock_kernel(); if (open(“/dev/console”, O_RDWR, 0) 0) while (pid != wait(&i)); 等待linuxrc進程退出 if (MAJOR(real_root_dev) != RAMDISK_MAJOR|| MINOR(real_root_dev) != 0) { ; 如果原來的根盤不是0號內(nèi)存盤,則使用原來的根文件系統(tǒng), ; 并且將內(nèi)存盤轉(zhuǎn)移到其/initrd目錄下 error = change_root(real_root_dev,”/initrd”); if (error) printk(KERN_ERR “Change root to /initrd: “”error %d/n”,error); } }#endif}#ifdef CONFIG_BLK_DEV_INITRDstatic int do_linuxrc(void * shell){ static char *argv = { “l(fā)inuxrc”, NULL, }; close(0);close(1);close(2); setsid(); 設(shè)置新的session號 (void) open(“/dev/console”,O_RDWR,0); (void) dup(0); (void) dup(0); return execve(shell, argv, envp_init);}#endif; arch/i386/kernel/setup.c#define RAMDISK_IMAGE_START_MASK 0x07FF#define RAMDISK_PROMPT_FLAG 0x8000#define RAMDISK_LOAD_FLAG 0x4000 #define PARAM ((unsigned char *)empty_zero_page)#define RAMDISK_FLAGS (*(unsigned short *) (PARAM+0x1F8)) 可用rdev設(shè)置的參數(shù)#define LOADER_TYPE (*(unsigned char *) (PARAM+0x210))#define INITRD_START (*(unsigned long *) (PARAM+0x218)) 初始化盤映象起始物理地址#define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c)) 初始化盤字節(jié)數(shù)void __init setup_arch(char **cmdline_p){ …#ifdef CONFIG_BLK_DEV_RAM rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK; 以塊為單位 rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0); rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);#endif …#ifdef CONFIG_BLK_DEV_INITRD if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE 0x%08lx)/ndisabling initrd/n”,INITRD_START + INITRD_SIZE,max_low_pfn (rd_length >> BLOCK_SIZE_BITS)) { ; 如果輸入盤的尺寸超過了輸出內(nèi)存盤的允許尺寸 printk(“RAMDISK: image too big! (%d/%ld blocks)/n”,nblocks, rd_length >> BLOCK_SIZE_BITS); goto done; } /* * OK, time to copy in the data */ buf = kmalloc(BLOCK_SIZE, GFP_KERNEL); if (buf == 0) { printk(KERN_ERR “RAMDISK: could not allocate buffer/n”); goto done; } if (blk_size) devblocks = blk_size; 取輸入盤的容量#ifdef CONFIG_BLK_DEV_INITRD if (MAJOR(device) == MAJOR_NR && MINOR(device) == INITRD_MINOR) devblocks = nblocks; 如果輸入是初始化內(nèi)存盤,則盤的容量為它的實際尺寸#endif if (devblocks == 0) { printk(KERN_ERR “RAMDISK: could not determine device size/n”); goto done; } printk(KERN_NOTICE “RAMDISK: Loading %d blocks into ram disk… “, nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? “s” : “”); for (i=0; i release) infile.f_op->release(inode, &infile); printk(“Please insert disk #%d and press ENTER/n”, i/devblocks+1); wait_for_keypress(); if (blkdev_open(inode, &infile) != 0) { printk(“Error opening disk./n”); goto done; } infile.f_pos = 0; printk(“Loading disk #%d… “, i/devblocks+1); } infile.f_op->read(&infile, buf, BLOCK_SIZE, &infile.f_pos); outfile.f_op->write(&outfile, buf, BLOCK_SIZE, &outfile.f_pos);#if !defined(CONFIG_ARCH_S390) if (!(i % 16)) { printk(“%c/b”, rotator); rotate++; }#endif } printk(“done./n”); kfree(buf);successful_load: invalidate_buffers(device); ROOT_DEV = MKDEV(MAJOR_NR, unit); 將根盤設(shè)備設(shè)置為當(dāng)前加載的內(nèi)存盤 if (ROOT_DEVICE_NAME != NULL) strcpy (ROOT_DEVICE_NAME, “rd/0″);done: if (infile.f_op->release) infile.f_op->release(inode, &infile); set_fs(fs); return;free_inodes: /* free inodes on error */ iput(out_inode); blkdev_put(inode->i_bdev, BDEV_FILE);free_inode: iput(inode);}int __init identify_ramdisk_image(kdev_t device, struct file *fp, int start_block){ const int size = 512; struct minix_super_block *minix; struct ext2_super_block *ext2; struct romfs_super_block *romf; int nblocks = -1; unsigned char *buf; buf = kmalloc(size, GFP_KERNEL); if (buf == 0) return -1; minix = (struct minix_super_block *) buf; ext2 = (struct ext2_super_block *) buf; romf = (struct romfs_super_block *) buf; memset(buf, 0xe5, size); /* * Read block 0 to test for gzipped kernel */ if (fp->f_op->llseek) fp->f_op->llseek(fp, start_block * BLOCK_SIZE, 0); fp->f_pos = start_block * BLOCK_SIZE; fp->f_op->read(fp, buf, size, &fp->f_pos); ; 讀取offset開始的512字節(jié) /* * If it matches the gzip magic numbers, return -1 */ if (buf == 037 && ((buf == 0213) || (buf == 0236))) { printk(KERN_NOTICE”RAMDISK: Compressed image found at block %d/n”,start_block); nblocks = 0; goto done; } /* romfs is at block zero too */ if (romf->word0 == ROMSB_WORD0 && romf->word1 == ROMSB_WORD1) { printk(KERN_NOTICE”RAMDISK: romfs filesystem found at block %d/n”,start_block); nblocks = (ntohl(romf->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS; goto done; } /* * Read block 1 to test for minix and ext2 superblock */ if (fp->f_op->llseek) fp->f_op->llseek(fp, (start_block+1) * BLOCK_SIZE, 0); fp->f_pos = (start_block+1) * BLOCK_SIZE; fp->f_op->read(fp, buf, size, &fp->f_pos); /* Try minix */ if (minix->s_magic == MINIX_SUPER_MAGIC || minix->s_magic == MINIX_SUPER_MAGIC2) { printk(KERN_NOTICE”RAMDISK: Minix filesystem found at block %d/n”,start_block); nblocks = minix->s_nzones s_log_zone_size; goto done; } /* Try ext2 */ if (ext2->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) { printk(KERN_NOTICE”RAMDISK: ext2 filesystem found at block %d/n”,start_block); nblocks = le32_to_cpu(ext2->s_blocks_count); goto done; } printk(KERN_NOTICE”RAMDISK: Couldn’t find valid RAM disk image starting at %d./n”,start_block);done: if (fp->f_op->llseek) fp->f_op->llseek(fp, start_block * BLOCK_SIZE, 0); fp->f_pos = start_block * BLOCK_SIZE; kfree(buf); return nblocks;}; fs/super.cvoid __init mount_root(void){ struct file_system_type * fs_type; struct super_block * ; struct vfount *vfnt; struct block_device *bdev = NULL; mode_t mode; int retval; void *handle; char path; int path_start = -1;#ifdef CONFIG_BLK_DEV_FD if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) { 當(dāng)根盤還是軟盤,表示沒有加載過內(nèi)存盤#ifdef CONFIG_BLK_DEV_RAM extern int rd_doload; extern void rd_load_secondary(void);#endif floppy_eject();#ifndef CONFIG_BLK_DEV_RAM printk(KERN_NOTICE “(Warning, this kernel has no ramdisk support)/n”);#else /* rd_doload is 2 for a dual initrd/ramload setup */ ; 只有當(dāng)加載了initrd但沒有釋放到內(nèi)存盤中(mount_inird=0)才有可能到這一步 if(rd_doload==2) rd_load_secondary(); 加載另一張軟盤到1號內(nèi)存盤作為根盤 else#endif { printk(KERN_NOTICE “VFS: Insert root floppy and press ENTER/n”); wait_for_keypress(); } }#endif devfs_make_root (root_device_name); handle = devfs_find_handle (NULL, ROOT_DEVICE_NAME, MAJOR (ROOT_DEV), MINOR (ROOT_DEV),DEVFS_SPECIAL_BLK, 1); if (handle) /* Sigh: bd*() functions only paper over the cracks */ { unsigned major, minor; devfs_get_maj_min (handle, &major, &minor); ROOT_DEV = MKDEV (major, minor); } /* * Probably pure paranoia, but I’m less than happy about delving into * devfs crap and checking it right now. Later. */ if (!ROOT_DEV) panic(“I have no root and I want to scream”); bdev = bdget(kdev_t_to_nr(ROOT_DEV)); if (!bdev) panic(__FUNCTION__ “: unable to allocate root device”); bdev->bd_op = devfs_get_ops (handle); path_start = devfs_generate_path (handle, path + 5, sizeof (path) – 5); mode = FMODE_READ; if (!(root_mountflags & MS_RDON)) mode |= FMODE_WRITE; retval = blkdev_get(bdev, mode, 0, BDEV_FS); if (retval == -EROFS) { root_mountflags |= MS_RDON; retval = blkdev_get(bdev, FMODE_READ, 0, BDEV_FS); } if (retval) {/* * Allow the user to distinguish between failed open * and bad superblock on root device. */ printk (“VFS: Cannot open root device /”%s/” or %s/n”, root_device_name, kdevname (ROOT_DEV)); printk (“Please append a correct /”root=/” boot option/n”); panic(“VFS: Unable to mount root fs on %s”, kdevname(ROOT_DEV)); } check_disk_change(ROOT_DEV); = get_super(ROOT_DEV); 取根盤的超級塊 if () { fs_type = ->s_type; goto mount_it; } read_lock(&file_systems_lock); for (fs_type = file_systems ; fs_type ; fs_type = fs_type->next) { if (!(fs_type->fs_flags & FS_REQUIRES_DEV)) continue; 根文件系統(tǒng)必須依賴于塊設(shè)備 if (!try_inc_mod_count(fs_type->owner)) continue; 當(dāng)文件系統(tǒng)模塊正在刪除過程中 read_unlock(&file_systems_lock); = read_super(ROOT_DEV,bdev,fs_type,root_mountflags,NULL,1);建立根盤的超級塊結(jié)構(gòu) if () goto mount_it; read_lock(&file_systems_lock); put_filesystem(fs_type); 釋放對文件系統(tǒng)模塊的引用 } read_unlock(&file_systems_lock); panic(“VFS: Unable to mount root fs on %s”, kdevname(ROOT_DEV));mount_it: printk (“VFS: Mounted root (%s filesystem)%s./n”, fs_type->name, (->s_flags & MS_RDON) ? ” readonly” : “”); if (path_start >= 0) { devfs_mk_symlink (NULL, “root”, DEVFS_FL_DEFAULT, path + 5 + path_start, NULL, NULL); memcpy (path + path_start, “/dev/”, 5); vfnt = add_vfnt(NULL, ->s_root, path + path_start); } else vfnt = add_vfnt(NULL, ->s_root, “/dev/root”); 建立根盤的安裝結(jié)構(gòu) /* FIXME: if something will try to umount us right now… */ if (vfnt) { set_fs_root(current->fs, vfnt, ->s_root); 設(shè)置當(dāng)前進程的根盤和根目錄 set_fs_pwd(current->fs, vfnt, ->s_root); 設(shè)置當(dāng)前進程的當(dāng)前盤和當(dāng)前目錄 if (bdev) bdput(bdev); /* holds a reference */ return; } panic(“VFS: add_vfnt failed for root fs”);}#ifdef CONFIG_BLK_DEV_INITRDint __init change_root(kdev_t new_root_dev,const char *put_old){ 以new_root_dev作為根盤重新安裝根文件系統(tǒng),原來的根轉(zhuǎn)移到put_old目錄下 struct vfount *old_rootmnt; struct nameidata devfs_nd, nd; int error = 0; read_lock(¤t->fs->lock); old_rootmnt = mntget(current->fs->rootmnt); 取當(dāng)前進程的根盤安裝結(jié)構(gòu) read_unlock(¤t->fs->lock); /* First unmount devfs if mounted */ if (path_init(“/dev”, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &devfs_nd)) error = path_walk(“/dev”, &devfs_nd); if (!error) { if (devfs_nd.mnt->mnt_->s_magic == DEVFS_SUPER_MAGIC && devfs_nd.dentry == devfs_nd.mnt->mnt_root) { dput(devfs_nd.dentry); down(&mount_sem); /* puts devfs_nd.mnt */ do_umount(devfs_nd.mnt, 0, 0); up(&mount_sem); } else path_release(&devfs_nd); } ROOT_DEV = new_root_dev; mount_root(); 改變根盤設(shè)備重新安裝根文件系統(tǒng)#if 1 shrink_dcache(); 清除目錄項緩沖中所有自由的目錄項 printk(“change_root: old root has d_count=%d/n”,atomic_read(&old_rootmnt->mnt_root->d_count));#endif mount_devfs_fs (); /* * Get the new mount directory */ error = 0; if (path_init(put_old, LOOKUP_FOLLOW|LOOKUP_POSITIVE|LOOKUP_DIRECTORY, &nd)) error = path_walk(put_old, &nd); 在新的根盤中尋找put_old目錄 if (error) { int blivet; printk(KERN_NOTICE “Trying to unmount old root … “); blivet = do_umount(old_rootmnt, 1, 0); 卸載原始的根盤 if (!blivet) { printk(“okay/n”); return 0; } printk(KERN_ERR “error %d/n”, blivet); return error; } /* FIXME: we should hold i_zombie on nd.dentry */ move_vfnt(old_rootmnt, nd.dentry, nd.mnt, “/dev/root.old”); mntput(old_rootmnt); path_release(&nd); return 0;}#endifstatic struct vfount *add_vfnt(struct nameidata *nd, 在虛擬文件系統(tǒng)中的安裝點 struct dentry *root, 安裝盤的根目錄項 const char *dev_name) 安裝盤名稱{ struct vfount *mnt;

————————————————

版權(quán)聲明:本文為CSDN博主「huanghaibin」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。

原文鏈接:

成都創(chuàng)新互聯(lián)科技有限公司,是一家專注于互聯(lián)網(wǎng)、IDC服務(wù)、應(yīng)用軟件開發(fā)、網(wǎng)站建設(shè)推廣的公司,為客戶提供互聯(lián)網(wǎng)基礎(chǔ)服務(wù)!
創(chuàng)新互聯(lián)(www.cdcxhl.com)提供簡單好用,價格厚道的香港/美國云服務(wù)器和獨立服務(wù)器。創(chuàng)新互聯(lián)——四川成都IDC機房服務(wù)器托管/機柜租用。為您精選優(yōu)質(zhì)idc數(shù)據(jù)中心機房租用、服務(wù)器托管、機柜租賃、大帶寬租用,高電服務(wù)器托管,算力服務(wù)器租用,可選線路電信、移動、聯(lián)通機房等。


文章題目:深入剖析LinuxC編程中的ntohl函數(shù)(linuxcntohl)
當(dāng)前網(wǎng)址:http://www.dlmjj.cn/article/dhiphhp.html