用乌班图编译ram
① ubuntu编译osmocombb完要多久
ubuntu编译GNUARM以及OsmocomBB环境方法如下,时间的话看你代码速度啦
以下所有操作基于Ubuntu linux下,所以基于Ubuntu、Debian等Linux版本均可使用。
一、以Root权限进行接下来的所有操作:
$ sudo -s
二、安装编译osmocomBB所需的软件包:
$ aptitude install libtool shtool autoconf git-core pkg-config make gcc
三、下载所需要的GnuARM ToolChain
基于x86架构
$ wget http://gnuarm.com/bu-2.15_gcc-3.4.3-c-c++-java_nl-1.12.0_gi-6.1.tar.bz2 网络网盘
$ tar xf bu-2.15_gcc-3.4.3-c-c++-java_nl-1.12.0_gi-6.1.tar.bz2
$ mv gnuarm-* ~/gnuarm
基于64位架构
$ wget http://www.gnuarm.com/bu-2.16.1_gcc-4.0.2-c-c++_nl-1.14.0_gi-6.4_x86-64.tar.bz2 网络网盘
$ tar xf bu-2.16.1_gcc-4.0.2-c-c++_nl-1.14.0_gi-6.4_x86-64.tar.bz2
$ mv gnuarm-* ~/gnuarm
这样子就已经完成了关于OsmocomBB的交叉编译环境的搭建,剩下就是最关键的设置环境变量
$ export PATH=~/gnuarm/bin:$PATH
建议是直接编辑~/.bashrc的内容,把上面的这个段话直接加到最后。
四、编译libosmocore:
$ git clone git://git.osmocom.org/libosmocore.git
$ cd libosmocore/
$ autoreconf -i
$ ./configure
$ make
$ make install
$ cd ..
$ ldconfig
ldconfig命令一定不要忘记执行,否则osmocomBB编译后运行时会出现找不到libosmocore.so.4的错误。
五、编译OsmocomBB:
$ git clone git://git.osmocom.org/osmocom-bb.git
$ cd osmocom-bb
$ git checkout --track origin/luca/gsmmap
$ cd src
$ make
基本上已经完成所有的编译操作了!Enjoy你的玩具吧!
使用OsmocomBB
首先我们需要在刷写固件之间完成以下几个手动操作,以便接下来的其他操作。因为摩托罗拉C118的数据连接线是用2.5mm音频接口的,所以连接方面大家要注意的是:
连接线接口的小缺陷
红色框住的地方可能会导致大家在误以为接口已经完全和手机接口衔接了,但在刷机的时候没有任何反应。所以这个部分需要大家自己去削一下的。
连接线与TTL的接法
黑/黄:GND
红:TX
白:RX
以上的接法是针对我们RadioWar淘宝店所出售的CP2102以及FT232rl,而基于淘宝其他的产品可能会在TX和RX部分需要反接,大家要记住。有些朋友会说为什么我们不建议PL2303,那是PL2303只有标准的波特率,所以无法进行任何调制,在真正功能固件上使用会出现很大的问题。所以我们不建议使用PL2303
当我们处理完以上的操作之后,就在osmocomBB套件目录下进行相关固件刷写操作,请记住这个操作过程只是临时性的,固件只是以RAM TO ROM的途径下进行临时刷写,关机后原有的摩托罗拉系统依然会存在的。
cd ~/osmocom-bb/src/host/osmocon/
启动osmocon刷写所需要的固件,通常大家都是直接刷写Layer1的固件。
./osmocon -m c123xor -p /dev/ttyUSB0 ../../target/firmware/board/compal_e88/layer1.compalram.bin
看清楚c123xor是基于C118的,非C118的手机请不要使用这个,并且记住C118的固件目录就是compal_e88,在输入以上命令之前,手机必须连接好连接线以及TTL,并且确保手机必须为关键状态。命令输入完成后,当前命令窗口会出现以下类似信息:
got 1 bytes from modem, data looks like: 2f /
got 1 bytes from modem, data looks like: 00 .
got 1 bytes from modem, data looks like: 1b .
got 4 bytes from modem, data looks like: f6 02 00 41 ...A
got 1 bytes from modem, data looks like: 01 .
got 1 bytes from modem, data looks like: 40 @
出现以上信息后,直接轻按手机的红色开机键,只需点亮机器而不需要进入手机的系统!!!这样子信息状态会显示类似以下的信息:
Received PROMPT1 from phone, responding with CMD
read_file(../../target/firmware/board/compal_e88/layer1.compalram.bin):file_size=56016,hdr_len=4,dnload_len=56023
got 1 bytes from modem, data looks like: 1b .
got 1 bytes from modem, data looks like: f6 .
got 1 bytes from modem, data looks like: 02 .
got 1 bytes from modem, data looks like: 00 .
got 1 bytes from modem, data looks like: 41 A
got 1 bytes from modem, data looks like: 02 .
got 1 bytes from modem, data looks like: 43 C
Received PROMPT2 from phone, starting download handle_write(): 4096 bytes (4096/56023)
handle_write(): 4096 bytes (8192/56023)
handle_write(): 4096 bytes (12288/56023)
handle_write(): 4096 bytes (16384/56023)
handle_write(): 4096 bytes (20480/56023)
handle_write(): 4096 bytes (24576/56023)
handle_write(): 4096 bytes (28672/56023)
handle_write(): 4096 bytes (32768/56023)
handle_write(): 4096 bytes (36864/56023)
handle_write(): 4096 bytes (40960/56023)
handle_write(): 4096 bytes (45056/56023)
handle_write(): 4096 bytes (49152/56023)
handle_write(): 4096 bytes (53248/56023)
handle_write(): 2775 bytes (56023/56023)
handle_write(): finished
got 1 bytes from modem, data looks like: 1b .
got 1 bytes from modem, data looks like: f6 .
got 1 bytes from modem, data looks like: 02 .
got 1 bytes from modem, data looks like: 00 .
got 1 bytes from modem, data looks like: 41 A
got 1 bytes from modem, data looks like: 03 .
got 1 bytes from modem, data looks like: 42 B
Received DOWNLOAD ACK from phone, your code is running now!
battery_compal_e88_init: starting up
看到以上的信息就证明你的固件刷写操作已经成功了,下来的操作可以是扫描基站或者其他简单而快速的方法:
扫描基站
~/cell_logger/osmocom-bb/src/host/layer23/src/misc/cell_log -O
扫描某一个基站,例如30
~/cell_logger/osmocom-bb/src/host/layer23/src/misc/ccch_scan -i 127.0.0.1 -a 30
将扫描基站的日志保存到本地
mpcap -i lo -w ~/cell_logger/mobilelog/Cell.log
打开WireShark实时读取相关的信息
sudo wireshark -k -i lo -f 'port 4729'
② Linux内核源码如何编译Ubuntu源代码在哪里呢
编译linux内核步骤:
1、安装内核
如果内核已经安装(/usr/src/目录有linux子目录),跳过。如果没有安装,在光驱中放入linux安装光盘,找到kernel-source-2.xx.xx.rpm文件(xx代表数字,表示内核的版本号),比如RedHat linux的RPMS目录是/RedHat/RPMS/目录,然后使用命令rpm -ivh kernel-source-2.xx.xx.rpm安装内核。如果没有安装盘,可以去各linux厂家站点或者www.kernel.org下载。
2、清除从前编译内核时残留的.o 文件和不必要的关联
cd /usr/src/linux
make mrproper
3、配置内核,修改相关参数,请参考其他资料
在图形界面下,make xconfig;字符界面下,make menuconfig。在内核配置菜单中正确设置个内核选项,保存退出
4、正确设置关联文件
make dep
5、编译内核
对于大内核(比如需要SCSI支持),make bzImage
对于小内核,make zImage
6、编译模块
make moles
7、安装模块
make moles_install
8、使用新内核
把/usr/src/linux/arch/i386/boot/目录内新生成的内核文件bzImage/zImage拷贝到/boot目录,然后修改/etc/lilo.conf文件,加一个启动选项,使用新内核bzImage/zImage启动。格式如下:
boot=/dev/hda
map=/boot/map
install=/boot/boot.b
prompt
timeout=50
linear
default=linux-new ### 告诉lilo缺省使用新内核启动linux ###
append="mem=256M"
image=/boot/vmlinuz-2.2.14-5.0
label=linux
read-only
root=/dev/hda5
image=/boot/bzImage(zImage)
label=linux-new
read-only
root=/dev/hda5
保留旧有的启动选项可以保证新内核不能引导的情况,还可以进入linux进行其他操作。保存退出后,不要忘记了最重要的一步,运行/sbin/lilo,使修改生效。
9、重新生成ram磁盘
如果您的系统中的/etc/lilo.conf没有使用了ram磁盘选项initrd,略过。如果您的系统中的/etc/lilo.conf使用了ram磁盘选项initrd,使用mkinitrd initrd-内核版本号,内核版本号命令重新生成ram磁盘文件,例如我的Redhat 6.2:
mkinitrd initrd-2.2.14-5.0 2.2.14-5.0
之后把/etc/lilo.conf中的initrd指向新生成的initrd-2.2.14-5.0文件:
initrd=/boot/initrd-2.2.14-5.0
ram磁盘能使系统性能尽可能的优化,具体参考/usr/src/linux/Documents/initrd.txt文件
10、重新启动,OK!
③ 怎么在ubuntu下开发stm32
环境:
ubuntu 13.10
stm32f103zet6
一、STM 32 GCC 安装
stm32 属于arm cortex-m系列thumb指令集,所以给arm用的arm-none-eabi就可以了,首先是下载
下载地址:
https://launchpad.net/gcc-arm-embedded/+download
下载其中的gcc-arm-none-eabi-version-linux.tar.bz2
把该编译器添加到用户的环境中:
④ Ubuntu编译了新的内核,进入新内核时一直显示载入Linux 5.6.7,载入初始化内存盘咋回事
概述====1)当内核配置了内存盘时, 内核在初始化时可以将软盘加载到内存盘中作为根盘.当同时配置了初始化内存盘(Initail RAM Disk)时, 内核在初始化时可以在安装主盘之前,通过引导程序所加载的initrd文件建立一个内存初始化盘, 首先将它安装成根文件系统, 然后执行其根目录下的linuxrc 文件,可用于在安装主盘之前加载一些内核模块. 等到linuxrc 程序退出后, 再将主盘安装成根文件系统,并将内存初始化盘转移安装到其/initrd目录下.2)当主盘就是initrd所生成的内存初始化盘时, 不再进行重新安装,在DOS下用loadlin加载的抢救盘就是这种工作方式.3)引导程序所加载的initrd为文件系统的映象文件, 可以是gzip压缩的, 也可以是不压缩的.能够识别的文件系统有minix,ext2,romfs三种.4)当内核的根盘为软盘时,内核初始化时会测试软盘的指定部位是否存在文件系统或压缩文件映象, 然后将之加载或解压到内存盘中作为根盘. 这是单张抢救软盘的工作方式.有关代码========; init/main.c#ifdef CONFIG_BLK_DEV_INITRDkdev_t real_root_dev; 启动参数所设定的根盘设备#endifasmlinkage 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 < min_low_pfn << PAGE_SHIFT) { ; min_low_pfn为内核末端_end所开始的物理页号,initrd_start,initrd_end在rd.c中定义 printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - " "disabling it./n",initrd_start,min_low_pfn << PAGE_SHIFT); initrd_start = 0; }#endif ... kernel_thread(init, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL); 创建init进程 unlock_kernel(); current->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) printk("Warning: unable to open an initial console./n"); (void) p(0); (void) p(0); /* * We try each of these until one succeeds. * * The Bourne shell can be used instead of init if we are * trying to recover a really broken machine. */ if (execute_command) execve(execute_command,argv_init,envp_init); execve("/sbin/init",argv_init,envp_init); execve("/etc/init",argv_init,envp_init); execve("/bin/init",argv_init,envp_init); execve("/bin/sh",argv_init,envp_init); panic("No init found. Try passing init= option to kernel.");}static void __init do_basic_setup(void){#ifdef CONFIG_BLK_DEV_INITRD int real_root_mountflags;#endif ...#ifdef CONFIG_BLK_DEV_INITRD real_root_dev = ROOT_DEV; ROOT_DEV为所请求根文件系统的块设备 real_root_mountflags = root_mountflags; if (initrd_start && mount_initrd) root_mountflags &= ~MS_RDONLY; else mount_initrd =0; #endif start_context_thread(); do_initcalls(); 会调用partition_setup()中加载内存盘 /* .. filesystems .. */ filesystem_setup(); /* Mount the root filesystem.. */ mount_root(); mount_devfs_fs ();#ifdef CONFIG_BLK_DEV_INITRD root_mountflags = real_root_mountflags; if (mount_initrd && ROOT_DEV != real_root_dev && MAJOR(ROOT_DEV) == RAMDISK_MAJOR && MINOR(ROOT_DEV) == 0) { ; 如果当前根盘为initrd所建立的内存盘 int error; int i, pid; pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD); 创建新的任务去执行程序/linuxrc if (pid>0) while (pid != wait(&i)); 等待linuxrc进程退出 if (MAJOR(real_root_dev) != RAMDISK_MAJOR || MINOR(real_root_dev) != 0) { ; 如果原来的根盘不是0号内存盘,则使用原来的根文件系统, ; 并且将内存盘转移到其/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[] = { "linuxrc", NULL, }; close(0);close(1);close(2); setsid(); 设置新的session号 (void) open("/dev/console",O_RDWR,0); (void) p(0); (void) p(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设置的参数#define LOADER_TYPE (*(unsigned char *) (PARAM+0x210))#define INITRD_START (*(unsigned long *) (PARAM+0x218)) 初始化盘映象起始物理地址#define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c)) 初始化盘字节数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 <= (max_low_pfn << PAGE_SHIFT)) { ; max_low_pfn表示内核空间1G范围以下最大允许的物理页号 reserve_bootmem(INITRD_START, INITRD_SIZE); initrd_start = INITRD_START ? INITRD_START + PAGE_OFFSET : 0; 转变为内核逻辑地址 initrd_end = initrd_start+INITRD_SIZE; } else { printk("initrd extends beyond end of memory " "(0x%08lx > 0x%08lx)/ndisabling initrd/n", INITRD_START + INITRD_SIZE, max_low_pfn << PAGE_SHIFT); initrd_start = 0; } }#endif ...}; fs/partitions/check.c:int __init partition_setup(void){ device_init(); 包含ramdisk设备的初始化#ifdef CONFIG_BLK_DEV_RAM#ifdef CONFIG_BLK_DEV_INITRD if (initrd_start && mount_initrd) initrd_load(); ;如果启动时加载了initrd文件,则用它去初始化根内存盘 else#endif rd_load(); 如果内核配置了内存盘并且根盘指定为软盘则试图将软盘加载为根内存盘#endif return 0;}__initcall(partition_setup);; drivers/block/rd.c:int rd_doload; /* 1 = load RAM disk, 0 = don't load */int rd_prompt = 1; /* 1 = prompt for RAM disk, 0 = don't prompt */int rd_image_start; /* starting block # of image */#ifdef CONFIG_BLK_DEV_INITRDunsigned long initrd_start, initrd_end;int mount_initrd = 1; /* zero if initrd should not be mounted */int initrd_below_start_ok;void __init rd_load(void){ rd_load_disk(0); 加载到0号内存盘}void __init rd_load_secondary(void){ rd_load_disk(1); 加载到1号内存盘}static void __init rd_load_disk(int n){#ifdef CONFIG_BLK_DEV_INITRD extern kdev_t real_root_dev;#endif if (rd_doload == 0) return; if (MAJOR(ROOT_DEV) != FLOPPY_MAJOR 如果根盘是不软盘#ifdef CONFIG_BLK_DEV_INITRD && MAJOR(real_root_dev) != FLOPPY_MAJOR#endif ) return; if (rd_prompt) {#ifdef CONFIG_BLK_DEV_FD floppy_eject();#endif#ifdef CONFIG_MAC_FLOPPY if(MAJOR(ROOT_DEV) == FLOPPY_MAJOR) swim3_fd_eject(MINOR(ROOT_DEV)); else if(MAJOR(real_root_dev) == FLOPPY_MAJOR) swim3_fd_eject(MINOR(real_root_dev));#endif printk(KERN_NOTICE "VFS: Insert root floppy disk to be loaded into RAM disk and press ENTER/n"); wait_for_keypress(); } rd_load_image(ROOT_DEV,rd_image_start, n); 将根软盘加载到n号内存盘}void __init initrd_load(void){ ; 使用initrd设备盘作为源盘去建立内存根盘 rd_load_image(MKDEV(MAJOR_NR, INITRD_MINOR),rd_image_start,0);}static void __init rd_load_image(kdev_t device, int offset, int unit){ struct inode *inode, *out_inode; struct file infile, outfile; struct dentry in_dentry, out_dentry; mm_segment_t fs; kdev_t ram_device; int nblocks, i; char *buf; unsigned short rotate = 0; unsigned short devblocks = 0; char rotator[4] = { '|' , '/' , '-' , '//' }; ram_device = MKDEV(MAJOR_NR, unit); 建立输出内存盘设备号 if ((inode = get_empty_inode()) == NULL) return; memset(&infile, 0, sizeof(infile)); memset(&in_dentry, 0, sizeof(in_dentry)); infile.f_mode = 1; /* read only */ infile.f_dentry = &in_dentry; in_dentry.d_inode = inode; infile.f_op = &def_blk_fops; init_special_inode(inode, S_IFBLK | S_IRUSR, kdev_t_to_nr(device)); if ((out_inode = get_empty_inode()) == NULL) goto free_inode; memset(&outfile, 0, sizeof(outfile)); memset(&out_dentry, 0, sizeof(out_dentry)); outfile.f_mode = 3; /* read/write */ outfile.f_dentry = &out_dentry; out_dentry.d_inode = out_inode; outfile.f_op = &def_blk_fops; init_special_inode(out_inode, S_IFBLK | S_IRUSR | S_IWUSR, kdev_t_to_nr(ram_device)); if (blkdev_open(inode, &infile) != 0) 打开输入盘文件 goto free_inode; if (blkdev_open(out_inode, &outfile) != 0) 打开输出内存盘文件 goto free_inodes; fs = get_fs(); set_fs(KERNEL_DS); nblocks = identify_ramdisk_image(device, &infile, offset); 鉴定输入盘的文件类型 if (nblocks < 0) 出错 goto done; if (nblocks == 0) { 表示输入盘是gzip文件#ifdef BUILD_CRAMDISK if (crd_load(&infile, &outfile) == 0) 将输入盘文件解压到输出盘文件中去 goto successful_load;#else printk(KERN_NOTICE "RAMDISK: Kernel does not support compressed " "RAM disk images/n");#endif goto done; } /* * NOTE NOTE: nblocks suppose that the blocksize is BLOCK_SIZE, so * rd_load_image will work only with filesystem BLOCK_SIZE wide! * So make sure to use 1k blocksize while generating ext2fs * ramdisk-images. */ if (nblocks > (rd_length[unit] >> BLOCK_SIZE_BITS)) { ; 如果输入盘的尺寸超过了输出内存盘的允许尺寸 printk("RAMDISK: image too big! (%d/%ld blocks)/n", nblocks, rd_length[unit] >> BLOCK_SIZE_BITS); goto done; } /* * OK, time to 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[MAJOR(device)]) devblocks = blk_size[MAJOR(device)][MINOR(device)]; 取输入盘的容量#ifdef CONFIG_BLK_DEV_INITRD if (MAJOR(device) == MAJOR_NR && MINOR(device) == INITRD_MINOR) devblocks = nblocks; 如果输入是初始化内存盘,则盘的容量为它的实际尺寸#endif if (devblocks == 0) { printk(KERN_ERR "RAMDISK: could not determine device size/n"); goto done; } printk(KERN_NOTICE "RAMDISK: Loading %d blocks [%d disk%s] into ram disk... ", nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : ""); for (i=0; i < nblocks; i++) { if (i && (i % devblocks == 0)) { printk("done disk #%d./n", i/devblocks); rotate = 0; invalidate_buffers(device); 使输入盘设备缓冲区无效 if (infile.f_op->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 & 0x3]); rotate++; }#endif } printk("done./n"); kfree(buf);successful_load: invalidate_buffers(device); ROOT_DEV = MKDEV(MAJOR_NR, unit); 将根盘设备设置为当前加载的内存盘 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 *minixsb; struct ext2_super_block *ext2sb; struct romfs_super_block *romfsb; int nblocks = -1; unsigned char *buf; buf = kmalloc(size, GFP_KERNEL); if (buf == 0) return -1; minixsb = (struct minix_super_block *) buf; ext2sb = (struct ext2_super_block *) buf; romfsb = (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字节 /* * If it matches the gzip magic numbers, return -1 */ if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 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 (romfsb->word0 == ROMSB_WORD0 && romfsb->word1 == ROMSB_WORD1) { printk(KERN_NOTICE "RAMDISK: romfs filesystem found at block %d/n", start_block); nblocks = (ntohl(romfsb->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 (minixsb->s_magic == MINIX_SUPER_MAGIC || minixsb->s_magic == MINIX_SUPER_MAGIC2) { printk(KERN_NOTICE "RAMDISK: Minix filesystem found at block %d/n", start_block); nblocks = minixsb->s_nzones << minixsb->s_log_zone_size; goto done; } /* Try ext2 */ if (ext2sb->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(ext2sb->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 * sb; struct vfsmount *vfsmnt; struct block_device *bdev = NULL; mode_t mode; int retval; void *handle; char path[64]; int path_start = -1;#ifdef CONFIG_BLK_DEV_FD if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) { 当根盘还是软盘,表示没有加载过内存盘#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 al initrd/ramload setup */ ; 只有当加载了initrd但没有释放到内存盘中(mount_inird=0)才有可能到这一步 if(rd_doload==2) rd_load_secondary(); 加载另一张软盘到1号内存盘作为根盘 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_RDONLY)) mode |= FMODE_WRITE; retval = blkdev_get(bdev, mode, 0, BDEV_FS); if (retval == -EROFS) { root_mountflags |= MS_RDONLY; 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); sb = get_super(ROOT_DEV); 取根盘的超级块 if (sb) { fs_type = sb->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; 根文件系统必须依赖于块设备 if (!try_inc_mod_count(fs_type->owner)) continue; 当文件系统模块正在删除过程中 read_unlock(&file_systems_lock); sb = read_super(ROOT_DEV,bdev,fs_type,root_mountflags,NULL,1);建立根盘的超级块结构 if (sb) goto mount_it; read_lock(&file_systems_lock); put_filesystem(fs_type); 释放对文件系统模块的引用 } 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, (sb->s_flags & MS_RDONLY) ? " 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); vfsmnt = add_vfsmnt(NULL, sb->s_root, path + path_start); } else vfsmnt = add_vfsmnt(NULL, sb->s_root, "/dev/root"); 建立根盘的安装结构 /* FIXME: if something will try to umount us right now... */ if (vfsmnt) { set_fs_root(current->fs, vfsmnt, sb->s_root); 设置当前进程的根盘和根目录 set_fs_pwd(current->fs, vfsmnt, sb->s_root); 设置当前进程的当前盘和当前目录 if (bdev) bdput(bdev); /* sb holds a reference */ return; } panic("VFS: add_vfsmnt failed for root fs");}#ifdef CONFIG_BLK_DEV_INITRDint __init change_root(kdev_t new_root_dev,const char *put_old){ 以new_root_dev作为根盘重新安装根文件系统,原来的根转移到put_old目录下 struct vfsmount *old_rootmnt; struct nameidata devfs_nd, nd; int error = 0; read_lock(¤t->fs->lock); old_rootmnt = mntget(current->fs->rootmnt); 取当前进程的根盘安装结构 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_sb->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(); 改变根盘设备重新安装根文件系统#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_vfsmnt(old_rootmnt, nd.dentry, nd.mnt, "/dev/root.old"); mntput(old_rootmnt); path_release(&nd); return 0;}#endifstatic struct vfsmount *add_vfsmnt(struct nameidata *nd, 在虚拟文件系统中的安装点 struct dentry *root, 安装盘的根目录项 const char *dev_name) 安装盘名称{ struct vfsmount *mnt;
————————————————
版权声明:本文为CSDN博主“huanghaibin”的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/huanghaibin/java/article/details/478215
⑤ 乌班图怎么编译JAVA
基本区别不大