diff --git a/.vscode/launch.json b/.vscode/launch.json index 04fe2fa5f..461e21b5a 100755 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -45,9 +45,9 @@ "environment": [], "externalConsole": false, // "miDebuggerPath": "/opt/homebrew/bin/arm-none-eabi-gdb", - "miDebuggerPath": "/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-gdb", - // "miDebuggerPath": "/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/bin/arm-none-eabi-gdb", - "miDebuggerServerAddress": "127.0.0.1:3333", + // "miDebuggerPath": "/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-gdb", + "miDebuggerPath": "/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/bin/arm-none-eabi-gdb", + "miDebuggerServerAddress": "127.0.0.1:3334", "MIMode": "gdb", "setupCommands": [ { diff --git a/install.sh b/install.sh new file mode 100644 index 000000000..419b85bef --- /dev/null +++ b/install.sh @@ -0,0 +1,496 @@ +#!/bin/bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin +export PATH +LANG=en_US.UTF-8 + + +echo " ++---------------------------------------------------------------------- +| Bt-WebPanel 5.x FOR Ubuntu/Debian ++---------------------------------------------------------------------- +| Copyright © 2015-2018 BT-SOFT(http://www.bt.cn) All rights reserved. ++---------------------------------------------------------------------- +| The WebPanel URL will be http://SERVER_IP:8888 when installed. ++---------------------------------------------------------------------- +" +deepinSys=`cat /etc/issue` +if [[ "${deepinSys}" =~ eepin ]]; then + isroot='' + if [ `whoami` != "root" ];then + isroot='sudo ' + fi + if [ -f "/etc/init.d/bt" ]; then + password=`${isroot}cat /www/server/panel/default.pl` + port=`${isroot}cat /www/server/panel/data/port.pl` + echo -e "==================================================================" + echo -e "Bt-Panel: http://localhost:$port" + echo -e "默认账户: admin" + echo -e "默认密码: $password" + echo -e "==================================================================" + echo -e "正在尝试打开浏览器..." + if [ -f "/opt/google/chrome/chrome" ]; then + ${isroot}/opt/google/chrome/chrome --no-sandbox http://localhost:$port + exit; + fi + if [ -f "/usr/lib/firefox/firefox" ]; then + /usr/lib/firefox/firefox http://localhost:$port + exit; + fi + echo -e "找不到chrome/firefox浏览器,请自行打开浏览器访问宝塔面板: http://loshost:$port" + exit; + + fi +fi +if [ `whoami` != "root" ];then + echo -e "\033[31mError: Please run the script with root privileges on Ubuntu, for example: sudo bash install.sh\033[0m"; + exit; +fi + +#自动选择下载节点 +get_node_url(){ + nodes=(http://125.88.182.172:5880 http://103.224.251.67 http://128.1.164.196 http://download.bt.cn); + i=1; + if [ ! -f /bin/curl ];then + if [ -f /usr/local/curl/bin/curl ];then + ln -sf /usr/local/curl/bin/curl /bin/curl + else + yum install curl -y + fi + fi + for node in ${nodes[@]}; + do + start=`date +%s.%N` + result=`curl -sS --connect-timeout 3 -m 60 $node/check.txt` + if [ $result = 'True' ];then + end=`date +%s.%N` + start_s=`echo $start | cut -d '.' -f 1` + start_ns=`echo $start | cut -d '.' -f 2` + end_s=`echo $end | cut -d '.' -f 1` + end_ns=`echo $end | cut -d '.' -f 2` + time_micro=$(( (10#$end_s-10#$start_s)*1000000 + (10#$end_ns/1000 - 10#$start_ns/1000) )) + time_ms=$(($time_micro/1000)) + values[$i]=$time_ms; + urls[$time_ms]=$node + i=$(($i+1)) + fi + done + j=5000 + for n in ${values[@]}; + do + if [ $j -gt $n ];then + j=$n + fi + done + if [ $j = 5000 ];then + NODE_URL='http://download.bt.cn'; + else + NODE_URL=${urls[$j]} + fi + +} + +echo '---------------------------------------------'; +echo "Selected download node..."; +get_node_url +download_Url=$NODE_URL +echo "Download node: $download_Url"; +echo '---------------------------------------------'; +setup_path=/www +port='8888' +if [ -f $setup_path/server/panel/data/port.pl ];then + port=`cat $setup_path/server/panel/data/port.pl` +fi + +while [ "$go" != 'y' ] && [ "$go" != 'n' ] +do + read -p "Do you want to install Bt-Panel to the $setup_path directory now?(y/n): " go; +done + +if [ "$go" = 'n' ];then + exit; +fi +startTime=`date +%s` + +#数据盘自动分区 +fdiskP(){ + + for i in `cat /proc/partitions|grep -v name|grep -v ram|awk '{print $4}'|grep -v '^$'|grep -v '[0-9]$'|grep -e 'vd' -e 'sd' -e 'xv'`; + do + #判断/www是否被挂载 + isR=`df -P|grep $setup_path` + if [ "$isR" != "" ];then + echo 'Warning: The /www directory has been mounted.' + return; + fi + #判断是否存在未分区磁盘 + isP=`fdisk -l /dev/$i |grep -v 'bytes'|grep "$i[1-9]*"` + if [ "$isP" = "" ];then + #开始分区 + fdisk -S 56 /dev/$i << EOF +n +p +1 + + +wq +EOF + + sleep 5 + #检查是否分区成功 + checkP=`fdisk -l /dev/$i|grep "/dev/${i}1"` + if [ "$checkP" != "" ];then + #格式化分区 + mkfs.ext4 /dev/${i}1 + mkdir $setup_path + #挂载分区 + sed -i "/\/dev\/${i}1/d" /etc/fstab + echo "/dev/${i}1 $setup_path ext4 defaults 0 0" >> /etc/fstab + mount -a + df -h + fi + else + #判断是否存在Windows磁盘分区 + isN=`fdisk -l /dev/$i|grep -v 'bytes'|grep -v "NTFS"|grep -v "FAT32"` + if [ "$isN" = "" ];then + echo 'Warning: The Windows partition was detected. For your data security, Mount manually.'; + return; + fi + + #挂载已有分区 + checkR=`df -P|grep "/dev/$i"` + if [ "$checkR" = "" ];then + mkdir $setup_path + sed -i "/\/dev\/${i}1/d" /etc/fstab + echo "/dev/${i}1 $setup_path ext4 defaults 0 0" >> /etc/fstab + mount -a + df -h + fi + + #清理不可写分区 + echo 'True' > $setup_path/checkD.pl + if [ ! -f $setup_path/checkD.pl ];then + sed -i "/\/dev\/${i}1/d" /etc/fstab + mount -a + df -h + else + rm -f $setup_path/checkD.pl + fi + fi + done +} +#fdiskP + +ln -sf bash /bin/sh +apt-get install ruby -y +apt-get update -y +apt-get install lsb-release -y +#apt-get install ntp ntpdate -y +#/etc/init.d/ntp stop +#update-rc.d ntp remove +#cat >>~/.profile<&1|awk '{print $2}') +pVersion=${tmp:0:3} + +Install_setuptools() +{ + if [ ! -f "/usr/bin/easy_install" ];then + wget -O setuptools-33.1.1.zip $download_Url/install/src/setuptools-33.1.1.zip -T 10 + unzip setuptools-33.1.1.zip + rm -f setuptools-33.1.1.zip + cd setuptools-33.1.1 + python setup.py install + cd .. + rm -rf setuptools-33.1.1 + fi + + if [ ! -f "/usr/bin/easy_install" ];then + echo '================================================='; + echo -e "\033[31msetuptools installation failed. \033[0m"; + exit; + fi +} +Install_Pillow() +{ + isSetup=`python -m PIL 2>&1|grep package` + if [ "$isSetup" = "" ];then + wget -O Pillow-3.2.0.zip $download_Url/install/src/Pillow-3.2.0.zip -T 10 + unzip Pillow-3.2.0.zip + rm -f Pillow-3.2.0.zip + cd Pillow-3.2.0 + python setup.py install + cd .. + rm -rf Pillow-3.2.0 + fi + isSetup=`python -m PIL 2>&1|grep package` + if [ "$isSetup" = "" ];then + echo '================================================='; + echo -e "\033[31mPillow installation failed. \033[0m"; + exit; + fi +} + +Install_psutil() +{ + isSetup=`python -m psutil 2>&1|grep package` + if [ "$isSetup" = "" ];then + wget -O psutil-5.2.2.tar.gz $download_Url/install/src/psutil-5.2.2.tar.gz -T 10 + tar xvf psutil-5.2.2.tar.gz + rm -f psutil-5.2.2.tar.gz + cd psutil-5.2.2 + python setup.py install + cd .. + rm -rf psutil-5.2.2 + fi + isSetup=`python -m psutil 2>&1|grep package` + if [ "$isSetup" = "" ];then + echo '================================================='; + echo -e "\033[31mpsutil installation failed. \033[0m"; + exit; + fi +} + +Install_mysqldb() +{ + isSetup=`python -m MySQLdb 2>&1|grep package` + if [ "$isSetup" = "" ];then + wget -O MySQL-python-1.2.5.zip $download_Url/install/src/MySQL-python-1.2.5.zip -T 10 + unzip MySQL-python-1.2.5.zip + rm -f MySQL-python-1.2.5.zip + cd MySQL-python-1.2.5 + python setup.py install + cd .. + rm -rf MySQL-python-1.2.5 + fi + +} + +Install_chardet() +{ + isSetup=`python -m chardet 2>&1|grep package` + if [ "$isSetup" = "" ];then + wget -O chardet-2.3.0.tar.gz $download_Url/install/src/chardet-2.3.0.tar.gz -T 10 + tar xvf chardet-2.3.0.tar.gz + rm -f chardet-2.3.0.tar.gz + cd chardet-2.3.0 + python setup.py install + cd .. + rm -rf chardet-2.3.0 + fi + isSetup=`python -m chardet 2>&1|grep package` + if [ "$isSetup" = "" ];then + echo '================================================='; + echo -e "\033[31mchardet installation failed. \033[0m"; + exit; + fi +} + +Install_webpy() +{ + isSetup=`python -m web 2>&1|grep package` + if [ "$isSetup" = "" ];then + wget -O web.py-0.38.tar.gz $download_Url/install/src/web.py-0.38.tar.gz -T 10 + tar xvf web.py-0.38.tar.gz + rm -f web.py-0.38.tar.gz + cd web.py-0.38 + python setup.py install + cd .. + rm -rf web.py-0.38 + fi + + isSetup=`python -m web 2>&1|grep package` + if [ "$isSetup" = "" ];then + echo '================================================='; + echo -e "\033[31mweb.py installation failed. \033[0m"; + exit; + fi +} +pipArg='' + + +pip install setuptools +#pip install --upgrade pip $pipArg +pip install psutil chardet web.py virtualenv Pillow $pipArg + + +Install_Pillow +Install_psutil +if [ -f /www/server/mysql/bin/mysql ]; then + pip install mysql-python + Install_mysqldb +fi +Install_chardet +Install_webpy + +mkdir -p $setup_path/server/panel/logs +mkdir -p $setup_path/server/panel/vhost/apache +mkdir -p $setup_path/server/panel/vhost/nginx +mkdir -p $setup_path/server/panel/vhost/rewrite +wget -O $setup_path/server/panel/certbot-auto $download_Url/install/certbot-auto.init -T 5 +chmod +x $setup_path/server/panel/certbot-auto + + +if [ -f '/etc/init.d/bt' ];then + /etc/init.d/bt stop +fi + +mkdir -p /www/server +mkdir -p /www/wwwroot +mkdir -p /www/wwwlogs +mkdir -p /www/backup/database +mkdir -p /www/backup/site + +wget -O panel.zip $download_Url/install/src/panel.zip -T 10 +wget -O /etc/init.d/bt $download_Url/install/src/bt.init -T 10 +if [ -f "$setup_path/server/panel/data/default.db" ];then + if [ -d "/$setup_path/server/panel/old_data" ];then + rm -rf $setup_path/server/panel/old_data + fi + mkdir -p $setup_path/server/panel/old_data + mv -f $setup_path/server/panel/data/default.db $setup_path/server/panel/old_data/default.db + mv -f $setup_path/server/panel/data/system.db $setup_path/server/panel/old_data/system.db + mv -f $setup_path/server/panel/data/aliossAs.conf $setup_path/server/panel/old_data/aliossAs.conf + mv -f $setup_path/server/panel/data/qiniuAs.conf $setup_path/server/panel/old_data/qiniuAs.conf + mv -f $setup_path/server/panel/data/iplist.txt $setup_path/server/panel/old_data/iplist.txt + mv -f $setup_path/server/panel/data/port.pl $setup_path/server/panel/old_data/port.pl +fi + +unzip -o panel.zip -d $setup_path/server/ > /dev/null + +if [ -d "$setup_path/server/panel/old_data" ];then + mv -f $setup_path/server/panel/old_data/default.db $setup_path/server/panel/data/default.db + mv -f $setup_path/server/panel/old_data/system.db $setup_path/server/panel/data/system.db + mv -f $setup_path/server/panel/old_data/aliossAs.conf $setup_path/server/panel/data/aliossAs.conf + mv -f $setup_path/server/panel/old_data/qiniuAs.conf $setup_path/server/panel/data/qiniuAs.conf + mv -f $setup_path/server/panel/old_data/iplist.txt $setup_path/server/panel/data/iplist.txt + mv -f $setup_path/server/panel/old_data/port.pl $setup_path/server/panel/data/port.pl + + if [ -d "/$setup_path/server/panel/old_data" ];then + rm -rf $setup_path/server/panel/old_data + fi +fi + +rm -f panel.zip + +if [ ! -f $setup_path/server/panel/tools.py ];then + echo -e "\033[31mERROR: Failed to download, please try again!\033[0m"; + echo '============================================' + exit; +fi + +rm -f $setup_path/server/panel/class/*.pyc +rm -f $setup_path/server/panel/*.pyc +python -m compileall $setup_path/server/panel +#rm -f $setup_path/server/panel/class/*.py +#rm -f $setup_path/server/panel/*.py + +chmod 777 /tmp +chmod +x /etc/init.d/bt +update-rc.d bt defaults +chmod -R 600 $setup_path/server/panel +chmod +x $setup_path/server/panel/certbot-auto +chmod -R +x $setup_path/server/panel/script +echo "$port" > $setup_path/server/panel/data/port.pl +/etc/init.d/bt start +password=`cat /dev/urandom | head -n 16 | md5sum | head -c 8` +cd $setup_path/server/panel/ +python tools.py username +username=`python tools.pyc panel $password` +cd ~ +echo "$password" > $setup_path/server/panel/default.pl +chmod 600 $setup_path/server/panel/default.pl + +isStart=`ps aux |grep 'python main.pyc'|grep -v grep|awk '{print $2}'` +if [ "$isStart" == '' ];then + echo -e "\033[31mERROR: The BT-Panel service startup failed.\033[0m"; + echo '============================================' + exit; +fi + +if [ ! -f "/usr/bin/ufw" ];then + apt-get install -y ufw +fi + +if [ -f "/usr/sbin/ufw" ];then + ufw allow 888,20,21,22,80,$port/tcp + ufw allow 39000:40000/tcp + ufw_status=`ufw status` + echo y|ufw enable + ufw default deny + ufw reload +fi +pip install web.py==0.39 +pip install psutil chardet psutil virtualenv $pipArg +if [ ! -d '/etc/letsencrypt' ];then + + mkdir -p /var/spool/cron + if [ ! -f '/var/spool/cron/crontabs/root' ];then + echo '' > /var/spool/cron/crontabs/root + chmod 600 /var/spool/cron/crontabs/root + fi + isCron=`cat /var/spool/cron/crontabs/root|grep certbot.log` + if [ "${isCron}" == "" ];then + echo "30 2 * * * $setup_path/server/panel/certbot-auto renew >> $setup_path/server/panel/logs/certbot.log" >> /var/spool/cron/crontabs/root + chown 600 /var/spool/cron/crontabs/root + fi + service cron restart + nohup $setup_path/server/panel/certbot-auto -n > /tmp/certbot-auto.log 2>&1 & +fi +if [[ "${deepinSys}" =~ eepin ]]; then + address="localhost" +else + address=`curl -sS --connect-timeout 10 -m 60 https://www.bt.cn/Api/getIpAddress` + + if [ "$address" == '0.0.0.0' ] || [ "$address" == '' ];then + isHosts=`cat /etc/hosts|grep 'www.bt.cn'` + if [ "$isHosts" == '' ];then + echo "" >> /etc/hosts + echo "125.88.182.170 www.bt.cn" >> /etc/hosts + address=`curl -sS --connect-timeout 10 -m 60 https://www.bt.cn/Api/getIpAddress` + if [ "$address" == '' ];then + sed -i "/bt.cn/d" /etc/hosts + fi + fi + fi + + ipCheck=`python -c "import re; print re.match('^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$','$address')"` + if [ "$address" == "None" ];then + address="SERVER_IP" + fi + if [ "$address" != "SERVER_IP" ];then + echo "$address" > $setup_path/server/panel/data/iplist.txt + fi +fi + +curl -sS --connect-timeout 10 -m 60 https://www.bt.cn/Api/SetupCount?type=Linux\&o=$1 > /dev/null 2>&1 +if [ $1 != "" ];then + echo $1 > /www/server/panel/data/o.pl + cd /www/server/panel + python tools.py o +fi + +echo -e "==================================================================" +echo -e "\033[32mCongratulations! Install succeeded!\033[0m" +echo -e "==================================================================" +echo -e "Bt-Panel: http://$address:$port" +echo -e "username: $username" +echo -e "password: $password" +echo -e "\033[33mWarning:\033[0m" +echo -e "\033[33mIf you cannot access the panel, \033[0m" +echo -e "\033[33mrelease the following port (8888|888|80|443|20|21) in the security group\033[0m" +echo -e "==================================================================" + +endTime=`date +%s` +((outTime=($endTime-$startTime)/60)) +echo -e "Time consumed:\033[32m $outTime \033[0mMinute!" +rm -f install.sh diff --git a/kconfig.cmake b/kconfig.cmake index 5eecee5a3..6fdf7213f 100644 --- a/kconfig.cmake +++ b/kconfig.cmake @@ -10,6 +10,7 @@ message( ${CMAKE_SOURCE_DIR}/build/log.txt "\n" ${CMAKE_SOURCE_DIR}/build/.config "\n" ) + execute_process( COMMAND ${PYTHON_EXECUTABLE} diff --git a/mkrtos_knl/drivers/stm32f1x/systick/systick.c b/mkrtos_knl/drivers/stm32f1x/systick/systick.c index 14e89f6f0..7d7b97e1d 100755 --- a/mkrtos_knl/drivers/stm32f1x/systick/systick.c +++ b/mkrtos_knl/drivers/stm32f1x/systick/systick.c @@ -12,9 +12,9 @@ umword_t sys_tick_cnt_get(void) void SysTick_Handler(void) { - // 进行上下文切换 thread_sched(); - timeout_times_tick(); sys_tick_cnt++; + timeout_times_tick(); + futex_timeout_times_tick(); } diff --git a/mkrtos_knl/drivers/stm32f2x/systick/systick.c b/mkrtos_knl/drivers/stm32f2x/systick/systick.c index e0a3e5eb9..89d65a32e 100755 --- a/mkrtos_knl/drivers/stm32f2x/systick/systick.c +++ b/mkrtos_knl/drivers/stm32f2x/systick/systick.c @@ -2,7 +2,7 @@ #include "arch.h" #include "thread.h" #include "ipc.h" - +#include "futex.h" static umword_t sys_tick_cnt; umword_t sys_tick_cnt_get(void) @@ -14,6 +14,7 @@ void SysTick_Handler(void) { // 进行上下文切换 thread_sched(); - timeout_times_tick(); sys_tick_cnt++; + timeout_times_tick(); + futex_timeout_times_tick(); } diff --git a/mkrtos_knl/inc/knl/access.h b/mkrtos_knl/inc/knl/access.h new file mode 100644 index 000000000..5937082a4 --- /dev/null +++ b/mkrtos_knl/inc/knl/access.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +bool_t is_rw_access(void *addr, size_t size, bool_t ignore_null); diff --git a/mkrtos_knl/inc/knl/futex.h b/mkrtos_knl/inc/knl/futex.h index 45dcbb04b..4df4eb6e9 100644 --- a/mkrtos_knl/inc/knl/futex.h +++ b/mkrtos_knl/inc/knl/futex.h @@ -1,3 +1,3 @@ #pragma once - +void futex_timeout_times_tick(void); diff --git a/mkrtos_knl/knl/access.c b/mkrtos_knl/knl/access.c new file mode 100644 index 000000000..c073442b0 --- /dev/null +++ b/mkrtos_knl/knl/access.c @@ -0,0 +1,32 @@ + +#include "types.h" +#include +#include +#include + +/** + * @brief 检测内存是否可访问 + * + * @param addr + * @param size + * @return bool_t + */ +bool_t is_rw_access(void *addr, size_t size, bool_t ignore_null) +{ + if (addr == NULL && ignore_null) + { + return TRUE; + } + + void *mem; + size_t mem_size; + task_t *cur_task = thread_get_current_task(); + + mm_space_get_ram_block(&cur_task->mm_space, &mem, &mem_size); + if (mem >= addr && ((char *)addr + size) < (char *)mem + mem_size) + { + return TRUE; + } + + return FALSE; +} diff --git a/mkrtos_knl/knl/futex.c b/mkrtos_knl/knl/futex.c index a6dbd7586..dc4823dda 100644 --- a/mkrtos_knl/knl/futex.c +++ b/mkrtos_knl/knl/futex.c @@ -1,4 +1,14 @@ - +/** + * @file futex.c + * @author zhangzheng (1358745329@qq.com) + * @brief futex在内核中实现 + * @note TODO: 可以使用hashmap优化 + * @version 0.1 + * @date 2023-11-20 + * + * @copyright Copyright (c) 2023 + * + */ #include "types.h" #include "init.h" #include "prot.h" @@ -13,10 +23,13 @@ #include "globals.h" #include "string.h" #include "ipc.h" +#include "err.h" +#include #define INT_MAX 0x7fffffff #define FT_ADDR_NR 16 //!< 最多加锁的对象 + #define FUTEX_WAIT 0 #define FUTEX_WAKE 1 #define FUTEX_FD 2 @@ -58,6 +71,50 @@ typedef struct futex } futex_t; static futex_t futex_obj; static void futex_init(futex_t *ft); +typedef struct futex_wait_item +{ + slist_head_t node; + thread_t *th; + umword_t sleep_times; +} futex_wait_item_t; +static slist_head_t wait_list; + +/** + * @brief 初始化一个超时等待队列 + * + */ +static void futex_wait_list_init(void) +{ + slist_init(&wait_list); +} +INIT_KOBJ(futex_wait_list_init); +/** + * @brief 检查超时队列 + * + */ +void futex_timeout_times_tick(void) +{ + futex_wait_item_t *item; + + slist_foreach(item, &wait_list, node) //!< 第一次循环等待的ipc + { + if (item->sleep_times > 0) + { + if ((--item->sleep_times) == 0) + { + //!< 超时时间满后直接唤醒等待者 + thread_ready(item->th, TRUE); + } + } + else + { + if (item->th->status == THREAD_SUSPEND) + { + thread_ready(item->th, TRUE); + } + } + } +} static void futex_reg(void) { futex_init(&futex_obj); @@ -130,8 +187,9 @@ static futex_lock_t *futex_find(futex_t *fst, void *uaddr) } return NULL; } + static int futex_dispose(futex_t *fst, uint32_t *uaddr, int futex_op, uint32_t val, - const struct timespec *timeout, uint32_t uaddr2, uint32_t val3, int tid) + umword_t timeout /*val2*/, uint32_t uaddr2, uint32_t val3, int tid) { thread_t *cur_th = thread_get_current(); @@ -143,6 +201,11 @@ static int futex_dispose(futex_t *fst, uint32_t *uaddr, int futex_op, uint32_t v { case FUTEX_REQUEUE: { + if (!is_rw_access(uaddr, sizeof(*uaddr), FALSE)) + { + spinlock_set(&fst->lock, status); + return -EACCES; + } if (val3 == *uaddr) { futex_lock_t *flt = futex_find(fst, uaddr); @@ -198,6 +261,11 @@ static int futex_dispose(futex_t *fst, uint32_t *uaddr, int futex_op, uint32_t v break; case FUTEX_WAIT: { + if (!is_rw_access(uaddr, sizeof(*uaddr), FALSE)) + { + spinlock_set(&fst->lock, status); + return -EACCES; + } if (val == *uaddr) { ref_counter_inc(&cur_th->ref); @@ -207,8 +275,33 @@ static int futex_dispose(futex_t *fst, uint32_t *uaddr, int futex_op, uint32_t v spinlock_set(&fst->lock, status); return -ENOMEM; } - thread_suspend(cur_th); // TODO:考虑超时时间 - preemption(); + if (timeout != 0) + { + //! 加入到等待队列中 + futex_wait_item_t item = { + .th = cur_th, + .sleep_times = timeout, + }; + + slist_init(&item.node); + slist_add_append(&wait_list, &item.node); + thread_suspend(cur_th); + preemption(); + slist_del(&item.node); + if (timeout <= 0) + { + ref_counter_dec_and_release(&cur_th->ref, &cur_th->kobj); + spinlock_set(&fst->lock, status); + return -ETIMEDOUT; + } + } + else + { + // 一直等待 + thread_suspend(cur_th); + preemption(); + } + ref_counter_dec_and_release(&cur_th->ref, &cur_th->kobj); } else @@ -249,6 +342,11 @@ static int futex_dispose(futex_t *fst, uint32_t *uaddr, int futex_op, uint32_t v case FUTEX_UNLOCK_PI: case FUTEX_WAKE_CLEAR: { + if (!is_rw_access(uaddr, sizeof(*uaddr), FALSE)) + { + spinlock_set(&fst->lock, status); + return -EACCES; + } futex_lock_t *flt = futex_find(fst, uaddr); int rel_cnt = 0; @@ -277,6 +375,11 @@ static int futex_dispose(futex_t *fst, uint32_t *uaddr, int futex_op, uint32_t v } case FUTEX_LOCK_PI: { + if (!is_rw_access(uaddr, sizeof(*uaddr), FALSE)) + { + spinlock_set(&fst->lock, status); + return -EACCES; + } if (*uaddr = 0) { *uaddr = tid; @@ -320,7 +423,7 @@ static void futex_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_ta uint32_t *uaddr = (uint32_t *)(msg->msg_buf[0]); int futex_op = msg->msg_buf[1]; uint32_t val = msg->msg_buf[2]; - const struct timespec *timeout = (const struct timespec *)(msg->msg_buf[3]); + umword_t timeout = msg->msg_buf[3]; uint32_t uaddr2 = msg->msg_buf[4]; uint32_t val3 = msg->msg_buf[5]; int tid = msg->msg_buf[6]; @@ -334,16 +437,10 @@ static void futex_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_ta } static void futex_release_stage1(kobject_t *kobj) { - // futex_t *futex = container_of(kobj, futex_t, kobj); - - // kobject_invalidate(kobj); - /*TODO:唤醒所有挂起的线程*/ + /*TODO:删除task所占用的futex资源*/ } static void futex_release_stage2(kobject_t *kobj) { - // futex_t *ipc = container_of(kobj, futex_t, kobj); - - // mm_limit_free(ipc->lim, kobj); printk("futex don't release.\n"); } static void futex_init(futex_t *ft) @@ -354,29 +451,3 @@ static void futex_init(futex_t *ft) ft->kobj.stage_1_func = futex_release_stage1; ft->kobj.stage_2_func = futex_release_stage2; } -// static futex_t *futex_create(ram_limit_t *lim) -// { -// futex_t *ft = mm_limit_alloc(lim, sizeof(futex_t)); - -// if (!ft) -// { -// return NULL; -// } -// memset(ft, 0, sizeof(futex_t)); -// futex_init(ft, lim); -// return ft; -// } -// static kobject_t *futex_create_func(ram_limit_t *lim, umword_t arg0, umword_t arg1, -// umword_t arg2, umword_t arg3) -// { -// return &futex_create(lim)->kobj; -// } -/** - * @brief 工厂注册函数 - * - */ -// static void futex_factory_register(void) -// { -// factory_register(futex_create_func, FUTEX_PROT); -// } -// INIT_KOBJ(futex_factory_register); diff --git a/mkrtos_knl/knl/ipc.c b/mkrtos_knl/knl/ipc.c index 26ae66e18..bece3f8a9 100755 --- a/mkrtos_knl/knl/ipc.c +++ b/mkrtos_knl/knl/ipc.c @@ -63,7 +63,7 @@ static slist_head_t wait_list; * @brief 初始化一个超时等待队列 * */ -void timeout_wait_list_init(void) +static void timeout_wait_list_init(void) { slist_init(&wait_list); } diff --git a/mkrtos_script/build.sh b/mkrtos_script/build.sh index d87fbefe7..b9d98b338 100755 --- a/mkrtos_script/build.sh +++ b/mkrtos_script/build.sh @@ -1,9 +1,9 @@ #!/bin/bash -# export TOOLCHAIN=/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/bin/ -# export TOOLCHAIN_LIB=/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/lib/gcc/arm-none-eabi/5.4.1/armv7-m -export TOOLCHAIN=/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/bin/ -export TOOLCHAIN_LIB=/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/lib/gcc/arm-none-eabi/10.3.1/thumb/v7-m/nofp +export TOOLCHAIN=/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/bin/ +export TOOLCHAIN_LIB=/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/lib/gcc/arm-none-eabi/5.4.1/armv7-m +# export TOOLCHAIN=/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/bin/ +# export TOOLCHAIN_LIB=/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/lib/gcc/arm-none-eabi/10.3.1/thumb/v7-m/nofp export KEN_OFFSET=0x2000 export INIT_OFFSET=0x10000 export BOOTFS_ADDR_OFFSET=0x20000 @@ -12,7 +12,6 @@ export KNL_DATA=0x20000000 export KNL_DATA_SIZE=64K export BOARD=STM32F2x - export PYTHON_EXECUTABLE=python3 set -e diff --git a/mkrtos_tool/kconfig/__pycache__/kconfigfunctions.cpython-38.pyc b/mkrtos_tool/kconfig/__pycache__/kconfigfunctions.cpython-38.pyc new file mode 100644 index 000000000..03368ce9f Binary files /dev/null and b/mkrtos_tool/kconfig/__pycache__/kconfigfunctions.cpython-38.pyc differ diff --git a/mkrtos_tool/kconfig/__pycache__/kconfiglib.cpython-38.pyc b/mkrtos_tool/kconfig/__pycache__/kconfiglib.cpython-38.pyc new file mode 100644 index 000000000..4e23e594f Binary files /dev/null and b/mkrtos_tool/kconfig/__pycache__/kconfiglib.cpython-38.pyc differ diff --git a/mkrtos_user/lib/libc_backend/src/futex_backend.c b/mkrtos_user/lib/libc_backend/src/futex_backend.c index b315e42cd..a738a83ee 100644 --- a/mkrtos_user/lib/libc_backend/src/futex_backend.c +++ b/mkrtos_user/lib/libc_backend/src/futex_backend.c @@ -30,20 +30,20 @@ int be_futex(uint32_t *uaddr, int futex_op, uint32_t val, struct pthread *pt = __pthread_self(); ipc_timeout_t to = ipc_timeout_create2(0, 0); umword_t total = 0; + umword_t st_val; sys_info_t sys_info; + msg_tag_t tag; if (timeout && !(futex_op & FUTEX_REQUEUE)) { to = ipc_timeout_create2(timeout->tv_sec * 1000 + timeout->tv_nsec / 1000 / 1000, 0); total = timeout->tv_sec * 1000 + timeout->tv_nsec / 1000 / 1000; } - umword_t st_val; _try_again: - sys_read_info(SYS_PROT, &sys_info); st_val = sys_info.sys_tick; - msg_tag_t tag = futex_ctrl(FUTEX_PROT, uaddr, futex_op, val, (void *)timeout, uaddr2, val3, pt->tid); + tag = futex_ctrl(FUTEX_PROT, uaddr, futex_op, val, total, uaddr2, val3, pt->tid); if (msg_tag_get_val(tag) == -EWTIMEDOUT) { umword_t en_val; diff --git a/mkrtos_user/lib/libc_backend/src/sys_backend.c b/mkrtos_user/lib/libc_backend/src/sys_backend.c index 0877dd9bf..b50a12d21 100644 --- a/mkrtos_user/lib/libc_backend/src/sys_backend.c +++ b/mkrtos_user/lib/libc_backend/src/sys_backend.c @@ -42,7 +42,6 @@ int be_clone(int (*func)(void *), void *stack, int flags, void *args, pid_t *pti ph = (struct pthread *)((char *)tls - sizeof(struct pthread)); - th1_hd = handler_alloc(); if (th1_hd == HANDLER_INVALID) { @@ -64,8 +63,9 @@ int be_clone(int (*func)(void *), void *stack, int flags, void *args, pid_t *pti stack = (char *)stack - MSG_BUG_LEN; umword_t *stack_tmp = (umword_t *)stack; + // 设置调用参数等 *(--stack_tmp) = (umword_t)args; - *(--stack_tmp) = (umword_t)0; + *(--stack_tmp) = (umword_t)0; // 保留 *(--stack_tmp) = (umword_t)func; tag = thread_exec_regs(th1_hd, (umword_t)__pthread_new_thread_entry__, (umword_t)stack_tmp, RAM_BASE(), 0); @@ -80,7 +80,10 @@ int be_clone(int (*func)(void *), void *stack, int flags, void *args, pid_t *pti handler_free_umap(th1_hd); return msg_tag_get_prot(tag); } - thread_run(th1_hd, 2); + ph->hd = th1_hd; + ph->ctid = (umword_t)ctid; + *ptid = th1_hd; + thread_run(th1_hd, 2); // 优先级默认为2 return 0; } diff --git a/mkrtos_user/lib/sys/inc/u_futex.h b/mkrtos_user/lib/sys/inc/u_futex.h index 1ed8cbc58..d817f9a6b 100644 --- a/mkrtos_user/lib/sys/inc/u_futex.h +++ b/mkrtos_user/lib/sys/inc/u_futex.h @@ -3,4 +3,4 @@ #include msg_tag_t futex_ctrl(obj_handler_t obj, uint32_t *uaddr, int futex_op, uint32_t val, - void *timeout, uint32_t uaddr2, uint32_t val3, int tid); + umword_t timeout, uint32_t uaddr2, uint32_t val3, int tid); diff --git a/mkrtos_user/lib/sys/src/u_futex.c b/mkrtos_user/lib/sys/src/u_futex.c index 691685271..ad7f25a8b 100644 --- a/mkrtos_user/lib/sys/src/u_futex.c +++ b/mkrtos_user/lib/sys/src/u_futex.c @@ -10,7 +10,7 @@ enum futex_op FUTEX_CTRL, }; msg_tag_t futex_ctrl(obj_handler_t obj, uint32_t *uaddr, int futex_op, uint32_t val, - void *timeout, uint32_t uaddr2, uint32_t val3, int tid) + umword_t timeout, uint32_t uaddr2, uint32_t val3, int tid) { ipc_msg_t *msg; diff --git a/mkrtos_user/server/init/src/test/pthread_lock_test.c b/mkrtos_user/server/init/src/test/pthread_lock_test.c index e08c54bfa..83d9d09ed 100644 --- a/mkrtos_user/server/init/src/test/pthread_lock_test.c +++ b/mkrtos_user/server/init/src/test/pthread_lock_test.c @@ -14,68 +14,53 @@ #include #define DEBUG_IPC_CALL 1 -static umword_t th1_hd = 0; -static umword_t th2_hd = 0; -static umword_t ipc_hd = 0; static pthread_mutex_t lock; +static pthread_t pth; +static pthread_t pth2; -static char msg_buf0[MSG_BUG_LEN]; -static char msg_buf1[MSG_BUG_LEN]; #define STACK_SIZE 2048 static __attribute__((aligned(8))) uint8_t stack0[STACK_SIZE]; static __attribute__((aligned(8))) uint8_t stack1[STACK_SIZE]; static void hard_sleep(void) { - for (volatile int i; i < 10000000; i++) ; } -static void thread_test_func(void) +static void *thread_test_func(void* arg) { - char *buf; - umword_t len; - thread_msg_buf_get(th1_hd, (umword_t *)(&buf), NULL); while (1) { pthread_mutex_lock(&lock); printf("thread 1 ..\n"); pthread_mutex_unlock(&lock); } - printf("thread_test_func.\n"); - task_unmap(TASK_PROT, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, th1_hd)); - printf("Error\n"); + return NULL; } -static void thread_test_func2(void) +static void *thread_test_func2(void* arg) { - char *buf; - umword_t len; - thread_msg_buf_get(th2_hd, (umword_t *)(&buf), NULL); while (1) { pthread_mutex_lock(&lock); printf("thread 2 ..\n"); pthread_mutex_unlock(&lock); } - printf("thread_test_func2.\n"); - task_unmap(TASK_PROT, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, th2_hd)); - printf("Error\n"); -} -static pthread_t pth; -static void *func_test(void *arg) -{ return NULL; } + /** * */ void pthread_lock_test(void) { - pthread_mutex_init(&lock, NULL); pthread_attr_t attr; + + pthread_mutex_init(&lock, NULL); pthread_attr_init(&attr); pthread_attr_setstack(&attr, stack0, STACK_SIZE); - pthread_create(&pth, &attr, func_test, NULL); + pthread_create(&pth, &attr, thread_test_func, NULL); + pthread_attr_setstack(&attr, stack1, STACK_SIZE); + pthread_create(&pth2, &attr, thread_test_func2, NULL); // th1_hd = handler_alloc(); // assert(th1_hd != HANDLER_INVALID);