[信息] CM3/CM4内核特权级和非特权(用户)级的详细差别

[复制链接]
25|1
Puchou 发表于 2026-2-4 07:08 | 显示全部楼层 |阅读模式
在Cortex-M内核中,**特权级(Privileged)和非特权级(Unprivileged,也称用户级)**是重要的安全保护机制。以下是它们的详细差别:

1. 权限对比总览

44910698056b5a0daf.png

2. 具体的权限差异
2.1 特殊寄存器访问
void demonstrate_register_access(void) {
    // 以下操作在特权级可以,在非特权级会触发UsageFault:

    // CONTROL寄存器(模式控制)
    __set_CONTROL(0x3);  // 非特权级:故障

    // MSP/PSP切换
    __set_MSP(stack_ptr);  // 非特权级:故障
    __set_PSP(stack_ptr);  // 非特权级:故障

    // 中断控制
    __disable_irq();      // 非特权级:故障(CPSID I)
    __enable_irq();       // 非特权级:故障(CPSIE I)

    // 系统控制块
    SCB->SHCSR = value;   // 非特权级:故障
}


2.2 内存系统权限
void demonstrate_memory_access(void) {
    // MPU(内存保护单元)配置
    MPU->CTRL = 1;        // 非特权级:故障
    MPU->RNR = region;    // 非特权级:故障
    MPU->RBAR = address;  // 非特权级:故障

    // 内存访问限制
    uint32_t system_data = *(uint32_t*)0xE0000000;  // 可能被MPU阻止

    // 外设访问可能被限制
    GPIOA->MODER = value;  // 可能被MPU阻止
}


3. 实际应用场景
场景1:操作系统中的权限分离
// 特权级代码(操作系统内核)
void privileged_kernel_function(void) {
    // 可以配置MPU保护内存区域
    setup_mpu_protection();

    // 可以创建新任务
    create_new_task(user_task_function, user_stack);

    // 可以修改系统配置
    configure_system_clock();
}

// 非特权级代码(用户应用程序)
void user_task_function(void) {
    // 只能访问分配的内存区域
    user_data* data = (user_data*)0x20001000;  // 允许的RAM区域

    // 不能修改系统设置
    // SCB->ICSR = ...;  // 这会触发UsageFault!

    // 需要通过系统调用请求服务
    make_system_call(SVC_OPEN_FILE, filename);
}


场景2:系统调用机制(SVC)
// 用户代码(非特权级)
void user_application(void) {
    // 需要执行特权操作时,使用SVC
    __asm volatile ("SVC #0x10");  // 请求文件打开服务
}

// SVC处理程序(自动提升到特权级)
void SVC_Handler(void) {
    // 进入Handler模式,自动获得特权级

    // 解析SVC编号并执行服务
    uint8_t svc_number = get_svc_number();

    switch(svc_number) {
        case 0x10:
            privileged_file_open();  // 执行实际的特权操作
            break;
    }

    // 返回用户模式
}




4. 权限级别控制
CONTROL寄存器
void demonstrate_control_register(void) {
    uint32_t control = __get_CONTROL();

    // CONTROL[0]: 0=MSP, 1=PSP
    // CONTROL[1]: 0=特权级, 1=非特权级

    printf("当前权限: %s\n",
           (control & 0x02) ? "非特权级" : "特权级");
    printf("当前堆栈: %s\n",
           (control & 0x01) ? "PSP" : "MSP");
}


权限切换示例
// 从特权级切换到非特权级
void switch_to_unprivileged(void) {
    // 前提:当前是特权级

    // 设置进程堆栈指针
    __set_PSP(user_stack_top);

    // 切换到非特权级 + PSP
    __set_CONTROL(0x03);  // Bit0=1(PSP), Bit1=1(非特权级)

    // 必须使用ISB指令
    __ISB();

    // 现在运行在非特权级
    // 不能再修改CONTROL、MSP等特殊寄存器
}

// 从非特权级返回特权级(只能通过异常)
void request_privileged_access(void) {
    // 在非特权级中,只能通过SVC异常返回特权级
    __asm volatile ("SVC #0x20");
}


5. 故障处理
非特权级访问违规
// UsageFault处理程序
void UsageFault_Handler(void) {
    uint32_t cfsr = SCB->CFSR;  // 配置故障状态寄存器

    if (cfsr & (1 << 4)) {  // STKERR: 堆栈操作违规
        printf("非特权级堆栈访问违规!\n");
    }
    if (cfsr & (1 << 3)) {  // UNSTKERR: 异常返回时堆栈违规  
        printf("异常返回堆栈违规!\n");
    }
    if (cfsr & (1 << 1)) {  // UNDEFINSTR: 未定义指令
        printf("执行了特权指令!\n");
    }

    // 处理故障...
    while(1);
}


6. 实际工程应用
嵌入式操作系统设计
// 操作系统启动流程
void os_startup(void) {
    // 1. 启动时是特权级(Thread模式 + MSP)

    // 2. 初始化MPU,保护系统区域
    mpu_init();

    // 3. 创建用户任务
    task_t* user_task = create_task(user_app, user_stack);

    // 4. 切换到用户模式运行第一个任务
    switch_to_user_task(user_task);
}

// 用户任务运行环境
void user_app(void) {
    // 运行在:Thread模式 + PSP + 非特权级

    while(1) {
        // 应用程序逻辑
        process_data();

        // 需要系统服务时使用SVC
        if (need_file_access) {
            __asm volatile ("SVC #0x30");
        }
    }
}



安全检查函数
// 验证当前权限级别
bool is_privileged(void) {
    uint32_t control = __get_CONTROL();
    return ((control & 0x02) == 0);
}

// 安全执行特权操作
void safe_privileged_operation(void (*func)(void)) {
    if (is_privileged()) {
        func();  // 直接执行
    } else {
        // 非特权级:通过SVC调用
        register void (*f)(void) asm("r0") = func;
        __asm volatile ("SVC #0x40" : : "r" (f));
    }
}


7. 总结
特权级的优势

完全系统访问权限

可以配置保护机制

适合操作系统内核、系统服务
非特权级的优势

提高系统安全性

防止应用程序破坏系统

支持多任务隔离
典型应用
特权级:操作系统内核、设备驱动、启动代码
非特权级:用户应用程序、第三方库、不信任的代码
这种权限分离机制是构建安全、稳定嵌入式系统的基础,特别是在运行复杂应用程序或使用第三方代码时尤为重要。
————————————————
版权声明:本文为CSDN博主「Just_BLei」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u011764302/article/details/154021540

heisexingqisi 发表于 2026-2-6 14:33 | 显示全部楼层
Cortex-A53 属于 ARMv8-A 架构(支持 AArch32/AArch64),CM3/CM4(树莓派 Compute Module)实际运行在 AArch32 模式下,特权级 / 非特权级的划分基于 Exception Level (EL) 和 Processor Mode
您需要登录后才可以回帖 登录 | 注册

本版积分规则

137

主题

384

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部
0