最近在提交cpufreq patch,稍微有点逻辑改动的Rafael都要你test, test。有个改动涉及setpolicy driver,要验证,第一印象就是用qemu。

让我们来看下如何搭环境(initrd=ramdisk):

my linux server(xeon) for building can not access internet,also vb under win is not. install qemu deb offline has too many dependens, forget it, let admin apt-get qemu(qemu-system-x86_64), it’s done.

I have already download the linux-pm git repo, below operations r based on this code.

kernel编译

1.generate .config

make O=out_x86_64/ x86_64_defconfig

btw: gcc is default for x86_64 in xeon.

tj@bsvr:/sys/devices/system/cpu/cpu0/cpufreq$ file /usr/bin/gcc
/usr/bin/gcc: symbolic link to `gcc-4.8'
tj@bsvr:/sys/devices/system/cpu/cpu0/cpufreq$ file /usr/bin/gcc-4.8
/usr/bin/gcc-4.8: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=fd10e59c8b3fd9ff72ecb1586fa83be45e339f7b, stripped

2.make

make O=out_x86_64/ bzImage -j8

遇到了错误:

You are building kernel with non-retpoline compiler.
Please update your compiler.
make[1]: *** [checkbin] Error 1

直接disable RETPOLINE:

arch/x86/Kconfig:
config RETPOLINE
bool "Avoid speculative indirect branches in kernel"
- default y
+ default n

继续又错:

error: Cannot generate ORC metadata for CONFIG_UNWINDER_ORC=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel

我们用menuconfig

make O=out_x86_64/ menuconfig 

改选Frame pointer…

Kernel hacking > Choose kernel unwinder  -> select Frame pointer unwinder

设置ramdisk size为65536 (64MB)

Device Drivers > Block dev > <*> RAM block device support > ()Default RAM disk size

then building is ok.

Kernel: arch/x86/boot/bzImage is ready  (#1)

tj@bsvr:~/work/kernel/linux-pm$ file out_x86_64/arch/x86/boot/bzImage
out_x86_64/arch/x86/boot/bzImage: x86 boot sector

building busybox

1.generate config

make defconfig

2.静态编译

make menuconfig
Busybox setting > --- Build Options > [*] Build Busybox as a static

3.building

make -j4

没有幺蛾子,it’s ok

  LINK    busybox_unstripped
Static linking against glibc, can't use --gc-sections
Trying libraries: crypt m
Library crypt is not needed, excluding it
Library m is needed, can't exclude it (yet)
Final link with: m

btw: my bb version: busybox-1.27.1

4.install

安装到指定目录for later usage:

make CONFIG_PREFIX=~/work/kernel/qemu/x86_64/busybox_install/ install

进去看下:

tj@bsvr:~/work/kernel/qemu/x86_64/busybox_install$ ls -l
total 12
drwxrwxr-x 2 tj tj 4096 Apr 30 12:30 bin
lrwxrwxrwx 1 tj tj 11 Apr 30 12:30 linuxrc -> bin/busybox
drwxrwxr-x 2 tj tj 4096 Apr 30 12:30 sbin
drwxrwxr-x 4 tj tj 4096 Apr 30 12:30 usr

有个linuxrc文件,link到了2.5M的bin/busybox,其他都是link。。。

tj@bsvr:/work/tj/kernel/qemu/x86_64/busybox_install/bin$ ls -lh
total 2.5M
lrwxrwxrwx 1 tj tj 7 Apr 30 12:30 ash -> busybox
lrwxrwxrwx 1 tj tj 7 Apr 30 12:30 base64 -> busybox
-rwxr-xr-x 1 tj tj 2.5M Apr 30 12:30 busybox
lrwxrwxrwx 1 tj tj 7 Apr 30 12:30 cat -> busybox
lrwxrwxrwx 1 tj tj 7 Apr 30 12:30 chattr -> busybox
lrwxrwxrwx 1 tj tj 7 Apr 30 12:30 chgrp -> busybox
lrwxrwxrwx 1 tj tj 7 Apr 30 12:30 chmod -> busybox
lrwxrwxrwx 1 tj tj 7 Apr 30 12:30 chown -> busybox
lrwxrwxrwx 1 tj tj 7 Apr 30 12:30 conspy -> busybox
lrwxrwxrwx 1 tj tj 7 Apr 30 12:30 cp -> busybox
...

制作ramdisk

这里参考别人了,hurry up,不过需要有root权限,只能cp到vb ubuntu下,得压缩后再cp,不然link全部变了real file了,几百M。

另外不要在vb下share的挂载点操作,cp到外面,比如Downloads:

tj@tj-u1404:~/Downloads/mk_ramdisk$ ls
busybox_install etc mk_ramdisk.sh

ok,run mk_ramdisk.h, then show below if successful:

Allocating group tables: done                            
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done

tj@tj-u1404:~/Downloads/mk_ramdisk$ ls
tj@tj-u1404:~/Downloads/mk_ramdisk$ ls
busybox_install etc mk_ramdisk.sh ramdisk ramdisk.gz rootfs tmpfs
tj@tj-u1404:~/Downloads/mk_ramdisk$
tj@tj-u1404:~/Downloads/mk_ramdisk$ ls -lh ramdisk.gz
-rw-rw-r-- 1 tj tj 1.5M Apr 30 03:17 ramdisk.gz

运行qemu x86_64

cp到一个目录:

tj@bsvr:~/work/kernel/qemu/x86_64$ ls
busybox_install busybox_install.tar bzImage ramdisk.gz run.sh

run.sh:

tj@bsvr:~/work/kernel/qemu/x86_64$ cat run.sh 
qemu-system-x86_64 \
-smp 2 \
-m 512M \
-kernel ./bzImage \
-nographic \
-append "root=/dev/ram0 rw rootfstype=ext4 console=ttyS0 init=/linuxrc" \
-initrd ./ramdisk.gz
tj@bsvr:~/work/kernel/qemu/x86_64$

see below, haha:)

[    4.472432] ifconfig (1082) used greatest stack depth: 13824 bytes left

Please press Enter to activate this console.

but no cpufreq:

[root@x86 cpu1]# ls
cache driver node0 subsystem
crash_notes firmware_node online topology
crash_notes_size hotplug power uevent
[root@x86 cpu1]#

退出ctl-A + x

check for intel_pstate

intel_pstate用的就是setpolicy driver。

[root@x86 cpu1]# dmesg | grep "intel"
[ 2.214309] intel_pstate: CPU ID not supported

nd, 不支持,看下代码需要硬件feature支持:

static int __init intel_pstate_init(void)
{
const struct x86_cpu_id *id;
int rc;

if (no_load)
return -ENODEV;

id = x86_match_cpu(hwp_support_ids);
if (id) {
copy_cpu_funcs(&core_funcs);
if (!no_hwp) {
hwp_active++;
hwp_mode_bdw = id->driver_data;
intel_pstate.attr = hwp_cpufreq_attrs;
goto hwp_cpu_matched;
}
} else {
id = x86_match_cpu(intel_pstate_cpu_ids);
if (!id) {
pr_info("CPU ID not supported\n");
return -ENODEV;
}

copy_cpu_funcs((struct pstate_funcs *)id->driver_data);
}
#define ICPU(model, policy) \
{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_APERFMPERF,\
(unsigned long)&policy }

static const struct x86_cpu_id intel_pstate_cpu_ids[] = {
ICPU(INTEL_FAM6_SANDYBRIDGE, core_funcs),
ICPU(INTEL_FAM6_SANDYBRIDGE_X, core_funcs),
ICPU(INTEL_FAM6_ATOM_SILVERMONT, silvermont_funcs),
ICPU(INTEL_FAM6_IVYBRIDGE, core_funcs),
ICPU(INTEL_FAM6_HASWELL_CORE, core_funcs),
ICPU(INTEL_FAM6_BROADWELL_CORE, core_funcs),
ICPU(INTEL_FAM6_IVYBRIDGE_X, core_funcs),
ICPU(INTEL_FAM6_HASWELL_X, core_funcs),
ICPU(INTEL_FAM6_HASWELL_ULT, core_funcs),
ICPU(INTEL_FAM6_HASWELL_GT3E, core_funcs),
ICPU(INTEL_FAM6_BROADWELL_GT3E, core_funcs),
ICPU(INTEL_FAM6_ATOM_AIRMONT, airmont_funcs),
ICPU(INTEL_FAM6_SKYLAKE_MOBILE, core_funcs),
ICPU(INTEL_FAM6_BROADWELL_X, core_funcs),
ICPU(INTEL_FAM6_SKYLAKE_DESKTOP, core_funcs),
ICPU(INTEL_FAM6_BROADWELL_XEON_D, core_funcs),
ICPU(INTEL_FAM6_XEON_PHI_KNL, knl_funcs),
ICPU(INTEL_FAM6_XEON_PHI_KNM, knl_funcs),
ICPU(INTEL_FAM6_ATOM_GOLDMONT, core_funcs),
ICPU(INTEL_FAM6_ATOM_GOLDMONT_PLUS, core_funcs),
ICPU(INTEL_FAM6_SKYLAKE_X, core_funcs),
{}
};

...

#define ICPU_HWP(model, hwp_mode) \
{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_HWP, hwp_mode }

static const struct x86_cpu_id hwp_support_ids[] __initconst = {
ICPU_HWP(INTEL_FAM6_BROADWELL_X, INTEL_PSTATE_HWP_BROADWELL),
ICPU_HWP(INTEL_FAM6_BROADWELL_XEON_D, INTEL_PSTATE_HWP_BROADWELL),
ICPU_HWP(X86_MODEL_ANY, 0),
{}
};

X86_FEATURE_HWP or X86_FEATURE_APERFMPERF,QEMU(x86_64)本身就不支持,即使host支持也不行,歇菜,还有个x86模拟器叫Bochs以后看了,先用real pc…

refer doc